|  | ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py | 
|  | ; RUN: llc -O3 < %s -mtriple=riscv32 | FileCheck %s | 
|  |  | 
|  | ; These tests demonstrate optimizations involving copies from VLENB. | 
|  |  | 
|  | define void @unused_copy_is_dead() { | 
|  | ; CHECK-LABEL: unused_copy_is_dead: | 
|  | ; CHECK:       # %bb.0: # %entry | 
|  | ; CHECK-NEXT:    ret | 
|  | entry: | 
|  | call i32 @llvm.read_register.i32(metadata !0) | 
|  | ret void | 
|  | } | 
|  |  | 
|  | define i32 @simple_cse() { | 
|  | ; CHECK-LABEL: simple_cse: | 
|  | ; CHECK:       # %bb.0: # %entry | 
|  | ; CHECK-NEXT:    csrr a0, vlenb | 
|  | ; CHECK-NEXT:    sub a0, a0, a0 | 
|  | ; CHECK-NEXT:    ret | 
|  | entry: | 
|  | %v1 = call i32 @llvm.read_register.i32(metadata !0) | 
|  | %v2 = call i32 @llvm.read_register.i32(metadata !0) | 
|  | %sub = sub i32 %v1, %v2 | 
|  | ret i32 %sub | 
|  | } | 
|  |  | 
|  | define i32 @sink_to_use_branch(i1 %c) { | 
|  | ; CHECK-LABEL: sink_to_use_branch: | 
|  | ; CHECK:       # %bb.0: # %entry | 
|  | ; CHECK-NEXT:    andi a0, a0, 1 | 
|  | ; CHECK-NEXT:    beqz a0, .LBB2_2 | 
|  | ; CHECK-NEXT:  # %bb.1: # %used | 
|  | ; CHECK-NEXT:    csrr a0, vlenb | 
|  | ; CHECK-NEXT:  .LBB2_2: # %unused | 
|  | ; CHECK-NEXT:    ret | 
|  | entry: | 
|  | %v1 = call i32 @llvm.read_register.i32(metadata !0) | 
|  | br i1 %c, label %used, label %unused | 
|  | used: | 
|  | ret i32 %v1 | 
|  | unused: | 
|  | ret i32 0 | 
|  | } | 
|  |  | 
|  | define i32 @sink_to_use_call() { | 
|  | ; CHECK-LABEL: sink_to_use_call: | 
|  | ; CHECK:       # %bb.0: # %entry | 
|  | ; CHECK-NEXT:    addi sp, sp, -16 | 
|  | ; CHECK-NEXT:    .cfi_def_cfa_offset 16 | 
|  | ; CHECK-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill | 
|  | ; CHECK-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill | 
|  | ; CHECK-NEXT:    .cfi_offset ra, -4 | 
|  | ; CHECK-NEXT:    .cfi_offset s0, -8 | 
|  | ; CHECK-NEXT:    csrr s0, vlenb | 
|  | ; CHECK-NEXT:    call unknown | 
|  | ; CHECK-NEXT:    mv a0, s0 | 
|  | ; CHECK-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload | 
|  | ; CHECK-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload | 
|  | ; CHECK-NEXT:    .cfi_restore ra | 
|  | ; CHECK-NEXT:    .cfi_restore s0 | 
|  | ; CHECK-NEXT:    addi sp, sp, 16 | 
|  | ; CHECK-NEXT:    .cfi_def_cfa_offset 0 | 
|  | ; CHECK-NEXT:    ret | 
|  | entry: | 
|  | %v1 = call i32 @llvm.read_register.i32(metadata !0) | 
|  | call void @unknown() ; maythrow | 
|  | ret i32 %v1 | 
|  | } | 
|  |  | 
|  | define void @machine_licm() { | 
|  | ; CHECK-LABEL: machine_licm: | 
|  | ; CHECK:       # %bb.0: # %entry | 
|  | ; CHECK-NEXT:    addi sp, sp, -16 | 
|  | ; CHECK-NEXT:    .cfi_def_cfa_offset 16 | 
|  | ; CHECK-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill | 
|  | ; CHECK-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill | 
|  | ; CHECK-NEXT:    .cfi_offset ra, -4 | 
|  | ; CHECK-NEXT:    .cfi_offset s0, -8 | 
|  | ; CHECK-NEXT:    csrr s0, vlenb | 
|  | ; CHECK-NEXT:  .LBB4_1: # %loop | 
|  | ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1 | 
|  | ; CHECK-NEXT:    mv a0, s0 | 
|  | ; CHECK-NEXT:    call use | 
|  | ; CHECK-NEXT:    j .LBB4_1 | 
|  | entry: | 
|  | br label %loop | 
|  |  | 
|  | loop: | 
|  | %v1 = call i32 @llvm.read_register.i32(metadata !0) | 
|  | call void @use(i32 %v1) | 
|  | br label %loop | 
|  | } | 
|  |  | 
|  |  | 
|  | declare i32 @llvm.read_register.i32(metadata) nounwind | 
|  | declare void @unknown() | 
|  | declare void @use(i32) | 
|  |  | 
|  | !0 = !{!"vlenb"} |