1171 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=riscv64 -mattr=+v | FileCheck %s3 4; Test binary operator with vp.merge and vp.smax.5define <vscale x 2 x i32> @vpmerge_vpadd(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {6; CHECK-LABEL: vpmerge_vpadd:7; CHECK: # %bb.0:8; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu9; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t10; CHECK-NEXT: ret11 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)12 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)13 ret <vscale x 2 x i32> %b14}15 16; Test glued node of merge should not be deleted.17define <vscale x 2 x i32> @vpmerge_vpadd2(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {18; CHECK-LABEL: vpmerge_vpadd2:19; CHECK: # %bb.0:20; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma21; CHECK-NEXT: vmseq.vv v0, v9, v1022; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, mu23; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t24; CHECK-NEXT: ret25 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)26 %m = call <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, metadata !"eq", <vscale x 2 x i1> splat (i1 -1), i32 %vl)27 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)28 ret <vscale x 2 x i32> %b29}30 31; Test vp.merge has all-ones mask.32define <vscale x 2 x i32> @vpmerge_vpadd3(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {33; CHECK-LABEL: vpmerge_vpadd3:34; CHECK: # %bb.0:35; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma36; CHECK-NEXT: vadd.vv v8, v9, v1037; CHECK-NEXT: ret38 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)39 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> splat (i1 -1), <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)40 ret <vscale x 2 x i32> %b41}42 43; Test float binary operator with vp.merge and vp.fadd.44define <vscale x 2 x float> @vpmerge_vpfadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {45; CHECK-LABEL: vpmerge_vpfadd:46; CHECK: # %bb.0:47; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu48; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t49; CHECK-NEXT: ret50 %a = call <vscale x 2 x float> @llvm.vp.fadd.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)51 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)52 ret <vscale x 2 x float> %b53}54 55; Test for binary operator with specific EEW by riscv.vrgatherei16.56define <vscale x 2 x i32> @vpmerge_vrgatherei16(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i16> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {57; CHECK-LABEL: vpmerge_vrgatherei16:58; CHECK: # %bb.0:59; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma60; CHECK-NEXT: vrgatherei16.vv v8, v9, v1061; CHECK-NEXT: ret62 %1 = zext i32 %vl to i6463 %2 = tail call <vscale x 2 x i32> @llvm.riscv.vrgatherei16.vv.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i16> %y, i64 %1)64 %3 = tail call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %2, <vscale x 2 x i32> %passthru, i32 %vl)65 ret <vscale x 2 x i32> %266}67 68; Test conversion by fptosi.69define <vscale x 2 x i16> @vpmerge_vpfptosi(<vscale x 2 x i16> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {70; CHECK-LABEL: vpmerge_vpfptosi:71; CHECK: # %bb.0:72; CHECK-NEXT: vsetvli zero, a0, e16, mf2, tu, mu73; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t74; CHECK-NEXT: ret75 %a = call <vscale x 2 x i16> @llvm.vp.fptosi.nxv2i16.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)76 %b = call <vscale x 2 x i16> @llvm.vp.merge.nxv2i16(<vscale x 2 x i1> %m, <vscale x 2 x i16> %a, <vscale x 2 x i16> %passthru, i32 %vl)77 ret <vscale x 2 x i16> %b78}79 80; Test conversion by sitofp.81define <vscale x 2 x float> @vpmerge_vpsitofp(<vscale x 2 x float> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {82; CHECK-LABEL: vpmerge_vpsitofp:83; CHECK: # %bb.0:84; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu85; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t86; CHECK-NEXT: ret87 %a = call <vscale x 2 x float> @llvm.vp.sitofp.nxv2f32.nxv2i64(<vscale x 2 x i64> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)88 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)89 ret <vscale x 2 x float> %b90}91 92; Test integer extension by vp.zext.93define <vscale x 2 x i32> @vpmerge_vpzext(<vscale x 2 x i32> %passthru, <vscale x 2 x i8> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {94; CHECK-LABEL: vpmerge_vpzext:95; CHECK: # %bb.0:96; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu97; CHECK-NEXT: vzext.vf4 v8, v9, v0.t98; CHECK-NEXT: ret99 %a = call <vscale x 2 x i32> @llvm.vp.zext.nxv2i32.nxv2i8(<vscale x 2 x i8> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)100 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)101 ret <vscale x 2 x i32> %b102}103 104; Test integer truncation by vp.trunc.105define <vscale x 2 x i32> @vpmerge_vptrunc(<vscale x 2 x i32> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {106; CHECK-LABEL: vpmerge_vptrunc:107; CHECK: # %bb.0:108; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu109; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t110; CHECK-NEXT: ret111 %a = call <vscale x 2 x i32> @llvm.vp.trunc.nxv2i32.nxv2i64(<vscale x 2 x i64> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)112 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)113 ret <vscale x 2 x i32> %b114}115 116; Test integer extension by vp.fpext.117define <vscale x 2 x double> @vpmerge_vpfpext(<vscale x 2 x double> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {118; CHECK-LABEL: vpmerge_vpfpext:119; CHECK: # %bb.0:120; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu121; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t122; CHECK-NEXT: ret123 %a = call <vscale x 2 x double> @llvm.vp.fpext.nxv2f64.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)124 %b = call <vscale x 2 x double> @llvm.vp.merge.nxv2f64(<vscale x 2 x i1> %m, <vscale x 2 x double> %a, <vscale x 2 x double> %passthru, i32 %vl)125 ret <vscale x 2 x double> %b126}127 128; Test integer truncation by vp.trunc.129define <vscale x 2 x float> @vpmerge_vpfptrunc(<vscale x 2 x float> %passthru, <vscale x 2 x double> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {130; CHECK-LABEL: vpmerge_vpfptrunc:131; CHECK: # %bb.0:132; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu133; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t134; CHECK-NEXT: ret135 %a = call <vscale x 2 x float> @llvm.vp.fptrunc.nxv2f32.nxv2f64(<vscale x 2 x double> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)136 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)137 ret <vscale x 2 x float> %b138}139 140; Test load operation by vp.load.141define <vscale x 2 x i32> @vpmerge_vpload(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {142; CHECK-LABEL: vpmerge_vpload:143; CHECK: # %bb.0:144; CHECK-NEXT: vsetvli zero, a1, e32, m1, tu, mu145; CHECK-NEXT: vle32.v v8, (a0), v0.t146; CHECK-NEXT: ret147 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)148 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)149 ret <vscale x 2 x i32> %b150}151 152; Test result has chain and glued node.153define <vscale x 2 x i32> @vpmerge_vpload2(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {154; CHECK-LABEL: vpmerge_vpload2:155; CHECK: # %bb.0:156; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma157; CHECK-NEXT: vmseq.vv v0, v9, v10158; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, mu159; CHECK-NEXT: vle32.v v8, (a0), v0.t160; CHECK-NEXT: ret161 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)162 %m = call <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, metadata !"eq", <vscale x 2 x i1> splat (i1 -1), i32 %vl)163 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)164 ret <vscale x 2 x i32> %b165}166 167; Test result has chain output of true operand of merge.vvm.168define void @vpmerge_vpload_store(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {169; CHECK-LABEL: vpmerge_vpload_store:170; CHECK: # %bb.0:171; CHECK-NEXT: vsetvli zero, a1, e32, m1, tu, mu172; CHECK-NEXT: vle32.v v8, (a0), v0.t173; CHECK-NEXT: vs1r.v v8, (a0)174; CHECK-NEXT: ret175 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)176 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)177 store <vscale x 2 x i32> %b, ptr %p178 ret void179}180 181define <vscale x 2 x i32> @vpmerge_vleff(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {182; CHECK-LABEL: vpmerge_vleff:183; CHECK: # %bb.0:184; CHECK-NEXT: vsetvli zero, a1, e32, m1, tu, mu185; CHECK-NEXT: vle32ff.v v8, (a0), v0.t186; CHECK-NEXT: ret187 %1 = zext i32 %vl to i64188 %a = call { <vscale x 2 x i32>, i64 } @llvm.riscv.vleff.nxv2i32(<vscale x 2 x i32> poison, ptr %p, i64 %1)189 %b = extractvalue { <vscale x 2 x i32>, i64 } %a, 0190 %c = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %b, <vscale x 2 x i32> %passthru, i32 %vl)191 ret <vscale x 2 x i32> %c192}193 194; Test strided load by riscv.vlse195define <vscale x 2 x i32> @vpmerge_vlse(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i64 %s, i32 zeroext %vl) {196; CHECK-LABEL: vpmerge_vlse:197; CHECK: # %bb.0:198; CHECK-NEXT: vsetvli zero, a2, e32, m1, tu, mu199; CHECK-NEXT: vlse32.v v8, (a0), a1, v0.t200; CHECK-NEXT: ret201 %1 = zext i32 %vl to i64202 %a = call <vscale x 2 x i32> @llvm.riscv.vlse.nxv2i32(<vscale x 2 x i32> poison, ptr %p, i64 %s, i64 %1)203 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)204 ret <vscale x 2 x i32> %b205}206 207; Test indexed load by riscv.vluxei208define <vscale x 2 x i32> @vpmerge_vluxei(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i64> %idx, <vscale x 2 x i1> %m, i64 %s, i32 zeroext %vl) {209; CHECK-LABEL: vpmerge_vluxei:210; CHECK: # %bb.0:211; CHECK-NEXT: vsetvli zero, a2, e32, m1, tu, mu212; CHECK-NEXT: vluxei64.v v8, (a0), v10, v0.t213; CHECK-NEXT: ret214 %1 = zext i32 %vl to i64215 %a = call <vscale x 2 x i32> @llvm.riscv.vluxei.nxv2i32.nxv2i64(<vscale x 2 x i32> poison, ptr %p, <vscale x 2 x i64> %idx, i64 %1)216 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)217 ret <vscale x 2 x i32> %b218}219 220; Test vector index by riscv.vid221define <vscale x 2 x i32> @vpmerge_vid(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, i32 zeroext %vl) {222; CHECK-LABEL: vpmerge_vid:223; CHECK: # %bb.0:224; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu225; CHECK-NEXT: vid.v v8, v0.t226; CHECK-NEXT: ret227 %1 = zext i32 %vl to i64228 %a = call <vscale x 2 x i32> @llvm.riscv.vid.nxv2i32(<vscale x 2 x i32> poison, i64 %1)229 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)230 ret <vscale x 2 x i32> %b231}232 233; Test not combine VIOTA_M and VMERGE_VVM without true mask.234define <vscale x 2 x i32> @vpmerge_viota(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, <vscale x 2 x i1> %vm, i32 zeroext %vl) {235; CHECK-LABEL: vpmerge_viota:236; CHECK: # %bb.0:237; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma238; CHECK-NEXT: viota.m v10, v9239; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, ma240; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0241; CHECK-NEXT: ret242 %1 = zext i32 %vl to i64243 %a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i1> %vm, i64 %1)244 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)245 ret <vscale x 2 x i32> %b246}247 248; Test combine VIOTA_M and VMERGE_VVM with true mask.249define <vscale x 2 x i32> @vpmerge_viota2(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %vm, i32 zeroext %vl) {250; CHECK-LABEL: vpmerge_viota2:251; CHECK: # %bb.0:252; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma253; CHECK-NEXT: viota.m v8, v0254; CHECK-NEXT: ret255 %1 = zext i32 %vl to i64256 %a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i1> %vm, i64 %1)257 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> splat (i1 -1), <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)258 ret <vscale x 2 x i32> %b259}260 261; Test riscv.vfclass262define <vscale x 2 x i32> @vpmerge_vflcass(<vscale x 2 x i32> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {263; CHECK-LABEL: vpmerge_vflcass:264; CHECK: # %bb.0:265; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu266; CHECK-NEXT: vfclass.v v8, v9, v0.t267; CHECK-NEXT: ret268 %1 = zext i32 %vl to i64269 %a = call <vscale x 2 x i32> @llvm.riscv.vfclass.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x float> %vf, i64 %1)270 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)271 ret <vscale x 2 x i32> %b272}273 274; Test riscv.vfsqrt275define <vscale x 2 x float> @vpmerge_vfsqrt(<vscale x 2 x float> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {276; CHECK-LABEL: vpmerge_vfsqrt:277; CHECK: # %bb.0:278; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu279; CHECK-NEXT: vfsqrt.v v8, v9, v0.t280; CHECK-NEXT: ret281 %1 = zext i32 %vl to i64282 %a = call <vscale x 2 x float> @llvm.riscv.vfsqrt.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %vf, i64 7, i64 %1)283 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)284 ret <vscale x 2 x float> %b285}286 287; Test reciprocal operation by riscv.vfrec7288define <vscale x 2 x float> @vpmerge_vfrec7(<vscale x 2 x float> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {289; CHECK-LABEL: vpmerge_vfrec7:290; CHECK: # %bb.0:291; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu292; CHECK-NEXT: vfrec7.v v8, v9, v0.t293; CHECK-NEXT: ret294 %1 = zext i32 %vl to i64295 %a = call <vscale x 2 x float> @llvm.riscv.vfrec7.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %vf, i64 7, i64 %1)296 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)297 ret <vscale x 2 x float> %b298}299 300; Test vector operations with VLMAX vector length.301 302; Test binary operator with vp.merge and add.303define <vscale x 2 x i32> @vpmerge_add(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {304; CHECK-LABEL: vpmerge_add:305; CHECK: # %bb.0:306; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu307; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t308; CHECK-NEXT: ret309 %a = add <vscale x 2 x i32> %x, %y310 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)311 ret <vscale x 2 x i32> %b312}313 314; Test binary operator with vp.merge and fadd.315define <vscale x 2 x float> @vpmerge_fadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {316; CHECK-LABEL: vpmerge_fadd:317; CHECK: # %bb.0:318; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu319; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t320; CHECK-NEXT: ret321 %a = fadd <vscale x 2 x float> %x, %y322 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)323 ret <vscale x 2 x float> %b324}325 326; This shouldn't be folded because we need to preserve exceptions with327; "fpexcept.strict" exception behaviour, and masking may hide them.328define <vscale x 2 x float> @vpmerge_constrained_fadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i64 %vl) strictfp {329; CHECK-LABEL: vpmerge_constrained_fadd:330; CHECK: # %bb.0:331; CHECK-NEXT: vsetvli a1, zero, e32, m1, ta, ma332; CHECK-NEXT: vfadd.vv v9, v9, v10333; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma334; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0335; CHECK-NEXT: ret336 %a = call <vscale x 2 x float> @llvm.experimental.constrained.fadd.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x float> %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp337 %b = call <vscale x 2 x float> @llvm.riscv.vmerge.nxv2f32.nxv2f32(<vscale x 2 x float> %passthru, <vscale x 2 x float> %passthru, <vscale x 2 x float> %a, <vscale x 2 x i1> %m, i64 %vl) strictfp338 ret <vscale x 2 x float> %b339}340 341; This shouldn't be folded because we need to preserve exceptions with342; "fpexcept.strict" exception behaviour, and masking may hide them.343define <vscale x 2 x float> @vpmerge_constrained_fadd_vlmax(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m) strictfp {344; CHECK-LABEL: vpmerge_constrained_fadd_vlmax:345; CHECK: # %bb.0:346; CHECK-NEXT: vsetvli a0, zero, e32, m1, ta, ma347; CHECK-NEXT: vfadd.vv v9, v9, v10348; CHECK-NEXT: vsetvli zero, zero, e32, m1, tu, ma349; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0350; CHECK-NEXT: ret351 %a = call <vscale x 2 x float> @llvm.experimental.constrained.fadd.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x float> %y, metadata !"round.dynamic", metadata !"fpexcept.strict") strictfp352 %b = call <vscale x 2 x float> @llvm.riscv.vmerge.nxv2f32.nxv2f32(<vscale x 2 x float> %passthru, <vscale x 2 x float> %passthru, <vscale x 2 x float> %a, <vscale x 2 x i1> %m, i64 -1) strictfp353 ret <vscale x 2 x float> %b354}355 356; Test conversion by fptosi.357define <vscale x 2 x i16> @vpmerge_fptosi(<vscale x 2 x i16> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {358; CHECK-LABEL: vpmerge_fptosi:359; CHECK: # %bb.0:360; CHECK-NEXT: vsetvli zero, a0, e16, mf2, tu, mu361; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t362; CHECK-NEXT: ret363 %a = fptosi <vscale x 2 x float> %x to <vscale x 2 x i16>364 %b = call <vscale x 2 x i16> @llvm.vp.merge.nxv2i16(<vscale x 2 x i1> %m, <vscale x 2 x i16> %a, <vscale x 2 x i16> %passthru, i32 %vl)365 ret <vscale x 2 x i16> %b366}367 368; Test conversion by sitofp.369define <vscale x 2 x float> @vpmerge_sitofp(<vscale x 2 x float> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {370; CHECK-LABEL: vpmerge_sitofp:371; CHECK: # %bb.0:372; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu373; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t374; CHECK-NEXT: ret375 %a = sitofp <vscale x 2 x i64> %x to <vscale x 2 x float>376 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)377 ret <vscale x 2 x float> %b378}379 380; Test float extension by fpext.381define <vscale x 2 x double> @vpmerge_fpext(<vscale x 2 x double> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {382; CHECK-LABEL: vpmerge_fpext:383; CHECK: # %bb.0:384; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu385; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t386; CHECK-NEXT: ret387 %a = fpext <vscale x 2 x float> %x to <vscale x 2 x double>388 %b = call <vscale x 2 x double> @llvm.vp.merge.nxv2f64(<vscale x 2 x i1> %m, <vscale x 2 x double> %a, <vscale x 2 x double> %passthru, i32 %vl)389 ret <vscale x 2 x double> %b390}391 392; Test float truncation by fptrunc.393define <vscale x 2 x float> @vpmerge_fptrunc(<vscale x 2 x float> %passthru, <vscale x 2 x double> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {394; CHECK-LABEL: vpmerge_fptrunc:395; CHECK: # %bb.0:396; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu397; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t398; CHECK-NEXT: ret399 %a = fptrunc <vscale x 2 x double> %x to <vscale x 2 x float>400 %b = call <vscale x 2 x float> @llvm.vp.merge.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)401 ret <vscale x 2 x float> %b402}403 404; Test integer extension by zext.405define <vscale x 2 x i32> @vpmerge_zext(<vscale x 2 x i32> %passthru, <vscale x 2 x i8> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {406; CHECK-LABEL: vpmerge_zext:407; CHECK: # %bb.0:408; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu409; CHECK-NEXT: vzext.vf4 v8, v9, v0.t410; CHECK-NEXT: ret411 %a = zext <vscale x 2 x i8> %x to <vscale x 2 x i32>412 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)413 ret <vscale x 2 x i32> %b414}415 416; Test integer truncation by trunc.417define <vscale x 2 x i32> @vpmerge_trunc(<vscale x 2 x i32> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {418; CHECK-LABEL: vpmerge_trunc:419; CHECK: # %bb.0:420; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu421; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t422; CHECK-NEXT: ret423 %a = trunc <vscale x 2 x i64> %x to <vscale x 2 x i32>424 %b = call <vscale x 2 x i32> @llvm.vp.merge.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)425 ret <vscale x 2 x i32> %b426}427 428; Test binary operator with vp.select and vp.smax.429define <vscale x 2 x i32> @vpselect_vpadd(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {430; CHECK-LABEL: vpselect_vpadd:431; CHECK: # %bb.0:432; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu433; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t434; CHECK-NEXT: ret435 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)436 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)437 ret <vscale x 2 x i32> %b438}439 440; Test glued node of select should not be deleted.441define <vscale x 2 x i32> @vpselect_vpadd2(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {442; CHECK-LABEL: vpselect_vpadd2:443; CHECK: # %bb.0:444; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu445; CHECK-NEXT: vmseq.vv v0, v9, v10446; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t447; CHECK-NEXT: ret448 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)449 %m = call <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, metadata !"eq", <vscale x 2 x i1> splat (i1 -1), i32 %vl)450 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)451 ret <vscale x 2 x i32> %b452}453 454; Test vp.select has all-ones mask.455define <vscale x 2 x i32> @vpselect_vpadd3(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {456; CHECK-LABEL: vpselect_vpadd3:457; CHECK: # %bb.0:458; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma459; CHECK-NEXT: vadd.vv v8, v9, v10460; CHECK-NEXT: ret461 %a = call <vscale x 2 x i32> @llvm.vp.add.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)462 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> splat (i1 -1), <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)463 ret <vscale x 2 x i32> %b464}465 466; Test float binary operator with vp.select and vp.fadd.467define <vscale x 2 x float> @vpselect_vpfadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {468; CHECK-LABEL: vpselect_vpfadd:469; CHECK: # %bb.0:470; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu471; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t472; CHECK-NEXT: ret473 %a = call <vscale x 2 x float> @llvm.vp.fadd.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> splat (i1 -1), i32 %vl)474 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)475 ret <vscale x 2 x float> %b476}477 478; Test for binary operator with specific EEW by riscv.vrgatherei16.479define <vscale x 2 x i32> @vpselect_vrgatherei16(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i16> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {480; CHECK-LABEL: vpselect_vrgatherei16:481; CHECK: # %bb.0:482; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma483; CHECK-NEXT: vrgatherei16.vv v8, v9, v10484; CHECK-NEXT: ret485 %1 = zext i32 %vl to i64486 %2 = tail call <vscale x 2 x i32> @llvm.riscv.vrgatherei16.vv.nxv2i32.i64(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i16> %y, i64 %1)487 %3 = tail call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %2, <vscale x 2 x i32> %passthru, i32 %vl)488 ret <vscale x 2 x i32> %2489}490 491; Test conversion by fptosi.492define <vscale x 2 x i16> @vpselect_vpfptosi(<vscale x 2 x i16> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {493; CHECK-LABEL: vpselect_vpfptosi:494; CHECK: # %bb.0:495; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, mu496; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t497; CHECK-NEXT: ret498 %a = call <vscale x 2 x i16> @llvm.vp.fptosi.nxv2i16.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)499 %b = call <vscale x 2 x i16> @llvm.vp.select.nxv2i16(<vscale x 2 x i1> %m, <vscale x 2 x i16> %a, <vscale x 2 x i16> %passthru, i32 %vl)500 ret <vscale x 2 x i16> %b501}502 503; Test conversion by sitofp.504define <vscale x 2 x float> @vpselect_vpsitofp(<vscale x 2 x float> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {505; CHECK-LABEL: vpselect_vpsitofp:506; CHECK: # %bb.0:507; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu508; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t509; CHECK-NEXT: ret510 %a = call <vscale x 2 x float> @llvm.vp.sitofp.nxv2f32.nxv2i64(<vscale x 2 x i64> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)511 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)512 ret <vscale x 2 x float> %b513}514 515; Test integer extension by vp.zext.516define <vscale x 2 x i32> @vpselect_vpzext(<vscale x 2 x i32> %passthru, <vscale x 2 x i8> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {517; CHECK-LABEL: vpselect_vpzext:518; CHECK: # %bb.0:519; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu520; CHECK-NEXT: vzext.vf4 v8, v9, v0.t521; CHECK-NEXT: ret522 %a = call <vscale x 2 x i32> @llvm.vp.zext.nxv2i32.nxv2i8(<vscale x 2 x i8> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)523 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)524 ret <vscale x 2 x i32> %b525}526 527; Test integer truncation by vp.trunc.528define <vscale x 2 x i32> @vpselect_vptrunc(<vscale x 2 x i32> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {529; CHECK-LABEL: vpselect_vptrunc:530; CHECK: # %bb.0:531; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu532; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t533; CHECK-NEXT: ret534 %a = call <vscale x 2 x i32> @llvm.vp.trunc.nxv2i32.nxv2i64(<vscale x 2 x i64> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)535 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)536 ret <vscale x 2 x i32> %b537}538 539; Test integer extension by vp.fpext.540define <vscale x 2 x double> @vpselect_vpfpext(<vscale x 2 x double> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {541; CHECK-LABEL: vpselect_vpfpext:542; CHECK: # %bb.0:543; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu544; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t545; CHECK-NEXT: ret546 %a = call <vscale x 2 x double> @llvm.vp.fpext.nxv2f64.nxv2f32(<vscale x 2 x float> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)547 %b = call <vscale x 2 x double> @llvm.vp.select.nxv2f64(<vscale x 2 x i1> %m, <vscale x 2 x double> %a, <vscale x 2 x double> %passthru, i32 %vl)548 ret <vscale x 2 x double> %b549}550 551; Test integer truncation by vp.trunc.552define <vscale x 2 x float> @vpselect_vpfptrunc(<vscale x 2 x float> %passthru, <vscale x 2 x double> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {553; CHECK-LABEL: vpselect_vpfptrunc:554; CHECK: # %bb.0:555; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu556; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t557; CHECK-NEXT: ret558 %a = call <vscale x 2 x float> @llvm.vp.fptrunc.nxv2f32.nxv2f64(<vscale x 2 x double> %x, <vscale x 2 x i1> splat (i1 -1), i32 %vl)559 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)560 ret <vscale x 2 x float> %b561}562 563; Test load operation by vp.load.564define <vscale x 2 x i32> @vpselect_vpload(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {565; CHECK-LABEL: vpselect_vpload:566; CHECK: # %bb.0:567; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu568; CHECK-NEXT: vle32.v v8, (a0), v0.t569; CHECK-NEXT: ret570 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)571 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)572 ret <vscale x 2 x i32> %b573}574 575; Test result has chain and glued node.576define <vscale x 2 x i32> @vpselect_vpload2(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i32 zeroext %vl) {577; CHECK-LABEL: vpselect_vpload2:578; CHECK: # %bb.0:579; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu580; CHECK-NEXT: vmseq.vv v0, v9, v10581; CHECK-NEXT: vle32.v v8, (a0), v0.t582; CHECK-NEXT: ret583 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)584 %m = call <vscale x 2 x i1> @llvm.vp.icmp.nxv2i32(<vscale x 2 x i32> %x, <vscale x 2 x i32> %y, metadata !"eq", <vscale x 2 x i1> splat (i1 -1), i32 %vl)585 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)586 ret <vscale x 2 x i32> %b587}588 589; Test result has chain output of true operand of select.vvm.590define void @vpselect_vpload_store(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {591; CHECK-LABEL: vpselect_vpload_store:592; CHECK: # %bb.0:593; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu594; CHECK-NEXT: vle32.v v8, (a0), v0.t595; CHECK-NEXT: vs1r.v v8, (a0)596; CHECK-NEXT: ret597 %a = call <vscale x 2 x i32> @llvm.vp.load.nxv2i32.p0(ptr %p, <vscale x 2 x i1> splat (i1 -1), i32 %vl)598 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)599 store <vscale x 2 x i32> %b, ptr %p600 ret void601}602 603define <vscale x 2 x i32> @vpselect_vleff(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i32 zeroext %vl) {604; CHECK-LABEL: vpselect_vleff:605; CHECK: # %bb.0:606; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu607; CHECK-NEXT: vle32ff.v v8, (a0), v0.t608; CHECK-NEXT: ret609 %1 = zext i32 %vl to i64610 %a = call { <vscale x 2 x i32>, i64 } @llvm.riscv.vleff.nxv2i32(<vscale x 2 x i32> poison, ptr %p, i64 %1)611 %b = extractvalue { <vscale x 2 x i32>, i64 } %a, 0612 %c = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %b, <vscale x 2 x i32> %passthru, i32 %vl)613 ret <vscale x 2 x i32> %c614}615 616; Test strided load by riscv.vlse617define <vscale x 2 x i32> @vpselect_vlse(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i1> %m, i64 %s, i32 zeroext %vl) {618; CHECK-LABEL: vpselect_vlse:619; CHECK: # %bb.0:620; CHECK-NEXT: vsetvli zero, a2, e32, m1, ta, mu621; CHECK-NEXT: vlse32.v v8, (a0), a1, v0.t622; CHECK-NEXT: ret623 %1 = zext i32 %vl to i64624 %a = call <vscale x 2 x i32> @llvm.riscv.vlse.nxv2i32(<vscale x 2 x i32> poison, ptr %p, i64 %s, i64 %1)625 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)626 ret <vscale x 2 x i32> %b627}628 629; Test indexed load by riscv.vluxei630define <vscale x 2 x i32> @vpselect_vluxei(<vscale x 2 x i32> %passthru, ptr %p, <vscale x 2 x i64> %idx, <vscale x 2 x i1> %m, i64 %s, i32 zeroext %vl) {631; CHECK-LABEL: vpselect_vluxei:632; CHECK: # %bb.0:633; CHECK-NEXT: vsetvli zero, a2, e32, m1, ta, mu634; CHECK-NEXT: vluxei64.v v8, (a0), v10, v0.t635; CHECK-NEXT: ret636 %1 = zext i32 %vl to i64637 %a = call <vscale x 2 x i32> @llvm.riscv.vluxei.nxv2i32.nxv2i64(<vscale x 2 x i32> poison, ptr %p, <vscale x 2 x i64> %idx, i64 %1)638 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)639 ret <vscale x 2 x i32> %b640}641 642; Test vector index by riscv.vid643define <vscale x 2 x i32> @vpselect_vid(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, i32 zeroext %vl) {644; CHECK-LABEL: vpselect_vid:645; CHECK: # %bb.0:646; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu647; CHECK-NEXT: vid.v v8, v0.t648; CHECK-NEXT: ret649 %1 = zext i32 %vl to i64650 %a = call <vscale x 2 x i32> @llvm.riscv.vid.nxv2i32(<vscale x 2 x i32> poison, i64 %1)651 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)652 ret <vscale x 2 x i32> %b653}654 655; Test riscv.viota656define <vscale x 2 x i32> @vpselect_viota(<vscale x 2 x i32> %passthru, <vscale x 2 x i1> %m, <vscale x 2 x i1> %vm, i32 zeroext %vl) {657; CHECK-LABEL: vpselect_viota:658; CHECK: # %bb.0:659; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, ma660; CHECK-NEXT: viota.m v10, v9661; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0662; CHECK-NEXT: ret663 %1 = zext i32 %vl to i64664 %a = call <vscale x 2 x i32> @llvm.riscv.viota.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i1> %vm, i64 %1)665 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)666 ret <vscale x 2 x i32> %b667}668 669; Test riscv.vfclass670define <vscale x 2 x i32> @vpselect_vflcass(<vscale x 2 x i32> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {671; CHECK-LABEL: vpselect_vflcass:672; CHECK: # %bb.0:673; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu674; CHECK-NEXT: vfclass.v v8, v9, v0.t675; CHECK-NEXT: ret676 %1 = zext i32 %vl to i64677 %a = call <vscale x 2 x i32> @llvm.riscv.vfclass.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x float> %vf, i64 %1)678 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)679 ret <vscale x 2 x i32> %b680}681 682; Test riscv.vfsqrt683define <vscale x 2 x float> @vpselect_vfsqrt(<vscale x 2 x float> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {684; CHECK-LABEL: vpselect_vfsqrt:685; CHECK: # %bb.0:686; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu687; CHECK-NEXT: vfsqrt.v v8, v9, v0.t688; CHECK-NEXT: ret689 %1 = zext i32 %vl to i64690 %a = call <vscale x 2 x float> @llvm.riscv.vfsqrt.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %vf, i64 7, i64 %1)691 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)692 ret <vscale x 2 x float> %b693}694 695; Test reciprocal operation by riscv.vfrec7696define <vscale x 2 x float> @vpselect_vfrec7(<vscale x 2 x float> %passthru, <vscale x 2 x float> %vf, <vscale x 2 x i1> %m, i32 zeroext %vl) {697; CHECK-LABEL: vpselect_vfrec7:698; CHECK: # %bb.0:699; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu700; CHECK-NEXT: vfrec7.v v8, v9, v0.t701; CHECK-NEXT: ret702 %1 = zext i32 %vl to i64703 %a = call <vscale x 2 x float> @llvm.riscv.vfrec7.nxv2f32(<vscale x 2 x float> poison, <vscale x 2 x float> %vf, i64 7, i64 %1)704 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)705 ret <vscale x 2 x float> %b706}707 708; Test slides709define <vscale x 2 x i32> @vpselect_vslideup(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %v, i64 %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {710; CHECK-LABEL: vpselect_vslideup:711; CHECK: # %bb.0:712; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu713; CHECK-NEXT: vslideup.vx v8, v9, a0, v0.t714; CHECK-NEXT: ret715 %1 = zext i32 %vl to i64716 %a = call <vscale x 2 x i32> @llvm.riscv.vslideup.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %v, i64 %x, i64 %1, i64 0)717 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)718 ret <vscale x 2 x i32> %b719}720 721define <vscale x 2 x i32> @vpselect_vslidedown(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %v, i64 %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {722; CHECK-LABEL: vpselect_vslidedown:723; CHECK: # %bb.0:724; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu725; CHECK-NEXT: vslidedown.vx v8, v9, a0, v0.t726; CHECK-NEXT: ret727 %1 = zext i32 %vl to i64728 %a = call <vscale x 2 x i32> @llvm.riscv.vslidedown.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %v, i64 %x, i64 %1, i64 0)729 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)730 ret <vscale x 2 x i32> %b731}732 733define <vscale x 2 x i32> @vpselect_vslide1up(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %v, i32 %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {734; CHECK-LABEL: vpselect_vslide1up:735; CHECK: # %bb.0:736; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu737; CHECK-NEXT: vslide1up.vx v8, v9, a0, v0.t738; CHECK-NEXT: ret739 %1 = zext i32 %vl to i64740 %a = call <vscale x 2 x i32> @llvm.riscv.vslide1up.nxv2i32.i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %v, i32 %x, i64 %1)741 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)742 ret <vscale x 2 x i32> %b743}744 745define <vscale x 2 x i32> @vpselect_vslide1down(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %v, i32 %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {746; CHECK-LABEL: vpselect_vslide1down:747; CHECK: # %bb.0:748; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu749; CHECK-NEXT: vslide1down.vx v8, v9, a0, v0.t750; CHECK-NEXT: ret751 %1 = zext i32 %vl to i64752 %a = call <vscale x 2 x i32> @llvm.riscv.vslide1down.nxv2i32.i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %v, i32 %x, i64 %1)753 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)754 ret <vscale x 2 x i32> %b755}756 757; Test vector operations with VLMAX vector length.758 759; Test binary operator with vp.select and add.760define <vscale x 2 x i32> @vpselect_add(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {761; CHECK-LABEL: vpselect_add:762; CHECK: # %bb.0:763; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu764; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t765; CHECK-NEXT: ret766 %a = add <vscale x 2 x i32> %x, %y767 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)768 ret <vscale x 2 x i32> %b769}770 771; Test binary operator with vp.select and fadd.772define <vscale x 2 x float> @vpselect_fadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i32 zeroext %vl) {773; CHECK-LABEL: vpselect_fadd:774; CHECK: # %bb.0:775; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu776; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t777; CHECK-NEXT: ret778 %a = fadd <vscale x 2 x float> %x, %y779 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)780 ret <vscale x 2 x float> %b781}782 783; Test conversion by fptosi.784define <vscale x 2 x i16> @vpselect_fptosi(<vscale x 2 x i16> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {785; CHECK-LABEL: vpselect_fptosi:786; CHECK: # %bb.0:787; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, mu788; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t789; CHECK-NEXT: ret790 %a = fptosi <vscale x 2 x float> %x to <vscale x 2 x i16>791 %b = call <vscale x 2 x i16> @llvm.vp.select.nxv2i16(<vscale x 2 x i1> %m, <vscale x 2 x i16> %a, <vscale x 2 x i16> %passthru, i32 %vl)792 ret <vscale x 2 x i16> %b793}794 795; Test conversion by sitofp.796define <vscale x 2 x float> @vpselect_sitofp(<vscale x 2 x float> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {797; CHECK-LABEL: vpselect_sitofp:798; CHECK: # %bb.0:799; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu800; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t801; CHECK-NEXT: ret802 %a = sitofp <vscale x 2 x i64> %x to <vscale x 2 x float>803 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)804 ret <vscale x 2 x float> %b805}806 807; Test float extension by fpext.808define <vscale x 2 x double> @vpselect_fpext(<vscale x 2 x double> %passthru, <vscale x 2 x float> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {809; CHECK-LABEL: vpselect_fpext:810; CHECK: # %bb.0:811; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu812; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t813; CHECK-NEXT: ret814 %a = fpext <vscale x 2 x float> %x to <vscale x 2 x double>815 %b = call <vscale x 2 x double> @llvm.vp.select.nxv2f64(<vscale x 2 x i1> %m, <vscale x 2 x double> %a, <vscale x 2 x double> %passthru, i32 %vl)816 ret <vscale x 2 x double> %b817}818 819; Test float truncation by fptrunc.820define <vscale x 2 x float> @vpselect_fptrunc(<vscale x 2 x float> %passthru, <vscale x 2 x double> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {821; CHECK-LABEL: vpselect_fptrunc:822; CHECK: # %bb.0:823; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu824; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t825; CHECK-NEXT: ret826 %a = fptrunc <vscale x 2 x double> %x to <vscale x 2 x float>827 %b = call <vscale x 2 x float> @llvm.vp.select.nxv2f32(<vscale x 2 x i1> %m, <vscale x 2 x float> %a, <vscale x 2 x float> %passthru, i32 %vl)828 ret <vscale x 2 x float> %b829}830 831; Test integer extension by zext.832define <vscale x 2 x i32> @vpselect_zext(<vscale x 2 x i32> %passthru, <vscale x 2 x i8> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {833; CHECK-LABEL: vpselect_zext:834; CHECK: # %bb.0:835; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu836; CHECK-NEXT: vzext.vf4 v8, v9, v0.t837; CHECK-NEXT: ret838 %a = zext <vscale x 2 x i8> %x to <vscale x 2 x i32>839 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)840 ret <vscale x 2 x i32> %b841}842 843; Test integer truncation by trunc.844define <vscale x 2 x i32> @vpselect_trunc(<vscale x 2 x i32> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {845; CHECK-LABEL: vpselect_trunc:846; CHECK: # %bb.0:847; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu848; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t849; CHECK-NEXT: ret850 %a = trunc <vscale x 2 x i64> %x to <vscale x 2 x i32>851 %b = call <vscale x 2 x i32> @llvm.vp.select.nxv2i32(<vscale x 2 x i1> %m, <vscale x 2 x i32> %a, <vscale x 2 x i32> %passthru, i32 %vl)852 ret <vscale x 2 x i32> %b853}854 855; Folding this would create a loop in the DAG becuase the chain from the VLE is856; used by the vssubu.857define void @test_dag_loop() {858; CHECK-LABEL: test_dag_loop:859; CHECK: # %bb.0: # %entry860; CHECK-NEXT: vsetivli zero, 0, e8, m4, ta, ma861; CHECK-NEXT: vmclr.m v0862; CHECK-NEXT: vmv.v.i v8, 0863; CHECK-NEXT: vmv.v.i v12, 0864; CHECK-NEXT: vsetvli zero, zero, e8, m4, tu, mu865; CHECK-NEXT: vssubu.vx v12, v8, zero, v0.t866; CHECK-NEXT: vsetvli zero, zero, e8, m4, ta, ma867; CHECK-NEXT: vmseq.vv v0, v12, v8868; CHECK-NEXT: vsetvli zero, zero, e16, m8, ta, ma869; CHECK-NEXT: vmv.v.i v8, 0870; CHECK-NEXT: vsetvli zero, zero, e16, m8, tu, mu871; CHECK-NEXT: vle16.v v8, (zero), v0.t872; CHECK-NEXT: vse16.v v8, (zero)873; CHECK-NEXT: ret874entry:875 %0 = call <vscale x 32 x i16> @llvm.riscv.vle.nxv32i16.i64(<vscale x 32 x i16> poison, ptr null, i64 1)876 %1 = tail call <vscale x 32 x i8> @llvm.riscv.vssubu.mask.nxv32i8.i8.i64(<vscale x 32 x i8> zeroinitializer, <vscale x 32 x i8> zeroinitializer, i8 0, <vscale x 32 x i1> zeroinitializer, i64 0, i64 0)877 %2 = tail call <vscale x 32 x i1> @llvm.riscv.vmseq.nxv32i8.nxv32i8.i64(<vscale x 32 x i8> %1, <vscale x 32 x i8> zeroinitializer, i64 0)878 %3 = tail call <vscale x 32 x i16> @llvm.riscv.vmerge.nxv32i16.nxv32i16.i64(<vscale x 32 x i16> zeroinitializer, <vscale x 32 x i16> zeroinitializer, <vscale x 32 x i16> %0, <vscale x 32 x i1> %2, i64 1)879 call void @llvm.riscv.vse.nxv32i16.i64(<vscale x 32 x i16> %3, ptr null, i64 0)880 ret void881}882 883define <vscale x 1 x i16> @test_vaaddu(<vscale x 1 x i16> %var_11, i16 zeroext %var_9, <vscale x 1 x i1> %var_5, <vscale x 1 x i16> %var_0) {884; CHECK-LABEL: test_vaaddu:885; CHECK: # %bb.0: # %entry886; CHECK-NEXT: csrwi vxrm, 0887; CHECK-NEXT: vsetivli zero, 3, e16, mf4, ta, mu888; CHECK-NEXT: vaaddu.vx v9, v8, a0, v0.t889; CHECK-NEXT: vmv1r.v v8, v9890; CHECK-NEXT: ret891entry:892 %0 = tail call <vscale x 1 x i16> @llvm.riscv.vaaddu.nxv1i16.i16.i64(<vscale x 1 x i16> poison, <vscale x 1 x i16> %var_11, i16 %var_9, i64 0, i64 3)893 %1 = tail call <vscale x 1 x i16> @llvm.riscv.vmerge.nxv1i16.nxv1i16.i64(<vscale x 1 x i16> poison, <vscale x 1 x i16> %var_0, <vscale x 1 x i16> %0, <vscale x 1 x i1> %var_5, i64 3)894 ret <vscale x 1 x i16> %1895}896 897; Test reductions don't have a vmerge folded into them, since the mask affects898; the result.899 900define <vscale x 2 x i32> @vredsum(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i64 %vl) {901; CHECK-LABEL: vredsum:902; CHECK: # %bb.0:903; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma904; CHECK-NEXT: vmv1r.v v11, v8905; CHECK-NEXT: vredsum.vs v11, v9, v10906; CHECK-NEXT: vmerge.vvm v8, v8, v11, v0907; CHECK-NEXT: ret908 %a = call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv2i32(909 <vscale x 2 x i32> %passthru,910 <vscale x 2 x i32> %x,911 <vscale x 2 x i32> %y,912 i64 %vl)913 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 %vl)914 ret <vscale x 2 x i32> %b915}916 917define <vscale x 2 x float> @vfredusum(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %m, i64 %vl) {918; CHECK-LABEL: vfredusum:919; CHECK: # %bb.0:920; CHECK-NEXT: fsrmi a1, 0921; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma922; CHECK-NEXT: vmv1r.v v11, v8923; CHECK-NEXT: vfredusum.vs v11, v9, v10924; CHECK-NEXT: vmerge.vvm v8, v8, v11, v0925; CHECK-NEXT: fsrm a1926; CHECK-NEXT: ret927 %a = call <vscale x 2 x float> @llvm.riscv.vfredusum.nxv2f32.nxv2f32(928 <vscale x 2 x float> %passthru,929 <vscale x 2 x float> %x,930 <vscale x 2 x float> %y,931 i64 0, i64 %vl)932 %b = call <vscale x 2 x float> @llvm.riscv.vmerge.nxv2f32.nxv2f32(<vscale x 2 x float> %passthru, <vscale x 2 x float> %passthru, <vscale x 2 x float> %a, <vscale x 2 x i1> %m, i64 %vl)933 ret <vscale x 2 x float> %b934}935 936; However we can fold it in if the mask is all ones.937define <vscale x 2 x i32> @vredsum_allones_mask(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 %vl) {938; CHECK-LABEL: vredsum_allones_mask:939; CHECK: # %bb.0:940; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma941; CHECK-NEXT: vredsum.vs v8, v9, v10942; CHECK-NEXT: ret943 %a = call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv2i32(944 <vscale x 2 x i32> %passthru,945 <vscale x 2 x i32> %x,946 <vscale x 2 x i32> %y,947 i64 %vl)948 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> splat (i1 -1), i64 %vl)949 ret <vscale x 2 x i32> %b950}951 952define <vscale x 2 x float> @vfredusum_allones_mask(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, i64 %vl) {953; CHECK-LABEL: vfredusum_allones_mask:954; CHECK: # %bb.0:955; CHECK-NEXT: fsrmi a1, 0956; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma957; CHECK-NEXT: vfredusum.vs v8, v9, v10958; CHECK-NEXT: fsrm a1959; CHECK-NEXT: ret960 %a = call <vscale x 2 x float> @llvm.riscv.vfredusum.nxv2f32.nxv2f32(961 <vscale x 2 x float> %passthru,962 <vscale x 2 x float> %x,963 <vscale x 2 x float> %y,964 i64 0, i64 %vl)965 %b = call <vscale x 2 x float> @llvm.riscv.vmerge.nxv2f32.nxv2f32(<vscale x 2 x float> %passthru, <vscale x 2 x float> %passthru, <vscale x 2 x float> %a, <vscale x 2 x i1> splat (i1 -1), i64 %vl)966 ret <vscale x 2 x float> %b967}968 969define <vscale x 2 x i32> @unfoldable_vredsum_allones_mask_diff_vl(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y) {970; CHECK-LABEL: unfoldable_vredsum_allones_mask_diff_vl:971; CHECK: # %bb.0:972; CHECK-NEXT: vsetvli a0, zero, e32, m1, tu, ma973; CHECK-NEXT: vmv1r.v v11, v8974; CHECK-NEXT: vredsum.vs v11, v9, v10975; CHECK-NEXT: vsetivli zero, 1, e32, m1, tu, ma976; CHECK-NEXT: vmv.v.v v8, v11977; CHECK-NEXT: ret978 %a = call <vscale x 2 x i32> @llvm.riscv.vredsum.nxv2i32.nxv2i32(979 <vscale x 2 x i32> %passthru,980 <vscale x 2 x i32> %x,981 <vscale x 2 x i32> %y,982 i64 -1)983 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> splat (i1 -1), i64 1)984 ret <vscale x 2 x i32> %b985}986 987; Tests for folding vmerge into its ops when their VLs differ988 989; Can fold with VL=2990define <vscale x 2 x i32> @vmerge_smaller_vl_same_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {991; CHECK-LABEL: vmerge_smaller_vl_same_passthru:992; CHECK: # %bb.0:993; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu994; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t995; CHECK-NEXT: ret996 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 4)997 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 2)998 ret <vscale x 2 x i32> %b999}1000 1001; Can fold with VL=21002define <vscale x 2 x i32> @vmerge_larger_vl_same_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1003; CHECK-LABEL: vmerge_larger_vl_same_passthru:1004; CHECK: # %bb.0:1005; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu1006; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t1007; CHECK-NEXT: ret1008 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 2)1009 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 3)1010 ret <vscale x 2 x i32> %b1011}1012 1013; Can fold with VL=21014define <vscale x 2 x i32> @vmerge_smaller_vl_different_passthru(<vscale x 2 x i32> %pt1, <vscale x 2 x i32> %pt2, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1015; CHECK-LABEL: vmerge_smaller_vl_different_passthru:1016; CHECK: # %bb.0:1017; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma1018; CHECK-NEXT: vadd.vv v8, v10, v111019; CHECK-NEXT: vmerge.vvm v9, v9, v8, v01020; CHECK-NEXT: vmv1r.v v8, v91021; CHECK-NEXT: ret1022 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> %pt1, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 3)1023 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %pt2, <vscale x 2 x i32> %pt2, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 2)1024 ret <vscale x 2 x i32> %b1025}1026 1027; Can't fold this because we need to take elements from both %pt1 and %pt21028define <vscale x 2 x i32> @vmerge_larger_vl_different_passthru(<vscale x 2 x i32> %pt1, <vscale x 2 x i32> %pt2, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1029; CHECK-LABEL: vmerge_larger_vl_different_passthru:1030; CHECK: # %bb.0:1031; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, ma1032; CHECK-NEXT: vadd.vv v8, v10, v111033; CHECK-NEXT: vsetivli zero, 3, e32, m1, tu, ma1034; CHECK-NEXT: vmerge.vvm v9, v9, v8, v01035; CHECK-NEXT: vmv1r.v v8, v91036; CHECK-NEXT: ret1037 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> %pt1, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 2)1038 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %pt2, <vscale x 2 x i32> %pt2, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 3)1039 ret <vscale x 2 x i32> %b1040}1041 1042; Can fold with VL=21043define <vscale x 2 x i32> @vmerge_smaller_vl_poison_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1044; CHECK-LABEL: vmerge_smaller_vl_poison_passthru:1045; CHECK: # %bb.0:1046; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu1047; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t1048; CHECK-NEXT: ret1049 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 3)1050 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 2)1051 ret <vscale x 2 x i32> %b1052}1053 1054; Can fold with VL=21055define <vscale x 2 x i32> @vmerge_larger_vl_poison_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1056; CHECK-LABEL: vmerge_larger_vl_poison_passthru:1057; CHECK: # %bb.0:1058; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu1059; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t1060; CHECK-NEXT: ret1061 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 2)1062 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %passthru, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 3)1063 ret <vscale x 2 x i32> %b1064}1065 1066; The vadd's new policy should be tail undisturbed since the false op of the1067; vmerge moves from the the body to the tail, and we need to preserve it.1068define <vscale x 2 x i32> @vmerge_larger_vl_false_becomes_tail(<vscale x 2 x i32> %false, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m) {1069; CHECK-LABEL: vmerge_larger_vl_false_becomes_tail:1070; CHECK: # %bb.0:1071; CHECK-NEXT: vsetivli zero, 2, e32, m1, tu, mu1072; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t1073; CHECK-NEXT: ret1074 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.nxv2i32.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 2)1075 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(<vscale x 2 x i32> poison, <vscale x 2 x i32> %false, <vscale x 2 x i32> %a, <vscale x 2 x i1> %m, i64 3)1076 ret <vscale x 2 x i32> %b1077}1078 1079; Test widening pseudos with their TIED variant (passthru same as first op).1080define <vscale x 2 x i64> @vpmerge_vwsub.w_tied(<vscale x 2 x i64> %passthru, <vscale x 2 x i64> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %mask, i32 zeroext %vl) {1081; CHECK-LABEL: vpmerge_vwsub.w_tied:1082; CHECK: # %bb.0:1083; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu1084; CHECK-NEXT: vwsub.wv v8, v8, v12, v0.t1085; CHECK-NEXT: ret1086 %vl.zext = zext i32 %vl to i641087 %a = call <vscale x 2 x i64> @llvm.riscv.vwsub.w.nxv2i64.nxv2i32(<vscale x 2 x i64> %passthru, <vscale x 2 x i64> %passthru, <vscale x 2 x i32> %y, i64 %vl.zext)1088 %b = call <vscale x 2 x i64> @llvm.vp.merge.nxv2i64(<vscale x 2 x i1> %mask, <vscale x 2 x i64> %a, <vscale x 2 x i64> %passthru, i32 %vl)1089 ret <vscale x 2 x i64> %b1090}1091 1092define <vscale x 2 x double> @vpmerge_vfwsub.w_tied(<vscale x 2 x double> %passthru, <vscale x 2 x double> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %mask, i32 zeroext %vl) {1093; CHECK-LABEL: vpmerge_vfwsub.w_tied:1094; CHECK: # %bb.0:1095; CHECK-NEXT: fsrmi a1, 11096; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu1097; CHECK-NEXT: vfwsub.wv v8, v8, v12, v0.t1098; CHECK-NEXT: fsrm a11099; CHECK-NEXT: ret1100 %vl.zext = zext i32 %vl to i641101 %a = call <vscale x 2 x double> @llvm.riscv.vfwsub.w.nxv2f64.nxv2f32(<vscale x 2 x double> %passthru, <vscale x 2 x double> %passthru, <vscale x 2 x float> %y, i64 1, i64 %vl.zext)1102 %b = call <vscale x 2 x double> @llvm.vp.merge.nxv2f64(<vscale x 2 x i1> %mask, <vscale x 2 x double> %a, <vscale x 2 x double> %passthru, i32 %vl)1103 ret <vscale x 2 x double> %b1104}1105 1106define <vscale x 2 x i32> @true_tied_dest_vmerge_implicit_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i64 %avl) {1107; CHECK-LABEL: true_tied_dest_vmerge_implicit_passthru:1108; CHECK: # %bb.0:1109; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu1110; CHECK-NEXT: vmacc.vv v8, v9, v10, v0.t1111; CHECK-NEXT: ret1112 %a = call <vscale x 2 x i32> @llvm.riscv.vmacc.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, i64 %avl, i64 0)1113 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(1114 <vscale x 2 x i32> poison,1115 <vscale x 2 x i32> %passthru,1116 <vscale x 2 x i32> %a,1117 <vscale x 2 x i1> %m,1118 i64 %avl1119 )1120 ret <vscale x 2 x i32> %b1121}1122 1123define <vscale x 2 x i32> @true_mask_vmerge_implicit_passthru(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i64 %avl) {1124; CHECK-LABEL: true_mask_vmerge_implicit_passthru:1125; CHECK: # %bb.0:1126; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu1127; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t1128; CHECK-NEXT: ret1129 %a = call <vscale x 2 x i32> @llvm.riscv.vadd.mask.nxv2i32.nxv2i32(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %x, <vscale x 2 x i32> %y, <vscale x 2 x i1> %m, i64 %avl, i64 0)1130 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(1131 <vscale x 2 x i32> poison,1132 <vscale x 2 x i32> %passthru,1133 <vscale x 2 x i32> %a,1134 <vscale x 2 x i1> shufflevector(<vscale x 2 x i1> insertelement(<vscale x 2 x i1> poison, i1 true, i32 0), <vscale x 2 x i1> poison, <vscale x 2 x i32> zeroinitializer),1135 i64 %avl1136 )1137 ret <vscale x 2 x i32> %b1138}1139 1140define <vscale x 2 x i32> @unfoldable_mismatched_sew(<vscale x 2 x i32> %passthru, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, <vscale x 2 x i1> %mask, i64 %avl) {1141; CHECK-LABEL: unfoldable_mismatched_sew:1142; CHECK: # %bb.0:1143; CHECK-NEXT: vsetvli zero, a0, e64, m1, ta, ma1144; CHECK-NEXT: vadd.vv v9, v9, v101145; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, ma1146; CHECK-NEXT: vmv.v.v v8, v91147; CHECK-NEXT: ret1148 %a = call <vscale x 1 x i64> @llvm.riscv.vadd.nxv1i64.nxv1i64(<vscale x 1 x i64> poison, <vscale x 1 x i64> %x, <vscale x 1 x i64> %y, i64 %avl)1149 %a.bitcast = bitcast <vscale x 1 x i64> %a to <vscale x 2 x i32>1150 %b = call <vscale x 2 x i32> @llvm.riscv.vmerge.nxv2i32.nxv2i32(1151 <vscale x 2 x i32> %passthru,1152 <vscale x 2 x i32> %passthru,1153 <vscale x 2 x i32> %a.bitcast,1154 <vscale x 2 x i1> splat (i1 true),1155 i64 %avl1156 )1157 ret <vscale x 2 x i32> %b1158}1159 1160define <vscale x 2 x float> @commute_vfmadd(<vscale x 2 x float> %passthru, <vscale x 2 x float> %x, <vscale x 2 x float> %y, <vscale x 2 x i1> %mask, i32 zeroext %evl) {1161; CHECK-LABEL: commute_vfmadd:1162; CHECK: # %bb.0:1163; CHECK-NEXT: vsetvli zero, a0, e32, m1, tu, mu1164; CHECK-NEXT: vfmacc.vv v8, v9, v10, v0.t1165; CHECK-NEXT: ret1166 %fmul = fmul contract <vscale x 2 x float> %x, %y1167 %fadd = fadd contract <vscale x 2 x float> %fmul, %passthru1168 %merge = call <vscale x 2 x float> @llvm.vp.merge(<vscale x 2 x i1> %mask, <vscale x 2 x float> %fadd, <vscale x 2 x float> %passthru, i32 %evl)1169 ret <vscale x 2 x float> %merge1170}1171