brintos

brintos / llvm-project-archived public Read only

0
0
Text · 47.2 KiB · 60a2914 Raw
1119 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv64 -mattr=+m,+f,+d,+a,+c,+v \3; RUN:    -target-abi=lp64d -verify-machineinstrs -O2 < %s | FileCheck %s4 5; The following tests check whether inserting VSETVLI avoids inserting6; unneeded vsetvlis across basic blocks.7 8define <vscale x 1 x double> @test1(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {9; CHECK-LABEL: test1:10; CHECK:       # %bb.0: # %entry11; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma12; CHECK-NEXT:    beqz a1, .LBB0_213; CHECK-NEXT:  # %bb.1: # %if.then14; CHECK-NEXT:    vfadd.vv v8, v8, v915; CHECK-NEXT:    ret16; CHECK-NEXT:  .LBB0_2: # %if.else17; CHECK-NEXT:    vfsub.vv v8, v8, v918; CHECK-NEXT:    ret19entry:20  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)21  %tobool = icmp eq i8 %cond, 022  br i1 %tobool, label %if.else, label %if.then23 24if.then:                                          ; preds = %entry25  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)26  br label %if.end27 28if.else:                                          ; preds = %entry29  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)30  br label %if.end31 32if.end:                                           ; preds = %if.else, %if.then33  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]34  ret <vscale x 1 x double> %c.035}36 37@scratch = global i8 0, align 1638 39define <vscale x 1 x double> @test2(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {40; CHECK-LABEL: test2:41; CHECK:       # %bb.0: # %entry42; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma43; CHECK-NEXT:    beqz a1, .LBB1_244; CHECK-NEXT:  # %bb.1: # %if.then45; CHECK-NEXT:    vfadd.vv v9, v8, v946; CHECK-NEXT:    vfmul.vv v8, v9, v847; CHECK-NEXT:    ret48; CHECK-NEXT:  .LBB1_2: # %if.else49; CHECK-NEXT:    vfsub.vv v9, v8, v950; CHECK-NEXT:    vfmul.vv v8, v9, v851; CHECK-NEXT:    ret52entry:53  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)54  %tobool = icmp eq i8 %cond, 055  br i1 %tobool, label %if.else, label %if.then56 57if.then:                                          ; preds = %entry58  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)59  br label %if.end60 61if.else:                                          ; preds = %entry62  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)63  br label %if.end64 65if.end:                                           ; preds = %if.else, %if.then66  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]67  %3 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %c.0, <vscale x 1 x double> %a, i64 7, i64 %0)68  ret <vscale x 1 x double> %369}70 71define <vscale x 1 x double> @test3(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {72; CHECK-LABEL: test3:73; CHECK:       # %bb.0: # %entry74; CHECK-NEXT:    beqz a1, .LBB2_275; CHECK-NEXT:  # %bb.1: # %if.then76; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma77; CHECK-NEXT:    vfadd.vv v9, v8, v978; CHECK-NEXT:    vfmul.vv v8, v9, v879; CHECK-NEXT:    ret80; CHECK-NEXT:  .LBB2_2: # %if.else81; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma82; CHECK-NEXT:    vfsub.vv v9, v8, v983; CHECK-NEXT:    vfmul.vv v8, v9, v884; CHECK-NEXT:    ret85entry:86  %tobool = icmp eq i8 %cond, 087  br i1 %tobool, label %if.else, label %if.then88 89if.then:                                          ; preds = %entry90  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)91  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)92  br label %if.end93 94if.else:                                          ; preds = %entry95  %2 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)96  %3 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %2)97  br label %if.end98 99if.end:                                           ; preds = %if.else, %if.then100  %vl.0 = phi i64 [ %0, %if.then], [ %2, %if.else ]101  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %3, %if.else ]102  %4 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %c.0, <vscale x 1 x double> %a, i64 7, i64 %vl.0)103  ret <vscale x 1 x double> %4104}105 106define <vscale x 1 x double> @test4(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %l, <vscale x 1 x double> %r) nounwind {107; CHECK-LABEL: test4:108; CHECK:       # %bb.0: # %entry109; CHECK-NEXT:    beqz a1, .LBB3_2110; CHECK-NEXT:  # %bb.1: # %if.then111; CHECK-NEXT:    li a1, 1023112; CHECK-NEXT:    slli a1, a1, 52113; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma114; CHECK-NEXT:    vmv.v.x v10, a1115; CHECK-NEXT:    li a1, 1116; CHECK-NEXT:    slli a1, a1, 62117; CHECK-NEXT:    vmv.v.x v11, a1118; CHECK-NEXT:    vfadd.vv v10, v10, v11119; CHECK-NEXT:    lui a1, %hi(scratch)120; CHECK-NEXT:    addi a1, a1, %lo(scratch)121; CHECK-NEXT:    vse64.v v10, (a1)122; CHECK-NEXT:    j .LBB3_3123; CHECK-NEXT:  .LBB3_2: # %if.else124; CHECK-NEXT:    lui a1, 260096125; CHECK-NEXT:    vsetvli zero, a0, e32, m1, ta, ma126; CHECK-NEXT:    vmv.v.x v10, a1127; CHECK-NEXT:    lui a1, 262144128; CHECK-NEXT:    vmv.v.x v11, a1129; CHECK-NEXT:    vfadd.vv v10, v10, v11130; CHECK-NEXT:    lui a1, %hi(scratch)131; CHECK-NEXT:    addi a1, a1, %lo(scratch)132; CHECK-NEXT:    vse32.v v10, (a1)133; CHECK-NEXT:  .LBB3_3: # %if.end134; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma135; CHECK-NEXT:    vfmul.vv v8, v8, v9136; CHECK-NEXT:    ret137entry:138  %tobool = icmp eq i8 %cond, 0139  br i1 %tobool, label %if.else, label %if.then140 141if.then:                                          ; preds = %entry142  %0 = tail call <vscale x 1 x double> @llvm.riscv.vfmv.v.f.nxv1f64.f64(<vscale x 1 x double> poison, double 1.000000e+00, i64 %avl)143  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfmv.v.f.nxv1f64.f64(<vscale x 1 x double> poison, double 2.000000e+00, i64 %avl)144  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %0, <vscale x 1 x double> %1, i64 7, i64 %avl)145  %3 = bitcast ptr @scratch to ptr146  tail call void @llvm.riscv.vse.nxv1f64(<vscale x 1 x double> %2, ptr %3, i64 %avl)147  br label %if.end148 149if.else:                                          ; preds = %entry150  %4 = tail call <vscale x 2 x float> @llvm.riscv.vfmv.v.f.nxv2f32.f32(<vscale x 2 x float> poison, float 1.000000e+00, i64 %avl)151  %5 = tail call <vscale x 2 x float> @llvm.riscv.vfmv.v.f.nxv2f32.f32(<vscale x 2 x float> poison, float 2.000000e+00, i64 %avl)152  %6 = tail call <vscale x 2 x float> @llvm.riscv.vfadd.nxv2f32.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %4, <vscale x 2 x float> %5, i64 7, i64 %avl)153  %7 = bitcast ptr @scratch to ptr154  tail call void @llvm.riscv.vse.nxv2f32(<vscale x 2 x float> %6, ptr %7, i64 %avl)155  br label %if.end156 157if.end:                                           ; preds = %if.else, %if.then158  %8 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %l, <vscale x 1 x double> %r, i64 7, i64 %avl)159  ret <vscale x 1 x double> %8160}161 162define <vscale x 1 x double> @test5(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {163; CHECK-LABEL: test5:164; CHECK:       # %bb.0: # %entry165; CHECK-NEXT:    andi a2, a1, 1166; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma167; CHECK-NEXT:    bnez a2, .LBB4_3168; CHECK-NEXT:  # %bb.1: # %if.else169; CHECK-NEXT:    vfsub.vv v9, v8, v9170; CHECK-NEXT:    andi a1, a1, 2171; CHECK-NEXT:    beqz a1, .LBB4_4172; CHECK-NEXT:  .LBB4_2: # %if.then4173; CHECK-NEXT:    vfmul.vv v8, v9, v8174; CHECK-NEXT:    ret175; CHECK-NEXT:  .LBB4_3: # %if.then176; CHECK-NEXT:    vfadd.vv v9, v8, v9177; CHECK-NEXT:    andi a1, a1, 2178; CHECK-NEXT:    bnez a1, .LBB4_2179; CHECK-NEXT:  .LBB4_4: # %if.else5180; CHECK-NEXT:    vfmul.vv v8, v8, v9181; CHECK-NEXT:    ret182entry:183  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)184  %conv = zext i8 %cond to i32185  %and = and i32 %conv, 1186  %tobool = icmp eq i32 %and, 0187  br i1 %tobool, label %if.else, label %if.then188 189if.then:                                          ; preds = %entry190  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)191  br label %if.end192 193if.else:                                          ; preds = %entry194  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)195  br label %if.end196 197if.end:                                           ; preds = %if.else, %if.then198  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]199  %and2 = and i32 %conv, 2200  %tobool3 = icmp eq i32 %and2, 0201  br i1 %tobool3, label %if.else5, label %if.then4202 203if.then4:                                         ; preds = %if.end204  %3 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %c.0, <vscale x 1 x double> %a, i64 7, i64 %0)205  br label %if.end6206 207if.else5:                                         ; preds = %if.end208  %4 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %c.0, i64 7, i64 %0)209  br label %if.end6210 211if.end6:                                          ; preds = %if.else5, %if.then4212  %c.1 = phi <vscale x 1 x double> [ %3, %if.then4 ], [ %4, %if.else5 ]213  ret <vscale x 1 x double> %c.1214}215 216; FIXME: The explicit vsetvli in if.then4 could be removed as it is redundant217; with the one in the entry, but we lack the ability to remove explicit218; vsetvli instructions.219define <vscale x 1 x double> @test6(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {220; CHECK-LABEL: test6:221; CHECK:       # %bb.0: # %entry222; CHECK-NEXT:    andi a2, a1, 1223; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma224; CHECK-NEXT:    bnez a2, .LBB5_3225; CHECK-NEXT:  # %bb.1: # %if.else226; CHECK-NEXT:    vfsub.vv v8, v8, v9227; CHECK-NEXT:    andi a1, a1, 2228; CHECK-NEXT:    beqz a1, .LBB5_4229; CHECK-NEXT:  .LBB5_2: # %if.then4230; CHECK-NEXT:    li a1, 1023231; CHECK-NEXT:    slli a1, a1, 52232; CHECK-NEXT:    vmv.v.x v9, a1233; CHECK-NEXT:    li a1, 1234; CHECK-NEXT:    slli a1, a1, 62235; CHECK-NEXT:    vmv.v.x v10, a1236; CHECK-NEXT:    vfadd.vv v9, v9, v10237; CHECK-NEXT:    lui a1, %hi(scratch)238; CHECK-NEXT:    addi a1, a1, %lo(scratch)239; CHECK-NEXT:    vse64.v v9, (a1)240; CHECK-NEXT:    j .LBB5_5241; CHECK-NEXT:  .LBB5_3: # %if.then242; CHECK-NEXT:    vfadd.vv v8, v8, v9243; CHECK-NEXT:    andi a1, a1, 2244; CHECK-NEXT:    bnez a1, .LBB5_2245; CHECK-NEXT:  .LBB5_4: # %if.else5246; CHECK-NEXT:    vsetvli zero, a0, e32, m1, ta, ma247; CHECK-NEXT:    lui a1, 260096248; CHECK-NEXT:    vmv.v.x v9, a1249; CHECK-NEXT:    lui a1, 262144250; CHECK-NEXT:    vmv.v.x v10, a1251; CHECK-NEXT:    vfadd.vv v9, v9, v10252; CHECK-NEXT:    lui a1, %hi(scratch)253; CHECK-NEXT:    addi a1, a1, %lo(scratch)254; CHECK-NEXT:    vse32.v v9, (a1)255; CHECK-NEXT:  .LBB5_5: # %if.end10256; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma257; CHECK-NEXT:    vfmul.vv v8, v8, v8258; CHECK-NEXT:    ret259entry:260  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)261  %conv = zext i8 %cond to i32262  %and = and i32 %conv, 1263  %tobool = icmp eq i32 %and, 0264  br i1 %tobool, label %if.else, label %if.then265 266if.then:                                          ; preds = %entry267  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)268  br label %if.end269 270if.else:                                          ; preds = %entry271  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)272  br label %if.end273 274if.end:                                           ; preds = %if.else, %if.then275  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]276  %and2 = and i32 %conv, 2277  %tobool3 = icmp eq i32 %and2, 0278  br i1 %tobool3, label %if.else5, label %if.then4279 280if.then4:                                         ; preds = %if.end281  %3 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)282  %4 = tail call <vscale x 1 x double> @llvm.riscv.vfmv.v.f.nxv1f64.f64(<vscale x 1 x double> poison, double 1.000000e+00, i64 %3)283  %5 = tail call <vscale x 1 x double> @llvm.riscv.vfmv.v.f.nxv1f64.f64(<vscale x 1 x double> poison, double 2.000000e+00, i64 %3)284  %6 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %4, <vscale x 1 x double> %5, i64 7, i64 %3)285  %7 = bitcast ptr @scratch to ptr286  tail call void @llvm.riscv.vse.nxv1f64(<vscale x 1 x double> %6, ptr %7, i64 %3)287  br label %if.end10288 289if.else5:                                         ; preds = %if.end290  %8 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 0)291  %9 = tail call <vscale x 2 x float> @llvm.riscv.vfmv.v.f.nxv2f32.f32(<vscale x 2 x float> poison, float 1.000000e+00, i64 %8)292  %10 = tail call <vscale x 2 x float> @llvm.riscv.vfmv.v.f.nxv2f32.f32( <vscale x 2 x float> poison, float 2.000000e+00, i64 %8)293  %11 = tail call <vscale x 2 x float> @llvm.riscv.vfadd.nxv2f32.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %9, <vscale x 2 x float> %10, i64 7, i64 %8)294  %12 = bitcast ptr @scratch to ptr295  tail call void @llvm.riscv.vse.nxv2f32(<vscale x 2 x float> %11, ptr %12, i64 %8)296  br label %if.end10297 298if.end10:                                         ; preds = %if.else5, %if.then4299  %13 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %c.0, <vscale x 1 x double> %c.0, i64 7, i64 %0)300  ret <vscale x 1 x double> %13301}302 303declare void @foo()304 305; Similar to test1, but contains a call to @foo to act as barrier to analyzing306; VL/VTYPE.307define <vscale x 1 x double> @test8(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {308; CHECK-LABEL: test8:309; CHECK:       # %bb.0: # %entry310; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma311; CHECK-NEXT:    beqz a1, .LBB6_2312; CHECK-NEXT:  # %bb.1: # %if.then313; CHECK-NEXT:    vfadd.vv v8, v8, v9314; CHECK-NEXT:    ret315; CHECK-NEXT:  .LBB6_2: # %if.else316; CHECK-NEXT:    addi sp, sp, -32317; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill318; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill319; CHECK-NEXT:    csrr a1, vlenb320; CHECK-NEXT:    slli a1, a1, 1321; CHECK-NEXT:    sub sp, sp, a1322; CHECK-NEXT:    mv s0, a0323; CHECK-NEXT:    csrr a0, vlenb324; CHECK-NEXT:    add a0, a0, sp325; CHECK-NEXT:    addi a0, a0, 16326; CHECK-NEXT:    vs1r.v v9, (a0) # vscale x 8-byte Folded Spill327; CHECK-NEXT:    addi a0, sp, 16328; CHECK-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill329; CHECK-NEXT:    call foo330; CHECK-NEXT:    csrr a0, vlenb331; CHECK-NEXT:    add a0, a0, sp332; CHECK-NEXT:    addi a0, a0, 16333; CHECK-NEXT:    vl1r.v v8, (a0) # vscale x 8-byte Folded Reload334; CHECK-NEXT:    addi a0, sp, 16335; CHECK-NEXT:    vl1r.v v9, (a0) # vscale x 8-byte Folded Reload336; CHECK-NEXT:    vsetvli zero, s0, e64, m1, ta, ma337; CHECK-NEXT:    vfsub.vv v8, v9, v8338; CHECK-NEXT:    csrr a0, vlenb339; CHECK-NEXT:    slli a0, a0, 1340; CHECK-NEXT:    add sp, sp, a0341; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload342; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload343; CHECK-NEXT:    addi sp, sp, 32344; CHECK-NEXT:    ret345entry:346  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)347  %tobool = icmp eq i8 %cond, 0348  br i1 %tobool, label %if.else, label %if.then349 350if.then:                                          ; preds = %entry351  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)352  br label %if.end353 354if.else:                                          ; preds = %entry355  call void @foo()356  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)357  br label %if.end358 359if.end:                                           ; preds = %if.else, %if.then360  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]361  ret <vscale x 1 x double> %c.0362}363 364; Similar to test2, but contains a call to @foo to act as barrier to analyzing365; VL/VTYPE.366define <vscale x 1 x double> @test9(i64 %avl, i8 zeroext %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {367; CHECK-LABEL: test9:368; CHECK:       # %bb.0: # %entry369; CHECK-NEXT:    addi sp, sp, -32370; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill371; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill372; CHECK-NEXT:    csrr a2, vlenb373; CHECK-NEXT:    slli a2, a2, 1374; CHECK-NEXT:    sub sp, sp, a2375; CHECK-NEXT:    mv s0, a0376; CHECK-NEXT:    vsetvli zero, a0, e64, m1, ta, ma377; CHECK-NEXT:    beqz a1, .LBB7_2378; CHECK-NEXT:  # %bb.1: # %if.then379; CHECK-NEXT:    vfadd.vv v9, v8, v9380; CHECK-NEXT:    addi a0, sp, 16381; CHECK-NEXT:    vs1r.v v9, (a0) # vscale x 8-byte Folded Spill382; CHECK-NEXT:    csrr a0, vlenb383; CHECK-NEXT:    add a0, a0, sp384; CHECK-NEXT:    addi a0, a0, 16385; CHECK-NEXT:    vs1r.v v8, (a0) # vscale x 8-byte Folded Spill386; CHECK-NEXT:    call foo387; CHECK-NEXT:    addi a0, sp, 16388; CHECK-NEXT:    vl1r.v v9, (a0) # vscale x 8-byte Folded Reload389; CHECK-NEXT:    csrr a0, vlenb390; CHECK-NEXT:    add a0, a0, sp391; CHECK-NEXT:    addi a0, a0, 16392; CHECK-NEXT:    vl1r.v v8, (a0) # vscale x 8-byte Folded Reload393; CHECK-NEXT:    j .LBB7_3394; CHECK-NEXT:  .LBB7_2: # %if.else395; CHECK-NEXT:    vfsub.vv v9, v8, v9396; CHECK-NEXT:  .LBB7_3: # %if.end397; CHECK-NEXT:    vsetvli zero, s0, e64, m1, ta, ma398; CHECK-NEXT:    vfmul.vv v8, v9, v8399; CHECK-NEXT:    csrr a0, vlenb400; CHECK-NEXT:    slli a0, a0, 1401; CHECK-NEXT:    add sp, sp, a0402; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload403; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload404; CHECK-NEXT:    addi sp, sp, 32405; CHECK-NEXT:    ret406entry:407  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)408  %tobool = icmp eq i8 %cond, 0409  br i1 %tobool, label %if.else, label %if.then410 411if.then:                                          ; preds = %entry412  %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)413  call void @foo()414  br label %if.end415 416if.else:                                          ; preds = %entry417  %2 = tail call <vscale x 1 x double> @llvm.riscv.vfsub.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %a, <vscale x 1 x double> %b, i64 7, i64 %0)418  br label %if.end419 420if.end:                                           ; preds = %if.else, %if.then421  %c.0 = phi <vscale x 1 x double> [ %1, %if.then ], [ %2, %if.else ]422  %3 = tail call <vscale x 1 x double> @llvm.riscv.vfmul.nxv1f64.nxv1f64(<vscale x 1 x double> poison, <vscale x 1 x double> %c.0, <vscale x 1 x double> %a, i64 7, i64 %0)423  ret <vscale x 1 x double> %3424}425 426define void @saxpy_vec(i64 %n, float %a, ptr nocapture readonly %x, ptr nocapture %y) {427; CHECK-LABEL: saxpy_vec:428; CHECK:       # %bb.0: # %entry429; CHECK-NEXT:    vsetvli a3, a0, e32, m8, ta, ma430; CHECK-NEXT:    beqz a3, .LBB8_2431; CHECK-NEXT:  .LBB8_1: # %for.body432; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1433; CHECK-NEXT:    vle32.v v8, (a1)434; CHECK-NEXT:    vle32.v v16, (a2)435; CHECK-NEXT:    slli a4, a3, 2436; CHECK-NEXT:    sub a0, a0, a3437; CHECK-NEXT:    add a1, a1, a4438; CHECK-NEXT:    vsetvli zero, zero, e32, m8, tu, ma439; CHECK-NEXT:    vfmacc.vf v16, fa0, v8440; CHECK-NEXT:    vse32.v v16, (a2)441; CHECK-NEXT:    vsetvli a3, a0, e32, m8, ta, ma442; CHECK-NEXT:    add a2, a2, a4443; CHECK-NEXT:    bnez a3, .LBB8_1444; CHECK-NEXT:  .LBB8_2: # %for.end445; CHECK-NEXT:    ret446entry:447  %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 3)448  %cmp.not13 = icmp eq i64 %0, 0449  br i1 %cmp.not13, label %for.end, label %for.body450 451for.body:                                         ; preds = %for.body, %entry452  %1 = phi i64 [ %7, %for.body ], [ %0, %entry ]453  %n.addr.016 = phi i64 [ %sub, %for.body ], [ %n, %entry ]454  %x.addr.015 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]455  %y.addr.014 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]456  %2 = bitcast ptr %x.addr.015 to ptr457  %3 = tail call <vscale x 16 x float> @llvm.riscv.vle.nxv16f32.i64(<vscale x 16 x float> poison, ptr %2, i64 %1)458  %add.ptr = getelementptr inbounds float, ptr %x.addr.015, i64 %1459  %4 = bitcast ptr %y.addr.014 to ptr460  %5 = tail call <vscale x 16 x float> @llvm.riscv.vle.nxv16f32.i64(<vscale x 16 x float> poison, ptr %4, i64 %1)461  %6 = tail call <vscale x 16 x float> @llvm.riscv.vfmacc.nxv16f32.f32.i64(<vscale x 16 x float> %5, float %a, <vscale x 16 x float> %3, i64 7, i64 %1, i64 0)462  tail call void @llvm.riscv.vse.nxv16f32.i64(<vscale x 16 x float> %6, ptr %4, i64 %1)463  %add.ptr1 = getelementptr inbounds float, ptr %y.addr.014, i64 %1464  %sub = sub i64 %n.addr.016, %1465  %7 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %sub, i64 2, i64 3)466  %cmp.not = icmp eq i64 %7, 0467  br i1 %cmp.not, label %for.end, label %for.body468 469for.end:                                          ; preds = %for.body, %entry470  ret void471}472 473define void @saxpy_vec_demanded_fields(i64 %n, float %a, ptr nocapture readonly %x, ptr nocapture %y) {474; CHECK-LABEL: saxpy_vec_demanded_fields:475; CHECK:       # %bb.0: # %entry476; CHECK-NEXT:    vsetvli a3, a0, e32, m8, ta, ma477; CHECK-NEXT:    beqz a3, .LBB9_2478; CHECK-NEXT:  .LBB9_1: # %for.body479; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1480; CHECK-NEXT:    vsetvli zero, a3, e32, m8, ta, ma481; CHECK-NEXT:    vle32.v v8, (a1)482; CHECK-NEXT:    vle32.v v16, (a2)483; CHECK-NEXT:    slli a4, a3, 2484; CHECK-NEXT:    sub a0, a0, a3485; CHECK-NEXT:    add a1, a1, a4486; CHECK-NEXT:    vsetvli zero, zero, e32, m8, tu, ma487; CHECK-NEXT:    vfmacc.vf v16, fa0, v8488; CHECK-NEXT:    vse32.v v16, (a2)489; CHECK-NEXT:    vsetvli a3, a0, e16, m4, ta, ma490; CHECK-NEXT:    add a2, a2, a4491; CHECK-NEXT:    bnez a3, .LBB9_1492; CHECK-NEXT:  .LBB9_2: # %for.end493; CHECK-NEXT:    ret494entry:495  %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 3)496  %cmp.not13 = icmp eq i64 %0, 0497  br i1 %cmp.not13, label %for.end, label %for.body498 499for.body:                                         ; preds = %for.body, %entry500  %1 = phi i64 [ %7, %for.body ], [ %0, %entry ]501  %n.addr.016 = phi i64 [ %sub, %for.body ], [ %n, %entry ]502  %x.addr.015 = phi ptr [ %add.ptr, %for.body ], [ %x, %entry ]503  %y.addr.014 = phi ptr [ %add.ptr1, %for.body ], [ %y, %entry ]504  %2 = bitcast ptr %x.addr.015 to ptr505  %3 = tail call <vscale x 16 x float> @llvm.riscv.vle.nxv16f32.i64(<vscale x 16 x float> poison, ptr %2, i64 %1)506  %add.ptr = getelementptr inbounds float, ptr %x.addr.015, i64 %1507  %4 = bitcast ptr %y.addr.014 to ptr508  %5 = tail call <vscale x 16 x float> @llvm.riscv.vle.nxv16f32.i64(<vscale x 16 x float> poison, ptr %4, i64 %1)509  %6 = tail call <vscale x 16 x float> @llvm.riscv.vfmacc.nxv16f32.f32.i64(<vscale x 16 x float> %5, float %a, <vscale x 16 x float> %3, i64 7, i64 %1, i64 0)510  tail call void @llvm.riscv.vse.nxv16f32.i64(<vscale x 16 x float> %6, ptr %4, i64 %1)511  %add.ptr1 = getelementptr inbounds float, ptr %y.addr.014, i64 %1512  %sub = sub i64 %n.addr.016, %1513  %7 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %sub, i64 1, i64 2)514  %cmp.not = icmp eq i64 %7, 0515  br i1 %cmp.not, label %for.end, label %for.body516 517for.end:                                          ; preds = %for.body, %entry518  ret void519}520 521; We need a vsetvli in the last block because the predecessors have different522; VTYPEs. The AVL is the same and the SEW/LMUL ratio implies the same VLMAX so523; we don't need to read AVL and can keep VL unchanged.524define <vscale x 2 x i32> @test_vsetvli_x0_x0(ptr %x, ptr %y, <vscale x 2 x i32> %z, i64 %vl, i1 %cond) nounwind {525; CHECK-LABEL: test_vsetvli_x0_x0:526; CHECK:       # %bb.0: # %entry527; CHECK-NEXT:    vsetvli zero, a2, e32, m1, ta, ma528; CHECK-NEXT:    vle32.v v9, (a0)529; CHECK-NEXT:    andi a3, a3, 1530; CHECK-NEXT:    beqz a3, .LBB10_2531; CHECK-NEXT:  # %bb.1: # %if532; CHECK-NEXT:    vle16.v v10, (a1)533; CHECK-NEXT:    vsetvli zero, zero, e16, mf2, ta, ma534; CHECK-NEXT:    vwcvt.x.x.v v8, v10535; CHECK-NEXT:  .LBB10_2: # %if.end536; CHECK-NEXT:    vsetvli zero, zero, e32, m1, ta, ma537; CHECK-NEXT:    vadd.vv v8, v9, v8538; CHECK-NEXT:    ret539entry:540  %a = call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32(<vscale x 2 x i32> poison, ptr %x, i64 %vl)541  br i1 %cond, label %if, label %if.end542 543if:544  %b = call <vscale x 2 x i16> @llvm.riscv.vle.nxv2i16(<vscale x 2 x i16> poison, ptr %y, i64 %vl)545  %c = call <vscale x 2 x i32> @llvm.riscv.vwadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i16> %b, i16 0, i64 %vl)546  br label %if.end547 548if.end:549  %d = phi <vscale x 2 x i32> [ %z, %entry ], [ %c, %if ]550  %e = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %a, <vscale x 2 x i32> %d, i64 %vl)551  ret <vscale x 2 x i32> %e552}553 554; We can use X0, X0 vsetvli in if2 and if2.end. The merge point as if.end will555; see two different vtypes with the same SEW/LMUL ratio. At if2.end we will only556; know the SEW/LMUL ratio for the if.end predecessor and the full vtype for557; the if2 predecessor. This makes sure we can merge a SEW/LMUL predecessor with558; a predecessor we know the vtype for.559define <vscale x 2 x i32> @test_vsetvli_x0_x0_2(ptr %x, ptr %y, ptr %z, i64 %vl, i1 %cond, i1 %cond2, <vscale x 2 x i32> %w) nounwind {560; CHECK-LABEL: test_vsetvli_x0_x0_2:561; CHECK:       # %bb.0: # %entry562; CHECK-NEXT:    vsetvli zero, a3, e32, m1, ta, ma563; CHECK-NEXT:    vle32.v v9, (a0)564; CHECK-NEXT:    andi a4, a4, 1565; CHECK-NEXT:    beqz a4, .LBB11_2566; CHECK-NEXT:  # %bb.1: # %if567; CHECK-NEXT:    vle16.v v10, (a1)568; CHECK-NEXT:    vsetvli zero, zero, e16, mf2, ta, ma569; CHECK-NEXT:    vwadd.wv v9, v9, v10570; CHECK-NEXT:  .LBB11_2: # %if.end571; CHECK-NEXT:    andi a5, a5, 1572; CHECK-NEXT:    beqz a5, .LBB11_4573; CHECK-NEXT:  # %bb.3: # %if2574; CHECK-NEXT:    vsetvli zero, zero, e16, mf2, ta, ma575; CHECK-NEXT:    vle16.v v10, (a2)576; CHECK-NEXT:    vwadd.wv v9, v9, v10577; CHECK-NEXT:  .LBB11_4: # %if2.end578; CHECK-NEXT:    vsetvli zero, zero, e32, m1, ta, ma579; CHECK-NEXT:    vadd.vv v8, v9, v8580; CHECK-NEXT:    ret581entry:582  %a = call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32(<vscale x 2 x i32> poison, ptr %x, i64 %vl)583  br i1 %cond, label %if, label %if.end584 585if:586  %b = call <vscale x 2 x i16> @llvm.riscv.vle.nxv2i16(<vscale x 2 x i16> poison, ptr %y, i64 %vl)587  %c = call <vscale x 2 x i32> @llvm.riscv.vwadd.w.nxv2i32.nxv2i16(<vscale x 2 x i32> poison, <vscale x 2 x i32> %a, <vscale x 2 x i16> %b, i64 %vl)588  br label %if.end589 590if.end:591  %d = phi <vscale x 2 x i32> [ %a, %entry ], [ %c, %if ]592  br i1 %cond2, label %if2, label %if2.end593 594if2:595  %e = call <vscale x 2 x i16> @llvm.riscv.vle.nxv2i16(<vscale x 2 x i16> poison, ptr %z, i64 %vl)596  %f = call <vscale x 2 x i32> @llvm.riscv.vwadd.w.nxv2i32.nxv2i16(<vscale x 2 x i32> poison, <vscale x 2 x i32> %d, <vscale x 2 x i16> %e, i64 %vl)597  br label %if2.end598 599if2.end:600  %g = phi <vscale x 2 x i32> [ %d, %if.end ], [ %f, %if2 ]601  %h = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %g, <vscale x 2 x i32> %w, i64 %vl)602  ret <vscale x 2 x i32> %h603}604 605; We should only need 1 vsetvli for this code.606define void @vlmax(i64 %N, ptr %c, ptr %a, ptr %b) {607; CHECK-LABEL: vlmax:608; CHECK:       # %bb.0: # %entry609; CHECK-NEXT:    blez a0, .LBB12_3610; CHECK-NEXT:  # %bb.1: # %for.body.preheader611; CHECK-NEXT:    li a4, 0612; CHECK-NEXT:    vsetvli a6, zero, e64, m1, ta, ma613; CHECK-NEXT:    slli a5, a6, 3614; CHECK-NEXT:  .LBB12_2: # %for.body615; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1616; CHECK-NEXT:    vle64.v v8, (a2)617; CHECK-NEXT:    vle64.v v9, (a3)618; CHECK-NEXT:    add a4, a4, a6619; CHECK-NEXT:    add a3, a3, a5620; CHECK-NEXT:    vfadd.vv v8, v8, v9621; CHECK-NEXT:    vse64.v v8, (a1)622; CHECK-NEXT:    add a1, a1, a5623; CHECK-NEXT:    add a2, a2, a5624; CHECK-NEXT:    blt a4, a0, .LBB12_2625; CHECK-NEXT:  .LBB12_3: # %for.end626; CHECK-NEXT:    ret627entry:628  %0 = tail call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 0)629  %cmp13 = icmp sgt i64 %N, 0630  br i1 %cmp13, label %for.body, label %for.end631 632for.body:                                         ; preds = %entry, %for.body633  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]634  %arrayidx = getelementptr inbounds double, ptr %a, i64 %i.014635  %1 = bitcast ptr %arrayidx to ptr636  %2 = tail call <vscale x 1 x double> @llvm.riscv.vle.nxv1f64.i64(<vscale x 1 x double> poison, ptr %1, i64 %0)637  %arrayidx1 = getelementptr inbounds double, ptr %b, i64 %i.014638  %3 = bitcast ptr %arrayidx1 to ptr639  %4 = tail call <vscale x 1 x double> @llvm.riscv.vle.nxv1f64.i64(<vscale x 1 x double> poison, ptr %3, i64 %0)640  %5 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64.i64(<vscale x 1 x double> poison, <vscale x 1 x double> %2, <vscale x 1 x double> %4, i64 7, i64 %0)641  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014642  %6 = bitcast ptr %arrayidx2 to ptr643  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> %5, ptr %6, i64 %0)644  %add = add nuw nsw i64 %i.014, %0645  %cmp = icmp slt i64 %add, %N646  br i1 %cmp, label %for.body, label %for.end647 648for.end:                                          ; preds = %for.body, %entry649  ret void650}651 652; A single vector store in the loop with VL controlled by VLMAX653define void @vector_init_vlmax(i64 %N, ptr %c) {654; CHECK-LABEL: vector_init_vlmax:655; CHECK:       # %bb.0: # %entry656; CHECK-NEXT:    blez a0, .LBB13_3657; CHECK-NEXT:  # %bb.1: # %for.body.preheader658; CHECK-NEXT:    li a2, 0659; CHECK-NEXT:    vsetvli a3, zero, e64, m1, ta, ma660; CHECK-NEXT:    slli a4, a3, 3661; CHECK-NEXT:    vmv.v.i v8, 0662; CHECK-NEXT:  .LBB13_2: # %for.body663; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1664; CHECK-NEXT:    vse64.v v8, (a1)665; CHECK-NEXT:    add a2, a2, a3666; CHECK-NEXT:    add a1, a1, a4667; CHECK-NEXT:    blt a2, a0, .LBB13_2668; CHECK-NEXT:  .LBB13_3: # %for.end669; CHECK-NEXT:    ret670entry:671  %0 = tail call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 0)672  %cmp13 = icmp sgt i64 %N, 0673  br i1 %cmp13, label %for.body, label %for.end674 675for.body:                                         ; preds = %entry, %for.body676  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]677  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014678  %addr = bitcast ptr %arrayidx2 to ptr679  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> zeroinitializer, ptr %addr, i64 %0)680  %add = add nuw nsw i64 %i.014, %0681  %cmp = icmp slt i64 %add, %N682  br i1 %cmp, label %for.body, label %for.end683 684for.end:                                          ; preds = %for.body, %entry685  ret void686}687 688; Same as above, but VL comes from user provided AVL value689define void @vector_init_vsetvli_N(i64 %N, ptr %c) {690; CHECK-LABEL: vector_init_vsetvli_N:691; CHECK:       # %bb.0: # %entry692; CHECK-NEXT:    blez a0, .LBB14_3693; CHECK-NEXT:  # %bb.1: # %for.body.preheader694; CHECK-NEXT:    li a2, 0695; CHECK-NEXT:    vsetvli a3, a0, e64, m1, ta, ma696; CHECK-NEXT:    slli a4, a3, 3697; CHECK-NEXT:    vmv.v.i v8, 0698; CHECK-NEXT:  .LBB14_2: # %for.body699; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1700; CHECK-NEXT:    vse64.v v8, (a1)701; CHECK-NEXT:    add a2, a2, a3702; CHECK-NEXT:    add a1, a1, a4703; CHECK-NEXT:    blt a2, a0, .LBB14_2704; CHECK-NEXT:  .LBB14_3: # %for.end705; CHECK-NEXT:    ret706entry:707  %0 = tail call i64 @llvm.riscv.vsetvli(i64 %N, i64 3, i64 0)708  %cmp13 = icmp sgt i64 %N, 0709  br i1 %cmp13, label %for.body, label %for.end710 711for.body:                                         ; preds = %entry, %for.body712  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]713  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014714  %addr = bitcast ptr %arrayidx2 to ptr715  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> zeroinitializer, ptr %addr, i64 %0)716  %add = add nuw nsw i64 %i.014, %0717  %cmp = icmp slt i64 %add, %N718  br i1 %cmp, label %for.body, label %for.end719 720for.end:                                          ; preds = %for.body, %entry721  ret void722}723 724; Same as above, but VL is a hard coded constant (in the preheader)725define void @vector_init_vsetvli_fv(i64 %N, ptr %c) {726; CHECK-LABEL: vector_init_vsetvli_fv:727; CHECK:       # %bb.0: # %entry728; CHECK-NEXT:    li a2, 0729; CHECK-NEXT:    vsetivli a3, 4, e64, m1, ta, ma730; CHECK-NEXT:    slli a4, a3, 3731; CHECK-NEXT:    vmv.v.i v8, 0732; CHECK-NEXT:  .LBB15_1: # %for.body733; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1734; CHECK-NEXT:    vse64.v v8, (a1)735; CHECK-NEXT:    add a2, a2, a3736; CHECK-NEXT:    add a1, a1, a4737; CHECK-NEXT:    blt a2, a0, .LBB15_1738; CHECK-NEXT:  # %bb.2: # %for.end739; CHECK-NEXT:    ret740entry:741  %0 = tail call i64 @llvm.riscv.vsetvli(i64 4, i64 3, i64 0)742  br label %for.body743 744for.body:                                         ; preds = %entry, %for.body745  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]746  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014747  %addr = bitcast ptr %arrayidx2 to ptr748  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> zeroinitializer, ptr %addr, i64 %0)749  %add = add nuw nsw i64 %i.014, %0750  %cmp = icmp slt i64 %add, %N751  br i1 %cmp, label %for.body, label %for.end752 753for.end:                                          ; preds = %for.body754  ret void755}756 757; Same as above, but result of vsetvli in preheader isn't used, and758; constant is repeated in loop759define void @vector_init_vsetvli_fv2(i64 %N, ptr %c) {760; CHECK-LABEL: vector_init_vsetvli_fv2:761; CHECK:       # %bb.0: # %entry762; CHECK-NEXT:    li a2, 0763; CHECK-NEXT:    vsetivli zero, 4, e64, m1, ta, ma764; CHECK-NEXT:    vmv.v.i v8, 0765; CHECK-NEXT:  .LBB16_1: # %for.body766; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1767; CHECK-NEXT:    vse64.v v8, (a1)768; CHECK-NEXT:    addi a2, a2, 4769; CHECK-NEXT:    addi a1, a1, 32770; CHECK-NEXT:    blt a2, a0, .LBB16_1771; CHECK-NEXT:  # %bb.2: # %for.end772; CHECK-NEXT:    ret773entry:774  tail call i64 @llvm.riscv.vsetvli(i64 4, i64 3, i64 0)775  br label %for.body776 777for.body:                                         ; preds = %entry, %for.body778  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]779  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014780  %addr = bitcast ptr %arrayidx2 to ptr781  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> zeroinitializer, ptr %addr, i64 4)782  %add = add nuw nsw i64 %i.014, 4783  %cmp = icmp slt i64 %add, %N784  br i1 %cmp, label %for.body, label %for.end785 786for.end:                                          ; preds = %for.body787  ret void788}789 790; Same as above, but AVL is only specified on the store intrinsic791; This case will require some form of hoisting or PRE792define void @vector_init_vsetvli_fv3(i64 %N, ptr %c) {793; CHECK-LABEL: vector_init_vsetvli_fv3:794; CHECK:       # %bb.0: # %entry795; CHECK-NEXT:    li a2, 0796; CHECK-NEXT:    vsetivli zero, 4, e64, m1, ta, ma797; CHECK-NEXT:    vmv.v.i v8, 0798; CHECK-NEXT:  .LBB17_1: # %for.body799; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1800; CHECK-NEXT:    vse64.v v8, (a1)801; CHECK-NEXT:    addi a2, a2, 4802; CHECK-NEXT:    addi a1, a1, 32803; CHECK-NEXT:    blt a2, a0, .LBB17_1804; CHECK-NEXT:  # %bb.2: # %for.end805; CHECK-NEXT:    ret806entry:807  br label %for.body808 809for.body:                                         ; preds = %entry, %for.body810  %i.014 = phi i64 [ %add, %for.body ], [ 0, %entry ]811  %arrayidx2 = getelementptr inbounds double, ptr %c, i64 %i.014812  %addr = bitcast ptr %arrayidx2 to ptr813  tail call void @llvm.riscv.vse.nxv1f64.i64(<vscale x 1 x double> zeroinitializer, ptr %addr, i64 4)814  %add = add nuw nsw i64 %i.014, 4815  %cmp = icmp slt i64 %add, %N816  br i1 %cmp, label %for.body, label %for.end817 818for.end:                                          ; preds = %for.body819  ret void820}821 822; Demonstrates a case where mutation in phase3 is problematic.  We mutate the823; vsetvli without considering that it changes the compatibility result of the824; vadd in the second block.825define <vscale x 4 x i32> @cross_block_mutate(<vscale x 4 x i32> %a, <vscale x 4 x i32> %b,826; CHECK-LABEL: cross_block_mutate:827; CHECK:       # %bb.0: # %entry828; CHECK-NEXT:    vsetivli a0, 6, e32, m2, tu, ma829; CHECK-NEXT:    vmv.s.x v8, a0830; CHECK-NEXT:    vsetvli zero, zero, e32, m2, ta, ma831; CHECK-NEXT:    vadd.vv v8, v8, v10, v0.t832; CHECK-NEXT:    ret833                                         <vscale x 4 x i1> %mask) {834entry:835  %vl = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 1, i64 0)836  %vl.trunc = trunc i64 %vl to i32837  %a.mod = insertelement <vscale x 4 x i32> %a, i32 %vl.trunc, i32 0838  br label %fallthrough839 840fallthrough:841  %res = call <vscale x 4 x i32> @llvm.riscv.vadd.mask.nxv4i32.nxv4i32(842               <vscale x 4 x i32> poison, <vscale x 4 x i32> %a.mod,843               <vscale x 4 x i32> %b, <vscale x 4 x i1> %mask, i64 %vl, i64 0)844  ret <vscale x 4 x i32> %res845}846 847define <vscale x 2 x i32> @pre_lmul(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i1 %cond) nounwind {848; CHECK-LABEL: pre_lmul:849; CHECK:       # %bb.0: # %entry850; CHECK-NEXT:    andi a0, a0, 1851; CHECK-NEXT:    vsetvli a1, zero, e64, m1, ta, ma852; CHECK-NEXT:    vsetvli zero, a1, e32, m1, ta, ma853; CHECK-NEXT:    vadd.vv v8, v8, v9854; CHECK-NEXT:    vadd.vv v8, v8, v9855; CHECK-NEXT:    ret856entry:857  %vl = tail call i64 @llvm.riscv.vsetvlimax.i64(i64 3, i64 0)858  %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 %vl)859  br i1 %cond, label %if, label %if.end860 861if:862  ; Deliberately change vtype - this could be an unknown call, but the broader863  ; code quality is distractingly bad864  tail call i64 @llvm.riscv.vsetvlimax.i64(i64 2, i64 1)865  br label %if.end866 867if.end:868  %b = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %a, <vscale x 2 x i32> %y, i64 %vl)869  ret <vscale x 2 x i32> %b870}871 872define <vscale x 1 x double> @compat_store_consistency(i1 %cond, <vscale x 1 x double> %a, <vscale x 1 x double> %b, ptr %p1, <vscale x 1 x float> %c, ptr %p2) {873; CHECK-LABEL: compat_store_consistency:874; CHECK:       # %bb.0: # %entry875; CHECK-NEXT:    andi a0, a0, 1876; CHECK-NEXT:    vsetvli a3, zero, e64, m1, ta, ma877; CHECK-NEXT:    vfadd.vv v8, v8, v9878; CHECK-NEXT:    vs1r.v v8, (a1)879; CHECK-NEXT:    beqz a0, .LBB20_2880; CHECK-NEXT:  # %bb.1: # %if.then881; CHECK-NEXT:    vse32.v v10, (a2)882; CHECK-NEXT:  .LBB20_2: # %if.end883; CHECK-NEXT:    ret884entry:885  %res = fadd <vscale x 1 x double> %a, %b886  store <vscale x 1 x double> %res, ptr %p1887  br i1 %cond, label %if.then, label %if.end888 889if.then:                                          ; preds = %entry890  store <vscale x 1 x float> %c, ptr %p2891  br label %if.end892 893if.end:                                           ; preds = %if.else, %if.then894  ret <vscale x 1 x double> %res895}896 897; Next two tests (which are the same except for swapped block order), make sure that the898; demanded reasoning around vmv.s.x correctly handles a forward state with only a valid899; SEWLMULRatio.  We previously had a crash bug in this case.900define <vscale x 2 x i32> @test_ratio_only_vmv_s_x(ptr %x, ptr %y, i1 %cond) nounwind {901; CHECK-LABEL: test_ratio_only_vmv_s_x:902; CHECK:       # %bb.0: # %entry903; CHECK-NEXT:    andi a2, a2, 1904; CHECK-NEXT:    beqz a2, .LBB21_2905; CHECK-NEXT:  # %bb.1: # %if906; CHECK-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma907; CHECK-NEXT:    vle16.v v9, (a1)908; CHECK-NEXT:    vwcvt.x.x.v v8, v9909; CHECK-NEXT:    j .LBB21_3910; CHECK-NEXT:  .LBB21_2:911; CHECK-NEXT:    vsetivli zero, 2, e32, m1, ta, ma912; CHECK-NEXT:    vle32.v v8, (a0)913; CHECK-NEXT:  .LBB21_3: # %if.end914; CHECK-NEXT:    vsetvli zero, zero, e32, m1, tu, ma915; CHECK-NEXT:    vmv.s.x v8, zero916; CHECK-NEXT:    ret917entry:918  %a = call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32(<vscale x 2 x i32> poison, ptr %x, i64 2)919  br i1 %cond, label %if, label %if.end920 921if:922  %b = call <vscale x 2 x i16> @llvm.riscv.vle.nxv2i16(<vscale x 2 x i16> poison, ptr %y, i64 2)923  %c = call <vscale x 2 x i32> @llvm.riscv.vwadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i16> %b, i16 0, i64 2)924  br label %if.end925 926if.end:927  %d = phi <vscale x 2 x i32> [ %a, %entry ], [ %c, %if ]928  %e = insertelement <vscale x 2 x i32> %d, i32 0, i32 0929  ret <vscale x 2 x i32> %e930}931 932define <vscale x 2 x i32> @test_ratio_only_vmv_s_x2(ptr %x, ptr %y, i1 %cond) nounwind {933; CHECK-LABEL: test_ratio_only_vmv_s_x2:934; CHECK:       # %bb.0: # %entry935; CHECK-NEXT:    andi a2, a2, 1936; CHECK-NEXT:    beqz a2, .LBB22_2937; CHECK-NEXT:  # %bb.1: # %if938; CHECK-NEXT:    vsetivli zero, 2, e32, m1, ta, ma939; CHECK-NEXT:    vle32.v v8, (a0)940; CHECK-NEXT:    j .LBB22_3941; CHECK-NEXT:  .LBB22_2:942; CHECK-NEXT:    vsetivli zero, 2, e16, mf2, ta, ma943; CHECK-NEXT:    vle16.v v9, (a1)944; CHECK-NEXT:    vwcvt.x.x.v v8, v9945; CHECK-NEXT:  .LBB22_3: # %if.end946; CHECK-NEXT:    vsetvli zero, zero, e32, m1, tu, ma947; CHECK-NEXT:    vmv.s.x v8, zero948; CHECK-NEXT:    ret949entry:950  %b = call <vscale x 2 x i16> @llvm.riscv.vle.nxv2i16(<vscale x 2 x i16> poison, ptr %y, i64 2)951  %c = call <vscale x 2 x i32> @llvm.riscv.vwadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i16> %b, i16 0, i64 2)952  br i1 %cond, label %if, label %if.end953 954if:955  %a = call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32(<vscale x 2 x i32> poison, ptr %x, i64 2)956  br label %if.end957 958if.end:959  %d = phi <vscale x 2 x i32> [ %a, %if ], [ %c, %entry ]960  %e = insertelement <vscale x 2 x i32> %d, i32 0, i32 0961  ret <vscale x 2 x i32> %e962}963 964; This case demonstrates a PRE case where the first instruction in the block965; doesn't require a state transition.966define void @pre_over_vle(ptr %A) {967; CHECK-LABEL: pre_over_vle:968; CHECK:       # %bb.0: # %entry969; CHECK-NEXT:    addi a1, a0, 800970; CHECK-NEXT:    vsetivli zero, 2, e32, mf2, ta, ma971; CHECK-NEXT:  .LBB23_1: # %vector.body972; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1973; CHECK-NEXT:    vle8.v v8, (a0)974; CHECK-NEXT:    vsext.vf4 v9, v8975; CHECK-NEXT:    vse32.v v9, (a0)976; CHECK-NEXT:    addi a0, a0, 8977; CHECK-NEXT:    bne a0, a1, .LBB23_1978; CHECK-NEXT:  # %bb.2: # %exit979; CHECK-NEXT:    ret980entry:981  br label %vector.body982 983vector.body:984  %iv = phi i64 [ 0, %entry], [%iv.next, %vector.body]985  %addr = getelementptr inbounds <2 x i32>, ptr %A, i64 %iv986  %v = load <2 x i8>, ptr %addr987  %v2 = sext <2 x i8> %v to <2 x i32>988  store <2 x i32> %v2, ptr %addr989  %iv.next = add i64 %iv, 1990  %cmp = icmp ne i64 %iv.next, 100991  br i1 %cmp, label %vector.body, label %exit992exit:993  ret void994}995 996; Normally a pseudo's AVL is already live in its block, so it will already be997; live where we're inserting the vsetvli, before the pseudo.  In some cases the998; AVL can be from a predecessor block, so make sure we extend its live range999; across blocks.1000define <vscale x 2 x i32> @cross_block_avl_extend(i64 %avl, <vscale x 2 x i32> %a, <vscale x 2 x i32> %b) {1001; CHECK-LABEL: cross_block_avl_extend:1002; CHECK:       # %bb.0: # %entry1003; CHECK-NEXT:    vsetivli zero, 1, e32, m1, ta, ma1004; CHECK-NEXT:    vadd.vv v9, v8, v91005; CHECK-NEXT:    vsetvli zero, a0, e32, m1, ta, ma1006; CHECK-NEXT:    vadd.vv v8, v8, v91007; CHECK-NEXT:    ret1008entry:1009  ; Get the output vl from a vsetvli1010  %vl = call i64 @llvm.riscv.vsetvli.i64(i64 %avl, i64 2, i64 0)1011  ; Force a vsetvli toggle so we need to insert a new vsetvli in exit1012  %d = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %a, <vscale x 2 x i32> %b, i64 1)1013  br label %exit1014exit:1015  ; The use of the vl from the vsetvli will be replaced with its %avl because1016  ; VLMAX is the same. So %avl, which was previously only live in %entry, will1017  ; need to be extended down toe %exit.1018  %c = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %a, <vscale x 2 x i32> %d, i64 %vl)1019  ret <vscale x 2 x i32> %c1020}1021 1022define void @cross_block_avl_extend_backwards(i1 %cond, <vscale x 8 x i8> %v, ptr %p, i64 %avl) {1023; CHECK-LABEL: cross_block_avl_extend_backwards:1024; CHECK:       # %bb.0: # %entry1025; CHECK-NEXT:    andi a0, a0, 11026; CHECK-NEXT:    beqz a0, .LBB25_21027; CHECK-NEXT:  # %bb.1: # %exit1028; CHECK-NEXT:    ret1029; CHECK-NEXT:  .LBB25_2: # %bar1030; CHECK-NEXT:    addi a2, a2, 11031; CHECK-NEXT:  .LBB25_3: # %foo1032; CHECK-NEXT:    # =>This Inner Loop Header: Depth=11033; CHECK-NEXT:    vsetivli zero, 1, e8, m1, ta, ma1034; CHECK-NEXT:    vse8.v v8, (a1)1035; CHECK-NEXT:    vsetvli zero, a2, e8, m1, ta, ma1036; CHECK-NEXT:    vse8.v v8, (a1)1037; CHECK-NEXT:    j .LBB25_31038entry:1039  br i1 %cond, label %exit, label %bar1040foo:1041  ; Force a vl toggle1042  call void @llvm.riscv.vse.nxv8i8.i64(<vscale x 8 x i8> %v, ptr %p, i64 1)1043  ; %add's LiveRange needs to be extended backwards to here.1044  call void @llvm.riscv.vse.nxv8i8.i64(<vscale x 8 x i8> %v, ptr %p, i64 %add)1045  br label %foo1046exit:1047  ret void1048bar:1049  %add = add i64 %avl, 11050  br label %foo1051}1052 1053define void @vlmax_avl_phi(i1 %cmp, ptr %p, i64 %a, i64 %b) {1054; CHECK-LABEL: vlmax_avl_phi:1055; CHECK:       # %bb.0: # %entry1056; CHECK-NEXT:    andi a0, a0, 11057; CHECK-NEXT:    beqz a0, .LBB26_21058; CHECK-NEXT:  # %bb.1: # %foo1059; CHECK-NEXT:    vsetvli zero, a2, e8, m1, ta, ma1060; CHECK-NEXT:    j .LBB26_31061; CHECK-NEXT:  .LBB26_2: # %bar1062; CHECK-NEXT:    vsetvli zero, a3, e8, m1, ta, ma1063; CHECK-NEXT:  .LBB26_3: # %exit1064; CHECK-NEXT:    vmv.v.i v8, 01065; CHECK-NEXT:    vsetivli zero, 1, e8, m1, ta, ma1066; CHECK-NEXT:    vse8.v v8, (a1)1067; CHECK-NEXT:    ret1068entry:1069  br i1 %cmp, label %foo, label %bar1070 1071foo:1072  %vl.foo = tail call i64 @llvm.riscv.vsetvli.i64(i64 %a, i64 0, i64 0)1073  br label %exit1074 1075bar:1076  %vl.bar = tail call i64 @llvm.riscv.vsetvli.i64(i64 %b, i64 0, i64 0)1077  br label %exit1078 1079exit:1080  %phivl = phi i64 [ %vl.foo, %foo ], [ %vl.bar, %bar ]1081  %1 = tail call <vscale x 8 x i8> @llvm.riscv.vmv.v.x.nxv8i8.i64(<vscale x 8 x i8> poison, i8 0, i64 %phivl)1082  call void @llvm.riscv.vse.nxv8i8(<vscale x 8 x i8> %1, ptr %p, i64 1)1083  ret void1084}1085 1086; Check that if we forward an AVL whose value is clobbered in its LiveInterval1087; we emit a copy instead.1088define <vscale x 4 x i32> @clobbered_forwarded_avl(i64 %n, <vscale x 4 x i32> %v, i1 %cmp) {1089; CHECK-LABEL: clobbered_forwarded_avl:1090; CHECK:       # %bb.0: # %entry1091; CHECK-NEXT:    vsetvli zero, a0, e32, m2, ta, ma1092; CHECK-NEXT:    andi a1, a1, 11093; CHECK-NEXT:  .LBB27_1: # %for.body1094; CHECK-NEXT:    # =>This Inner Loop Header: Depth=11095; CHECK-NEXT:    addi a0, a0, 11096; CHECK-NEXT:    bnez a1, .LBB27_11097; CHECK-NEXT:  # %bb.2: # %for.cond.cleanup1098; CHECK-NEXT:    vadd.vv v10, v8, v81099; CHECK-NEXT:    vadd.vv v8, v10, v81100; CHECK-NEXT:    ret1101entry:1102  %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 1)1103  br label %for.body1104 1105for.body:1106  ; Use %n in a PHI here so its virtual register is assigned to a second time here.1107  %1 = phi i64 [ %3, %for.body ], [ %n, %entry ]1108  %2 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %1, i64 0, i64 0)1109  %3 = add i64 %1, 11110  br i1 %cmp, label %for.body, label %for.cond.cleanup1111 1112for.cond.cleanup:1113  %4 = tail call <vscale x 4 x i32> @llvm.riscv.vadd.nxv2f32.nxv2f32.i64(<vscale x 4 x i32> poison, <vscale x 4 x i32> %v, <vscale x 4 x i32> %v, i64 -1)1114  ; VL toggle needed here: If the %n AVL was forwarded here we wouldn't be able1115  ; to extend it's LiveInterval because it would clobber the assignment at %1.1116  %5 = tail call <vscale x 4 x i32> @llvm.riscv.vadd.nxv2f32.nxv2f32.i64(<vscale x 4 x i32> poison, <vscale x 4 x i32> %4, <vscale x 4 x i32> %v, i64 %0)1117  ret <vscale x 4 x i32> %51118}1119