848 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 -verify-machineinstrs -O2 < %s | FileCheck %s --check-prefixes=CHECK,NODEPVL3; RUN: llc -mtriple=riscv64 -mattr=+m,+f,+d,+a,+c,+v,+vl-dependent-latency -verify-machineinstrs -O2 < %s | FileCheck %s --check-prefixes=CHECK,DEPVL4 5define <vscale x 1 x double> @test1(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {6; CHECK-LABEL: test1:7; CHECK: # %bb.0: # %entry8; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma9; CHECK-NEXT: vfadd.vv v8, v8, v910; CHECK-NEXT: ret11entry:12 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)13 %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(14 <vscale x 1 x double> poison,15 <vscale x 1 x double> %a,16 <vscale x 1 x double> %b,17 i64 7, i64 %0)18 ret <vscale x 1 x double> %119}20 21define <vscale x 1 x double> @test2(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {22; CHECK-LABEL: test2:23; CHECK: # %bb.0: # %entry24; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma25; CHECK-NEXT: vfadd.vv v8, v8, v926; CHECK-NEXT: ret27entry:28 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)29 %1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(30 <vscale x 1 x double> poison,31 <vscale x 1 x double> %a,32 <vscale x 1 x double> %b,33 i64 7, i64 %avl)34 ret <vscale x 1 x double> %135}36 37define <vscale x 1 x i64> @test3(i64 %avl, <vscale x 1 x i64> %a, ptr %b, <vscale x 1 x i1> %c) nounwind {38; CHECK-LABEL: test3:39; CHECK: # %bb.0: # %entry40; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, mu41; CHECK-NEXT: vle64.v v8, (a1), v0.t42; CHECK-NEXT: ret43entry:44 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)45 %1 = call <vscale x 1 x i64> @llvm.riscv.vle.mask.nxv1i64(46 <vscale x 1 x i64> %a,47 ptr %b,48 <vscale x 1 x i1> %c,49 i64 %0, i64 1)50 51 ret <vscale x 1 x i64> %152}53 54define <vscale x 1 x i64> @test4(i64 %avl, <vscale x 1 x i64> %a, ptr %b, <vscale x 1 x i1> %c) nounwind {55; CHECK-LABEL: test4:56; CHECK: # %bb.0: # %entry57; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, mu58; CHECK-NEXT: vle64.v v8, (a1), v0.t59; CHECK-NEXT: ret60entry:61 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)62 %1 = call <vscale x 1 x i64> @llvm.riscv.vle.mask.nxv1i64(63 <vscale x 1 x i64> %a,64 ptr %b,65 <vscale x 1 x i1> %c,66 i64 %avl, i64 1)67 68 ret <vscale x 1 x i64> %169}70 71; Make sure we don't insert a vsetvli for the vmand instruction.72define <vscale x 1 x i1> @test5(<vscale x 1 x i64> %0, <vscale x 1 x i64> %1, <vscale x 1 x i1> %2, i64 %avl) nounwind {73; CHECK-LABEL: test5:74; CHECK: # %bb.0: # %entry75; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma76; CHECK-NEXT: vmseq.vv v8, v8, v977; CHECK-NEXT: vmand.mm v0, v8, v078; CHECK-NEXT: ret79entry:80 %vl = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 0)81 %a = call <vscale x 1 x i1> @llvm.riscv.vmseq.nxv1i64.i64(<vscale x 1 x i64> %0, <vscale x 1 x i64> %1, i64 %vl)82 %b = call <vscale x 1 x i1> @llvm.riscv.vmand.nxv1i1.i64(<vscale x 1 x i1> %a, <vscale x 1 x i1> %2, i64 %vl)83 ret <vscale x 1 x i1> %b84}85 86; Make sure we don't insert a vsetvli for the vmor instruction.87define void @test6(ptr nocapture readonly %A, ptr nocapture %B, i64 %n) {88; CHECK-LABEL: test6:89; CHECK: # %bb.0: # %entry90; CHECK-NEXT: vsetvli a2, a2, e32, m1, ta, ma91; CHECK-NEXT: beqz a2, .LBB5_392; CHECK-NEXT: # %bb.1: # %for.body.preheader93; CHECK-NEXT: li a3, 094; CHECK-NEXT: .LBB5_2: # %for.body95; CHECK-NEXT: # =>This Inner Loop Header: Depth=196; CHECK-NEXT: slli a4, a3, 297; CHECK-NEXT: add a5, a0, a498; CHECK-NEXT: vle32.v v8, (a5)99; CHECK-NEXT: add a3, a3, a2100; CHECK-NEXT: vmsle.vi v9, v8, -3101; CHECK-NEXT: vmsgt.vi v10, v8, 2102; CHECK-NEXT: vmor.mm v0, v9, v10103; CHECK-NEXT: add a4, a4, a1104; CHECK-NEXT: vse32.v v8, (a4), v0.t105; CHECK-NEXT: vsetvli a2, a2, e32, m1, ta, ma106; CHECK-NEXT: bnez a2, .LBB5_2107; CHECK-NEXT: .LBB5_3: # %for.cond.cleanup108; CHECK-NEXT: ret109entry:110 %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 2, i64 0)111 %cmp.not11 = icmp eq i64 %0, 0112 br i1 %cmp.not11, label %for.cond.cleanup, label %for.body113 114for.cond.cleanup: ; preds = %for.body, %entry115 ret void116 117for.body: ; preds = %entry, %for.body118 %1 = phi i64 [ %8, %for.body ], [ %0, %entry ]119 %i.012 = phi i64 [ %add, %for.body ], [ 0, %entry ]120 %add.ptr = getelementptr inbounds i32, ptr %A, i64 %i.012121 %2 = bitcast ptr %add.ptr to ptr122 %3 = tail call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32.i64(<vscale x 2 x i32> poison, ptr %2, i64 %1)123 %4 = tail call <vscale x 2 x i1> @llvm.riscv.vmslt.nxv2i32.i32.i64(<vscale x 2 x i32> %3, i32 -2, i64 %1)124 %5 = tail call <vscale x 2 x i1> @llvm.riscv.vmsgt.nxv2i32.i32.i64(<vscale x 2 x i32> %3, i32 2, i64 %1)125 %6 = tail call <vscale x 2 x i1> @llvm.riscv.vmor.nxv2i1.i64(<vscale x 2 x i1> %4, <vscale x 2 x i1> %5, i64 %1)126 %add.ptr1 = getelementptr inbounds i32, ptr %B, i64 %i.012127 %7 = bitcast ptr %add.ptr1 to ptr128 tail call void @llvm.riscv.vse.mask.nxv2i32.i64(<vscale x 2 x i32> %3, ptr %7, <vscale x 2 x i1> %6, i64 %1)129 %add = add i64 %1, %i.012130 %8 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %1, i64 2, i64 0)131 %cmp.not = icmp eq i64 %8, 0132 br i1 %cmp.not, label %for.cond.cleanup, label %for.body133}134 135define <vscale x 1 x i64> @test7(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {136; CHECK-LABEL: test7:137; CHECK: # %bb.0: # %entry138; CHECK-NEXT: vsetivli zero, 1, e64, m1, tu, ma139; CHECK-NEXT: vmv.s.x v8, a0140; CHECK-NEXT: ret141entry:142 %x = tail call i64 @llvm.riscv.vsetvlimax(i64 3, i64 0)143 %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(144 <vscale x 1 x i64> %a,145 i64 %b, i64 1)146 147 ret <vscale x 1 x i64> %y148}149 150define <vscale x 1 x i64> @test8(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {151; CHECK-LABEL: test8:152; CHECK: # %bb.0: # %entry153; CHECK-NEXT: vsetivli zero, 2, e64, m1, tu, ma154; CHECK-NEXT: vmv.s.x v8, a0155; CHECK-NEXT: ret156entry:157 %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)158 %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(<vscale x 1 x i64> %a, i64 %b, i64 2)159 ret <vscale x 1 x i64> %y160}161 162define <vscale x 1 x i64> @test9(<vscale x 1 x i64> %a, i64 %b, <vscale x 1 x i1> %mask) nounwind {163; CHECK-LABEL: test9:164; CHECK: # %bb.0: # %entry165; CHECK-NEXT: vsetivli zero, 9, e64, m1, tu, mu166; CHECK-NEXT: vadd.vv v8, v8, v8, v0.t167; CHECK-NEXT: vmv.s.x v8, a0168; CHECK-NEXT: ret169entry:170 %x = call <vscale x 1 x i64> @llvm.riscv.vadd.mask.nxv1i64.nxv1i64(171 <vscale x 1 x i64> %a,172 <vscale x 1 x i64> %a,173 <vscale x 1 x i64> %a,174 <vscale x 1 x i1> %mask,175 i64 9,176 i64 0)177 %y = call <vscale x 1 x i64> @llvm.riscv.vmv.s.x.nxv1i64(<vscale x 1 x i64> %x, i64 %b, i64 2)178 ret <vscale x 1 x i64> %y179}180 181define <vscale x 1 x double> @test10(<vscale x 1 x double> %a, double %b) nounwind {182; CHECK-LABEL: test10:183; CHECK: # %bb.0: # %entry184; CHECK-NEXT: vsetivli zero, 1, e64, m1, tu, ma185; CHECK-NEXT: vfmv.s.f v8, fa0186; CHECK-NEXT: ret187entry:188 %x = tail call i64 @llvm.riscv.vsetvlimax(i64 3, i64 0)189 %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(190 <vscale x 1 x double> %a, double %b, i64 1)191 ret <vscale x 1 x double> %y192}193 194define <vscale x 1 x double> @test11(<vscale x 1 x double> %a, double %b) nounwind {195; CHECK-LABEL: test11:196; CHECK: # %bb.0: # %entry197; CHECK-NEXT: vsetivli zero, 2, e64, m1, tu, ma198; CHECK-NEXT: vfmv.s.f v8, fa0199; CHECK-NEXT: ret200entry:201 %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)202 %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(203 <vscale x 1 x double> %a, double %b, i64 2)204 ret <vscale x 1 x double> %y205}206 207define <vscale x 1 x double> @test12(<vscale x 1 x double> %a, double %b, <vscale x 1 x i1> %mask) nounwind {208; CHECK-LABEL: test12:209; CHECK: # %bb.0: # %entry210; CHECK-NEXT: vsetivli zero, 9, e64, m1, tu, mu211; CHECK-NEXT: vfadd.vv v8, v8, v8, v0.t212; CHECK-NEXT: vfmv.s.f v8, fa0213; CHECK-NEXT: ret214entry:215 %x = call <vscale x 1 x double> @llvm.riscv.vfadd.mask.nxv1f64.f64(216 <vscale x 1 x double> %a,217 <vscale x 1 x double> %a,218 <vscale x 1 x double> %a,219 <vscale x 1 x i1> %mask,220 i64 7,221 i64 9,222 i64 0)223 %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(224 <vscale x 1 x double> %x, double %b, i64 2)225 ret <vscale x 1 x double> %y226}227 228define <vscale x 1 x double> @test13(<vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {229; CHECK-LABEL: test13:230; CHECK: # %bb.0: # %entry231; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma232; CHECK-NEXT: vfadd.vv v8, v8, v9233; CHECK-NEXT: ret234entry:235 %0 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(236 <vscale x 1 x double> poison,237 <vscale x 1 x double> %a,238 <vscale x 1 x double> %b,239 i64 7, i64 -1)240 ret <vscale x 1 x double> %0241}242 243define <vscale x 1 x double> @test14(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {244; CHECK-LABEL: test14:245; CHECK: # %bb.0: # %entry246; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma247; CHECK-NEXT: vfadd.vv v8, v8, v9248; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma249; CHECK-NEXT: vfadd.vv v8, v8, v9250; CHECK-NEXT: ret251entry:252 %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)253 %f1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(254 <vscale x 1 x double> poison,255 <vscale x 1 x double> %a,256 <vscale x 1 x double> %b,257 i64 7, i64 1)258 %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(259 <vscale x 1 x double> poison,260 <vscale x 1 x double> %f1,261 <vscale x 1 x double> %b,262 i64 7, i64 %vsetvli)263 ret <vscale x 1 x double> %f2264}265 266define <vscale x 1 x double> @test15(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {267; CHECK-LABEL: test15:268; CHECK: # %bb.0: # %entry269; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma270; CHECK-NEXT: vfadd.vv v8, v8, v9271; CHECK-NEXT: vfadd.vv v8, v8, v9272; CHECK-NEXT: ret273entry:274 %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)275 %f1 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(276 <vscale x 1 x double> poison,277 <vscale x 1 x double> %a,278 <vscale x 1 x double> %b,279 i64 7, i64 %avl)280 %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(281 <vscale x 1 x double> poison,282 <vscale x 1 x double> %f1,283 <vscale x 1 x double> %b,284 i64 7, i64 %vsetvli)285 ret <vscale x 1 x double> %f2286}287 288@gdouble = external global double289 290define <vscale x 1 x double> @test16(i64 %avl, double %a, <vscale x 1 x double> %b) nounwind {291; CHECK-LABEL: test16:292; CHECK: # %bb.0: # %entry293; CHECK-NEXT: vsetvli a0, a0, e64, mf2, ta, ma294; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma295; CHECK-NEXT: vfmv.v.f v9, fa0296; CHECK-NEXT: vfadd.vv v8, v9, v8297; CHECK-NEXT: ret298entry:299 %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 3, i64 7)300 301 %head = insertelement <vscale x 1 x double> poison, double %a, i32 0302 %splat = shufflevector <vscale x 1 x double> %head, <vscale x 1 x double> poison, <vscale x 1 x i32> zeroinitializer303 %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(304 <vscale x 1 x double> poison,305 <vscale x 1 x double> %splat,306 <vscale x 1 x double> %b,307 i64 7, i64 %vsetvli)308 ret <vscale x 1 x double> %f2309}310 311define double @test17(i64 %avl, <vscale x 1 x double> %a, <vscale x 1 x double> %b) nounwind {312; CHECK-LABEL: test17:313; CHECK: # %bb.0: # %entry314; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma315; CHECK-NEXT: vfmv.f.s fa5, v8316; CHECK-NEXT: vfadd.vv v8, v8, v9317; CHECK-NEXT: vfmv.f.s fa4, v8318; CHECK-NEXT: fadd.d fa0, fa5, fa4319; CHECK-NEXT: ret320entry:321 %vsetvli = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)322 %c1 = extractelement <vscale x 1 x double> %a, i32 0323 %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(324 <vscale x 1 x double> poison,325 <vscale x 1 x double> %a,326 <vscale x 1 x double> %b,327 i64 7, i64 %vsetvli)328 %c2 = extractelement <vscale x 1 x double> %f2, i32 0329 %c3 = fadd double %c1, %c2330 ret double %c3331}332 333define <vscale x 1 x double> @test18(<vscale x 1 x double> %a, double %b) nounwind {334; CHECK-LABEL: test18:335; CHECK: # %bb.0: # %entry336; CHECK-NEXT: vsetivli zero, 6, e64, m1, ta, ma337; CHECK-NEXT: vfadd.vv v9, v8, v8338; CHECK-NEXT: vsetvli zero, zero, e64, m1, tu, ma339; CHECK-NEXT: vfmv.s.f v8, fa0340; CHECK-NEXT: vfmv.s.f v9, fa0341; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma342; CHECK-NEXT: vfadd.vv v8, v8, v9343; CHECK-NEXT: ret344entry:345 %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)346 %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(347 <vscale x 1 x double> %a, double %b, i64 2)348 %f2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(349 <vscale x 1 x double> poison,350 <vscale x 1 x double> %a,351 <vscale x 1 x double> %a,352 i64 7, i64 %x)353 %y2 = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(354 <vscale x 1 x double> %f2, double %b, i64 1)355 %res = fadd <vscale x 1 x double> %y, %y2356 ret <vscale x 1 x double> %res357}358 359define <vscale x 1 x double> @test19(<vscale x 1 x double> %a, double %b) nounwind {360; CHECK-LABEL: test19:361; CHECK: # %bb.0: # %entry362; CHECK-NEXT: vsetivli zero, 1, e64, m8, tu, ma363; CHECK-NEXT: vmv1r.v v9, v8364; CHECK-NEXT: vfmv.s.f v9, fa0365; CHECK-NEXT: vsetvli a0, zero, e64, m1, ta, ma366; CHECK-NEXT: vfadd.vv v8, v9, v8367; CHECK-NEXT: ret368entry:369 %x = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 3, i64 0)370 %y = call <vscale x 1 x double> @llvm.riscv.vfmv.s.f.nxv1f64(371 <vscale x 1 x double> %a, double %b, i64 2)372 %y2 = fadd <vscale x 1 x double> %y, %a373 ret <vscale x 1 x double> %y2374}375 376define i64 @avl_forward1(<vscale x 2 x i32> %v, ptr %p) nounwind {377; CHECK-LABEL: avl_forward1:378; CHECK: # %bb.0: # %entry379; CHECK-NEXT: vsetivli a1, 6, e32, m1, ta, ma380; CHECK-NEXT: vse32.v v8, (a0)381; CHECK-NEXT: mv a0, a1382; CHECK-NEXT: ret383entry:384 %vl = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 2, i64 0)385 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)386 ret i64 %vl387}388 389; Incompatible vtype390define i64 @avl_forward1b_neg(<vscale x 2 x i32> %v, ptr %p) nounwind {391; CHECK-LABEL: avl_forward1b_neg:392; CHECK: # %bb.0: # %entry393; CHECK-NEXT: vsetivli a1, 6, e16, m1, ta, ma394; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma395; CHECK-NEXT: vse32.v v8, (a0)396; CHECK-NEXT: mv a0, a1397; CHECK-NEXT: ret398entry:399 %vl = tail call i64 @llvm.riscv.vsetvli(i64 6, i64 1, i64 0)400 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)401 ret i64 %vl402}403 404define i64 @avl_forward2(<vscale x 2 x i32> %v, ptr %p) nounwind {405; CHECK-LABEL: avl_forward2:406; CHECK: # %bb.0: # %entry407; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma408; CHECK-NEXT: vse32.v v8, (a0)409; CHECK-NEXT: mv a0, a1410; CHECK-NEXT: ret411entry:412 %vl = tail call i64 @llvm.riscv.vsetvlimax(i64 2, i64 0)413 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)414 ret i64 %vl415}416 417; %vl is intentionally used only once418define void @avl_forward3(<vscale x 2 x i32> %v, ptr %p, i64 %reg) nounwind {419; CHECK-LABEL: avl_forward3:420; CHECK: # %bb.0: # %entry421; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma422; CHECK-NEXT: vse32.v v8, (a0)423; CHECK-NEXT: ret424entry:425 %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 2, i64 0)426 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)427 ret void428}429 430; %vl has multiple uses431define i64 @avl_forward3b(<vscale x 2 x i32> %v, ptr %p, i64 %reg) nounwind {432; CHECK-LABEL: avl_forward3b:433; CHECK: # %bb.0: # %entry434; CHECK-NEXT: vsetvli a1, a1, e32, m1, ta, ma435; CHECK-NEXT: vse32.v v8, (a0)436; CHECK-NEXT: mv a0, a1437; CHECK-NEXT: ret438entry:439 %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 2, i64 0)440 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)441 ret i64 %vl442}443 444; Like4, but with incompatible VTYPE445define void @avl_forward4(<vscale x 2 x i32> %v, ptr %p, i64 %reg) nounwind {446; CHECK-LABEL: avl_forward4:447; CHECK: # %bb.0: # %entry448; CHECK-NEXT: vsetvli a1, a1, e16, m1, ta, ma449; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma450; CHECK-NEXT: vse32.v v8, (a0)451; CHECK-NEXT: ret452entry:453 %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 1, i64 0)454 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)455 ret void456}457 458; Like4b, but with incompatible VTYPE459define i64 @avl_forward4b(<vscale x 2 x i32> %v, ptr %p, i64 %reg) nounwind {460; CHECK-LABEL: avl_forward4b:461; CHECK: # %bb.0: # %entry462; CHECK-NEXT: vsetvli a1, a1, e16, m1, ta, ma463; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma464; CHECK-NEXT: vse32.v v8, (a0)465; CHECK-NEXT: mv a0, a1466; CHECK-NEXT: ret467entry:468 %vl = tail call i64 @llvm.riscv.vsetvli(i64 %reg, i64 1, i64 0)469 call void @llvm.riscv.vse.nxv2i32.i64(<vscale x 2 x i32> %v, ptr %p, i64 %vl)470 ret i64 %vl471}472 473; Fault first loads can modify VL.474; TODO: The VSETVLI of vadd could be removed here.475define <vscale x 1 x i64> @vleNff(ptr %str, i64 %n, i64 %x) {476; CHECK-LABEL: vleNff:477; CHECK: # %bb.0: # %entry478; CHECK-NEXT: vsetvli a1, a1, e8, m4, ta, ma479; CHECK-NEXT: vsetvli zero, a1, e64, m1, ta, ma480; CHECK-NEXT: vle64ff.v v8, (a0)481; CHECK-NEXT: vsetvli zero, zero, e64, m1, tu, ma482; CHECK-NEXT: vadd.vx v8, v8, a2483; CHECK-NEXT: ret484entry:485 %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 0, i64 2)486 %1 = bitcast ptr %str to ptr487 %2 = tail call { <vscale x 1 x i64>, i64 } @llvm.riscv.vleff.nxv1i64.i64(<vscale x 1 x i64> poison, ptr %1, i64 %0)488 %3 = extractvalue { <vscale x 1 x i64>, i64 } %2, 0489 %4 = extractvalue { <vscale x 1 x i64>, i64 } %2, 1490 %5 = tail call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64.i64(<vscale x 1 x i64> %3, <vscale x 1 x i64> %3, i64 %x, i64 %4)491 ret <vscale x 1 x i64> %5492}493 494; Similiar test case, but use same policy for vleff and vadd.495; Note: The test may be redundant if we could fix the TODO of @vleNff.496define <vscale x 1 x i64> @vleNff2(ptr %str, i64 %n, i64 %x) {497; CHECK-LABEL: vleNff2:498; CHECK: # %bb.0: # %entry499; CHECK-NEXT: vsetvli a1, a1, e8, m4, ta, ma500; CHECK-NEXT: vsetvli zero, a1, e64, m1, ta, ma501; CHECK-NEXT: vle64ff.v v8, (a0)502; CHECK-NEXT: vadd.vx v8, v8, a2503; CHECK-NEXT: ret504entry:505 %0 = tail call i64 @llvm.riscv.vsetvli.i64(i64 %n, i64 0, i64 2)506 %1 = bitcast ptr %str to ptr507 %2 = tail call { <vscale x 1 x i64>, i64 } @llvm.riscv.vleff.nxv1i64.i64(<vscale x 1 x i64> poison, ptr %1, i64 %0)508 %3 = extractvalue { <vscale x 1 x i64>, i64 } %2, 0509 %4 = extractvalue { <vscale x 1 x i64>, i64 } %2, 1510 %5 = tail call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.i64.i64(<vscale x 1 x i64> poison, <vscale x 1 x i64> %3, i64 %x, i64 %4)511 ret <vscale x 1 x i64> %5512}513 514; Ensure AVL register is alive when forwarding an AVL immediate that does not fit in 5 bits515define <vscale x 2 x i32> @avl_forward5(ptr %addr) {516; CHECK-LABEL: avl_forward5:517; CHECK: # %bb.0:518; CHECK-NEXT: li a1, 32519; CHECK-NEXT: vsetvli a1, a1, e8, m4, ta, ma520; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma521; CHECK-NEXT: vle32.v v8, (a0)522; CHECK-NEXT: ret523 %gvl = tail call i64 @llvm.riscv.vsetvli.i64(i64 32, i64 0, i64 2)524 %ret = tail call <vscale x 2 x i32> @llvm.riscv.vle.nxv2i32.i64(<vscale x 2 x i32> poison, ptr %addr, i64 %gvl)525 ret <vscale x 2 x i32> %ret526}527 528define <vscale x 1 x double> @test20(i64 %avl, <vscale x 1 x float> %a, <vscale x 1 x float> %b, <vscale x 1 x double> %c) nounwind {529; CHECK-LABEL: test20:530; CHECK: # %bb.0: # %entry531; CHECK-NEXT: vsetvli zero, a0, e32, mf2, ta, ma532; CHECK-NEXT: vfwadd.vv v11, v8, v9533; CHECK-NEXT: vsetvli zero, zero, e64, m1, ta, ma534; CHECK-NEXT: vfadd.vv v8, v11, v10535; CHECK-NEXT: ret536entry:537 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %avl, i64 2, i64 7)538 %1 = tail call <vscale x 1 x double> @llvm.riscv.vfwadd.nxv1f64.nxv1f32.nxv1f32(539 <vscale x 1 x double> poison,540 <vscale x 1 x float> %a,541 <vscale x 1 x float> %b,542 i64 7, i64 %0)543 %2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd.nxv1f64.nxv1f64(544 <vscale x 1 x double> poison,545 <vscale x 1 x double> %1,546 <vscale x 1 x double> %c,547 i64 7, i64 %0)548 ret <vscale x 1 x double> %2549}550 551; This used to fail the machine verifier due to the vsetvli being removed552; while the add was still using it.553define i64 @bad_removal(<2 x i64> %arg) {554; CHECK-LABEL: bad_removal:555; CHECK: # %bb.0: # %bb556; CHECK-NEXT: vsetivli a0, 16, e64, m1, ta, ma557; CHECK-NEXT: vmv.x.s a1, v8558; CHECK-NEXT: add a0, a0, a1559; CHECK-NEXT: ret560bb:561 %tmp = extractelement <2 x i64> %arg, i64 0562 %tmp1 = call i64 @llvm.riscv.vsetvli.i64(i64 16, i64 3, i64 0)563 %tmp2 = add i64 %tmp, %tmp1564 ret i64 %tmp2565}566 567define void @add_v128i8(ptr %x, ptr %y) vscale_range(2,2) {568; CHECK-LABEL: add_v128i8:569; CHECK: # %bb.0:570; CHECK-NEXT: vl8r.v v8, (a0)571; CHECK-NEXT: vl8r.v v16, (a1)572; CHECK-NEXT: vsetvli a1, zero, e8, m8, ta, ma573; CHECK-NEXT: vadd.vv v8, v8, v16574; CHECK-NEXT: vs8r.v v8, (a0)575; CHECK-NEXT: ret576 %a = load <128 x i8>, ptr %x577 %b = load <128 x i8>, ptr %y578 %c = add <128 x i8> %a, %b579 store <128 x i8> %c, ptr %x580 ret void581}582 583define void @add_v16i64(ptr %x, ptr %y) vscale_range(2,2) {584; CHECK-LABEL: add_v16i64:585; CHECK: # %bb.0:586; CHECK-NEXT: vl8re64.v v8, (a0)587; CHECK-NEXT: vl8re64.v v16, (a1)588; CHECK-NEXT: vsetivli zero, 16, e64, m8, ta, ma589; CHECK-NEXT: vadd.vv v8, v8, v16590; CHECK-NEXT: vs8r.v v8, (a0)591; CHECK-NEXT: ret592 %a = load <16 x i64>, ptr %x593 %b = load <16 x i64>, ptr %y594 %c = add <16 x i64> %a, %b595 store <16 x i64> %c, ptr %x596 ret void597}598 599define <vscale x 2 x float> @fp_reduction_vfmv_s_f(float %0, <vscale x 8 x float> %1, i64 %2) {600; CHECK-LABEL: fp_reduction_vfmv_s_f:601; CHECK: # %bb.0:602; CHECK-NEXT: vsetvli zero, a0, e32, m4, ta, ma603; CHECK-NEXT: vfmv.s.f v12, fa0604; CHECK-NEXT: vfredusum.vs v8, v8, v12605; CHECK-NEXT: ret606 %4 = tail call <vscale x 8 x float> @llvm.riscv.vfmv.s.f.nxv8f32.i64(<vscale x 8 x float> poison, float %0, i64 %2)607 %5 = tail call <vscale x 2 x float> @llvm.vector.extract.nxv2f32.nxv8f32(<vscale x 8 x float> %4, i64 0)608 %6 = tail call <vscale x 2 x float> @llvm.riscv.vfredusum.nxv2f32.nxv8f32.i64(<vscale x 2 x float> poison, <vscale x 8 x float> %1, <vscale x 2 x float> %5, i64 7, i64 %2)609 ret <vscale x 2 x float> %6610}611 612define dso_local <vscale x 2 x i32> @int_reduction_vmv_s_x(i32 signext %0, <vscale x 8 x i32> %1, i64 %2) {613; CHECK-LABEL: int_reduction_vmv_s_x:614; CHECK: # %bb.0:615; CHECK-NEXT: vsetvli zero, a1, e32, m4, ta, ma616; CHECK-NEXT: vmv.s.x v12, a0617; CHECK-NEXT: vredsum.vs v8, v8, v12618; CHECK-NEXT: ret619 %4 = tail call <vscale x 8 x i32> @llvm.riscv.vmv.s.x.nxv8i32.i64(<vscale x 8 x i32> poison, i32 %0, i64 %2)620 %5 = tail call <vscale x 2 x i32> @llvm.vector.extract.nxv2i32.nxv8i32(<vscale x 8 x i32> %4, i64 0)621 %6 = tail call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv8i32.i64(<vscale x 2 x i32> poison, <vscale x 8 x i32> %1, <vscale x 2 x i32> %5, i64 %2)622 ret <vscale x 2 x i32> %6623}624 625define <vscale x 2 x i32> @avl_undef1(<vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32>) {626; CHECK-LABEL: avl_undef1:627; CHECK: # %bb.0:628; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, ma629; CHECK-NEXT: vadd.vv v8, v9, v10630; CHECK-NEXT: ret631 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(632 <vscale x 2 x i32> %0,633 <vscale x 2 x i32> %1,634 <vscale x 2 x i32> %2,635 i64 poison636 )637 ret <vscale x 2 x i32> %a638}639 640define i64 @avl_undef2() {641; CHECK-LABEL: avl_undef2:642; CHECK: # %bb.0:643; CHECK-NEXT: vsetvli a0, a0, e32, mf2, ta, ma644; CHECK-NEXT: ret645 %1 = tail call i64 @llvm.riscv.vsetvli(i64 poison, i64 2, i64 7)646 ret i64 %1647}648 649define i64 @vsetvli_vleff(ptr %s, i64 %evl) {650; CHECK-LABEL: vsetvli_vleff:651; CHECK: # %bb.0: # %entry652; CHECK-NEXT: vsetvli a3, zero, e16, m1, ta, ma653; CHECK-NEXT: vmv.v.i v8, 0654; CHECK-NEXT: .LBB37_1: # %while.body655; CHECK-NEXT: # =>This Inner Loop Header: Depth=1656; CHECK-NEXT: vsetvli zero, a1, e16, m1, tu, ma657; CHECK-NEXT: vmv1r.v v9, v8658; CHECK-NEXT: vle16ff.v v9, (a0)659; CHECK-NEXT: csrr a2, vl660; CHECK-NEXT: beqz a2, .LBB37_1661; CHECK-NEXT: # %bb.2: # %while.end662; CHECK-NEXT: li a0, 0663; CHECK-NEXT: ret664entry:665 br label %while.cond666 667while.cond:668 %new_vl.0 = phi i64 [ 0, %entry ], [ %1, %while.body ]669 %cmp = icmp eq i64 %new_vl.0, 0670 br i1 %cmp, label %while.body, label %while.end671 672while.body:673 %0 = tail call { <vscale x 4 x i16>, i64 } @llvm.riscv.vleff.nxv4i16.i64(<vscale x 4 x i16> zeroinitializer, ptr %s, i64 %evl)674 %1 = extractvalue { <vscale x 4 x i16>, i64 } %0, 1675 br label %while.cond676 677while.end:678 ret i64 0679}680 681define <vscale x 1 x i64> @vslideup_vl1(<vscale x 1 x i64> %a) nounwind {682; NODEPVL-LABEL: vslideup_vl1:683; NODEPVL: # %bb.0: # %entry684; NODEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma685; NODEPVL-NEXT: vslideup.vi v9, v8, 1686; NODEPVL-NEXT: vadd.vv v8, v9, v9687; NODEPVL-NEXT: ret688;689; DEPVL-LABEL: vslideup_vl1:690; DEPVL: # %bb.0: # %entry691; DEPVL-NEXT: vsetivli zero, 1, e64, m1, ta, ma692; DEPVL-NEXT: vslideup.vi v9, v8, 1693; DEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma694; DEPVL-NEXT: vadd.vv v8, v9, v9695; DEPVL-NEXT: ret696entry:697 %1 = tail call <vscale x 1 x i64> @llvm.riscv.vslideup(698 <vscale x 1 x i64> poison,699 <vscale x 1 x i64> %a,700 i64 1,701 i64 1,702 i64 3)703 %2 = tail call <vscale x 1 x i64> @llvm.riscv.vadd(704 <vscale x 1 x i64> poison,705 <vscale x 1 x i64> %1,706 <vscale x 1 x i64> %1,707 i64 2)708 ret <vscale x 1 x i64> %2709}710 711define <vscale x 1 x i64> @vslidedown_vl1(<vscale x 1 x i64> %a) nounwind {712; NODEPVL-LABEL: vslidedown_vl1:713; NODEPVL: # %bb.0: # %entry714; NODEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma715; NODEPVL-NEXT: vslidedown.vi v8, v8, 1716; NODEPVL-NEXT: vadd.vv v8, v8, v8717; NODEPVL-NEXT: ret718;719; DEPVL-LABEL: vslidedown_vl1:720; DEPVL: # %bb.0: # %entry721; DEPVL-NEXT: vsetivli zero, 1, e64, m1, ta, ma722; DEPVL-NEXT: vslidedown.vi v8, v8, 1723; DEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma724; DEPVL-NEXT: vadd.vv v8, v8, v8725; DEPVL-NEXT: ret726entry:727 %1 = tail call <vscale x 1 x i64> @llvm.riscv.vslidedown(728 <vscale x 1 x i64> poison,729 <vscale x 1 x i64> %a,730 i64 1,731 i64 1,732 i64 3)733 %2 = tail call <vscale x 1 x i64> @llvm.riscv.vadd(734 <vscale x 1 x i64> poison,735 <vscale x 1 x i64> %1,736 <vscale x 1 x i64> %1,737 i64 2)738 ret <vscale x 1 x i64> %2739}740 741define <vscale x 1 x i64> @vmv.v.x_vl1() nounwind {742; NODEPVL-LABEL: vmv.v.x_vl1:743; NODEPVL: # %bb.0: # %entry744; NODEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma745; NODEPVL-NEXT: vmv.v.i v8, 1746; NODEPVL-NEXT: vadd.vv v8, v8, v8747; NODEPVL-NEXT: ret748;749; DEPVL-LABEL: vmv.v.x_vl1:750; DEPVL: # %bb.0: # %entry751; DEPVL-NEXT: vsetivli zero, 1, e64, m1, ta, ma752; DEPVL-NEXT: vmv.v.i v8, 1753; DEPVL-NEXT: vsetivli zero, 2, e64, m1, ta, ma754; DEPVL-NEXT: vadd.vv v8, v8, v8755; DEPVL-NEXT: ret756entry:757 %1 = tail call <vscale x 1 x i64> @llvm.riscv.vmv.v.x(758 <vscale x 1 x i64> poison,759 i64 1,760 i64 1)761 %2 = tail call <vscale x 1 x i64> @llvm.riscv.vadd(762 <vscale x 1 x i64> poison,763 <vscale x 1 x i64> %1,764 <vscale x 1 x i64> %1,765 i64 2)766 ret <vscale x 1 x i64> %2767}768 769define <vscale x 1 x double> @vfmv.v.f_vl1(double %f) nounwind {770; CHECK-LABEL: vfmv.v.f_vl1:771; CHECK: # %bb.0: # %entry772; CHECK-NEXT: vsetivli zero, 2, e64, m1, ta, ma773; CHECK-NEXT: vfmv.s.f v8, fa0774; CHECK-NEXT: vfadd.vv v8, v8, v8775; CHECK-NEXT: ret776entry:777 %1 = tail call <vscale x 1 x double> @llvm.riscv.vfmv.v.f(778 <vscale x 1 x double> poison,779 double %f,780 i64 1)781 %2 = tail call <vscale x 1 x double> @llvm.riscv.vfadd(782 <vscale x 1 x double> poison,783 <vscale x 1 x double> %1,784 <vscale x 1 x double> %1,785 i64 7,786 i64 2)787 ret <vscale x 1 x double> %2788}789 790; The two vsetvlis will be coalesced so the add will be made dead and791; removed. Make sure we shrink the live interval of %x.792define void @non_li_addi(i64 %x, ptr %p) {793; CHECK-LABEL: non_li_addi:794; CHECK: # %bb.0: # %entry795; CHECK-NEXT: vsetivli zero, 1, e64, m1, ta, ma796; CHECK-NEXT: ret797entry:798 %add = add i64 %x, 1799 %0 = tail call i64 @llvm.riscv.vsetvli(i64 %add, i64 3, i64 0)800 %1 = call <vscale x 8 x i8> @llvm.riscv.vle(<vscale x 8 x i8> poison, ptr %p, i64 %0)801 %2 = tail call i64 @llvm.riscv.vsetvli(i64 1, i64 3, i64 0)802 %3 = tail call { <vscale x 8 x i8>, i64 } @llvm.riscv.vleff(<vscale x 8 x i8> poison, ptr %p, i64 %2)803 ret void804}805 806; This will create a live interval in such a way we can't coalesce two vsetvlis,807; see the corresponding .mir test for more details. Make sure we check for this808; and don't crash.809define void @coalesce_vl_clobber(ptr %p) {810; CHECK-LABEL: coalesce_vl_clobber:811; CHECK: # %bb.0: # %entry812; CHECK-NEXT: li a2, 0813; CHECK-NEXT: li a1, 0814; CHECK-NEXT: vsetivli zero, 0, e8, mf2, ta, ma815; CHECK-NEXT: vmclr.m v8816; CHECK-NEXT: vmv.v.i v9, 0817; CHECK-NEXT: vmv1r.v v0, v8818; CHECK-NEXT: vmerge.vim v9, v9, 1, v0819; CHECK-NEXT: .LBB43_1: # %vector.body820; CHECK-NEXT: # =>This Inner Loop Header: Depth=1821; CHECK-NEXT: vsetvli a3, a2, e8, mf8, ta, ma822; CHECK-NEXT: vmv1r.v v0, v8823; CHECK-NEXT: slli a1, a1, 32824; CHECK-NEXT: vsetivli zero, 0, e8, mf2, ta, mu825; CHECK-NEXT: vmv.v.i v10, 0826; CHECK-NEXT: srli a1, a1, 32827; CHECK-NEXT: vmerge.vim v10, v10, 1, v0828; CHECK-NEXT: vslideup.vx v10, v9, a1, v0.t829; CHECK-NEXT: vsetvli zero, zero, e8, mf2, ta, ma830; CHECK-NEXT: vmsne.vi v0, v10, 0, v0.t831; CHECK-NEXT: vsetvli zero, a3, e32, m2, ta, ma832; CHECK-NEXT: vmv.v.i v10, 0833; CHECK-NEXT: vse32.v v10, (a0), v0.t834; CHECK-NEXT: li a2, 1835; CHECK-NEXT: mv a1, a3836; CHECK-NEXT: j .LBB43_1837entry:838 br label %vector.body839 840vector.body:841 %avl = phi i64 [ 0, %entry ], [ 1, %vector.body ]842 %prev.evl = phi i32 [ 0, %entry ], [ %0, %vector.body ]843 %0 = tail call i32 @llvm.experimental.get.vector.length(i64 %avl, i32 1, i1 true)844 %1 = tail call <vscale x 4 x i1> @llvm.experimental.vp.splice(<vscale x 4 x i1> zeroinitializer, <vscale x 4 x i1> zeroinitializer, i32 0, <vscale x 4 x i1> zeroinitializer, i32 %prev.evl, i32 0)845 tail call void @llvm.vp.store(<vscale x 4 x float> zeroinitializer, ptr %p, <vscale x 4 x i1> %1, i32 %0)846 br label %vector.body847}848