171 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -mattr=+m,+v < %s | FileCheck --check-prefix=RV32 %s3; RUN: llc -mtriple=riscv64 -mattr=+m,+v < %s | FileCheck --check-prefix=RV64 %s4 5; FIXME: We can rematerialize "addi s0, a2, 32" (ideally along the edge6; %do.call -> %exit), and shrink wrap this routine7define void @vecaddr_straightline(i32 zeroext %a, ptr %p) {8; RV32-LABEL: vecaddr_straightline:9; RV32: # %bb.0:10; RV32-NEXT: addi sp, sp, -1611; RV32-NEXT: .cfi_def_cfa_offset 1612; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill13; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill14; RV32-NEXT: .cfi_offset ra, -415; RV32-NEXT: .cfi_offset s0, -816; RV32-NEXT: addi s0, a1, 3217; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma18; RV32-NEXT: vle32.v v8, (s0)19; RV32-NEXT: vadd.vi v8, v8, 120; RV32-NEXT: li a1, 5721; RV32-NEXT: vse32.v v8, (s0)22; RV32-NEXT: beq a0, a1, .LBB0_223; RV32-NEXT: # %bb.1: # %do_call24; RV32-NEXT: call foo25; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma26; RV32-NEXT: .LBB0_2: # %exit27; RV32-NEXT: vle32.v v8, (s0)28; RV32-NEXT: vadd.vi v8, v8, 129; RV32-NEXT: vse32.v v8, (s0)30; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload31; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload32; RV32-NEXT: .cfi_restore ra33; RV32-NEXT: .cfi_restore s034; RV32-NEXT: addi sp, sp, 1635; RV32-NEXT: .cfi_def_cfa_offset 036; RV32-NEXT: ret37;38; RV64-LABEL: vecaddr_straightline:39; RV64: # %bb.0:40; RV64-NEXT: addi sp, sp, -1641; RV64-NEXT: .cfi_def_cfa_offset 1642; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill43; RV64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill44; RV64-NEXT: .cfi_offset ra, -845; RV64-NEXT: .cfi_offset s0, -1646; RV64-NEXT: addi s0, a1, 3247; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma48; RV64-NEXT: vle32.v v8, (s0)49; RV64-NEXT: vadd.vi v8, v8, 150; RV64-NEXT: li a1, 5751; RV64-NEXT: vse32.v v8, (s0)52; RV64-NEXT: beq a0, a1, .LBB0_253; RV64-NEXT: # %bb.1: # %do_call54; RV64-NEXT: call foo55; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma56; RV64-NEXT: .LBB0_2: # %exit57; RV64-NEXT: vle32.v v8, (s0)58; RV64-NEXT: vadd.vi v8, v8, 159; RV64-NEXT: vse32.v v8, (s0)60; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload61; RV64-NEXT: ld s0, 0(sp) # 8-byte Folded Reload62; RV64-NEXT: .cfi_restore ra63; RV64-NEXT: .cfi_restore s064; RV64-NEXT: addi sp, sp, 1665; RV64-NEXT: .cfi_def_cfa_offset 066; RV64-NEXT: ret67 %gep = getelementptr i8, ptr %p, i32 3268 %v1 = load <4 x i32>, ptr %gep69 %v2 = add <4 x i32> %v1, splat (i32 1)70 store <4 x i32> %v2, ptr %gep71 %cmp0 = icmp eq i32 %a, 5772 br i1 %cmp0, label %exit, label %do_call73do_call:74 call i32 @foo()75 br label %exit76exit:77 %v3 = load <4 x i32>, ptr %gep78 %v4 = add <4 x i32> %v3, splat (i32 1)79 store <4 x i32> %v4, ptr %gep80 ret void81}82 83; In this case, the second use is in a loop, so using a callee84; saved register to avoid a remat is the profitable choice.85; FIXME: We can shrink wrap the frame setup around the loop86; and avoid it along the %bb.0 -> %exit edge87define void @vecaddr_loop(i32 zeroext %a, ptr %p) {88; RV32-LABEL: vecaddr_loop:89; RV32: # %bb.0:90; RV32-NEXT: addi sp, sp, -1691; RV32-NEXT: .cfi_def_cfa_offset 1692; RV32-NEXT: sw ra, 12(sp) # 4-byte Folded Spill93; RV32-NEXT: sw s0, 8(sp) # 4-byte Folded Spill94; RV32-NEXT: .cfi_offset ra, -495; RV32-NEXT: .cfi_offset s0, -896; RV32-NEXT: addi s0, a1, 3297; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma98; RV32-NEXT: vle32.v v8, (s0)99; RV32-NEXT: vadd.vi v8, v8, 1100; RV32-NEXT: li a1, 57101; RV32-NEXT: vse32.v v8, (s0)102; RV32-NEXT: beq a0, a1, .LBB1_2103; RV32-NEXT: .LBB1_1: # %do_call104; RV32-NEXT: # =>This Inner Loop Header: Depth=1105; RV32-NEXT: call foo106; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma107; RV32-NEXT: vle32.v v8, (s0)108; RV32-NEXT: vadd.vi v8, v8, 1109; RV32-NEXT: vse32.v v8, (s0)110; RV32-NEXT: bnez a0, .LBB1_1111; RV32-NEXT: .LBB1_2: # %exit112; RV32-NEXT: lw ra, 12(sp) # 4-byte Folded Reload113; RV32-NEXT: lw s0, 8(sp) # 4-byte Folded Reload114; RV32-NEXT: .cfi_restore ra115; RV32-NEXT: .cfi_restore s0116; RV32-NEXT: addi sp, sp, 16117; RV32-NEXT: .cfi_def_cfa_offset 0118; RV32-NEXT: ret119;120; RV64-LABEL: vecaddr_loop:121; RV64: # %bb.0:122; RV64-NEXT: addi sp, sp, -16123; RV64-NEXT: .cfi_def_cfa_offset 16124; RV64-NEXT: sd ra, 8(sp) # 8-byte Folded Spill125; RV64-NEXT: sd s0, 0(sp) # 8-byte Folded Spill126; RV64-NEXT: .cfi_offset ra, -8127; RV64-NEXT: .cfi_offset s0, -16128; RV64-NEXT: addi s0, a1, 32129; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma130; RV64-NEXT: vle32.v v8, (s0)131; RV64-NEXT: vadd.vi v8, v8, 1132; RV64-NEXT: li a1, 57133; RV64-NEXT: vse32.v v8, (s0)134; RV64-NEXT: beq a0, a1, .LBB1_2135; RV64-NEXT: .LBB1_1: # %do_call136; RV64-NEXT: # =>This Inner Loop Header: Depth=1137; RV64-NEXT: call foo138; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma139; RV64-NEXT: vle32.v v8, (s0)140; RV64-NEXT: vadd.vi v8, v8, 1141; RV64-NEXT: vse32.v v8, (s0)142; RV64-NEXT: bnez a0, .LBB1_1143; RV64-NEXT: .LBB1_2: # %exit144; RV64-NEXT: ld ra, 8(sp) # 8-byte Folded Reload145; RV64-NEXT: ld s0, 0(sp) # 8-byte Folded Reload146; RV64-NEXT: .cfi_restore ra147; RV64-NEXT: .cfi_restore s0148; RV64-NEXT: addi sp, sp, 16149; RV64-NEXT: .cfi_def_cfa_offset 0150; RV64-NEXT: ret151 %gep = getelementptr i8, ptr %p, i32 32152 %v1 = load <4 x i32>, ptr %gep153 %v2 = add <4 x i32> %v1, splat (i32 1)154 store <4 x i32> %v2, ptr %gep155 %cmp0 = icmp eq i32 %a, 57156 br i1 %cmp0, label %exit, label %do_call157do_call:158 %b = call i32 @foo()159 %v3 = load <4 x i32>, ptr %gep160 %v4 = add <4 x i32> %v3, splat (i32 1)161 store <4 x i32> %v4, ptr %gep162 163 %cmp1 = icmp eq i32 %b, 0164 br i1 %cmp1, label %exit, label %do_call165exit:166 ret void167}168 169declare zeroext i32 @foo()170 171