diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2633,19 +2633,33 @@ Opcode == RISCV::PseudoVMERGE_VVM_M8_TU; }; + auto IsVMergeTA = [](unsigned Opcode) { + return Opcode == RISCV::PseudoVMERGE_VVM_MF8 || + Opcode == RISCV::PseudoVMERGE_VVM_MF4 || + Opcode == RISCV::PseudoVMERGE_VVM_MF2 || + Opcode == RISCV::PseudoVMERGE_VVM_M1 || + Opcode == RISCV::PseudoVMERGE_VVM_M2 || + Opcode == RISCV::PseudoVMERGE_VVM_M4 || + Opcode == RISCV::PseudoVMERGE_VVM_M8; + }; + unsigned Opc = N->getMachineOpcode(); - // TODO: Also deal with TA VMerge nodes. - if (!IsVMergeTU(Opc)) + unsigned Offset = 0; + uint64_t Policy = 0; // TUMU. + if (IsVMergeTU(Opc)) { + // MergeOp should equal to FalseOp. + if (N->getOperand(0) != N->getOperand(1)) + continue; + Offset = 1; + } else if (IsVMergeTA(Opc)) { + Policy = RISCVII::TAIL_AGNOSTIC; + } else continue; - SDValue Merge = N->getOperand(0); - SDValue False = N->getOperand(1); - SDValue True = N->getOperand(2); - SDValue Mask = N->getOperand(3); - SDValue VL = N->getOperand(4); - - if (Merge != False) - continue; + SDValue False = N->getOperand(0 + Offset); + SDValue True = N->getOperand(1 + Offset); + SDValue Mask = N->getOperand(2 + Offset); + SDValue VL = N->getOperand(3 + Offset); assert(True.getResNo() == 0 && "Expect True is the first output of an instruction."); @@ -2698,13 +2712,14 @@ SDLoc DL(N); unsigned MaskedOpc = Info->MaskedPseudo; SmallVector Ops; - Ops.push_back(Merge); + if (RISCVII::hasVecPolicyOp(TII->get(MaskedOpc).TSFlags)) + Ops.push_back(False); Ops.append(True->op_begin(), True->op_begin() + TrueVLIndex); Ops.append({Mask, VL, /* SEW */ True.getOperand(TrueVLIndex + 1)}); if (RISCVII::hasVecPolicyOp(TII->get(MaskedOpc).TSFlags)) Ops.push_back( - CurDAG->getTargetConstant(/* TUMU */ 0, DL, Subtarget->getXLenVT())); + CurDAG->getTargetConstant(Policy, DL, Subtarget->getXLenVT())); // Result node should have chain operand of True. if (HasChainOp) diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-peephole-vmerge-vops.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-peephole-vmerge-vops.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-peephole-vmerge-vops.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-peephole-vmerge-vops.ll @@ -337,3 +337,327 @@ %b = call <8 x i32> @llvm.vp.merge.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) ret <8 x i32> %b } + +declare <8 x i16> @llvm.vp.select.nxv2i16(<8 x i1>, <8 x i16>, <8 x i16>, i32) +declare <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1>, <8 x i32>, <8 x i32>, i32) +declare <8 x float> @llvm.vp.select.nxv2f32(<8 x i1>, <8 x float>, <8 x float>, i32) +declare <8 x double> @llvm.vp.select.nxv2f64(<8 x i1>, <8 x double>, <8 x double>, i32) + +; Test binary operator with vp.select and vp.add. +define <8 x i32> @vpselect_vpadd(<8 x i32> %passthru, <8 x i32> %x, <8 x i32> %y, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVADD_VV_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.add.nxv2i32(<8 x i32> %x, <8 x i32> %y, <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test glued node of select should not be deleted. +define <8 x i32> @vpselect_vpadd2(<8 x i32> %passthru, <8 x i32> %x, <8 x i32> %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd2: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vmseq.vv v0, v9, v10 +; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd2 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: [[PseudoVMSEQ_VV_M1_:%[0-9]+]]:vr = PseudoVMSEQ_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v0 = COPY [[PseudoVMSEQ_VV_M1_]] + ; MIR-NEXT: [[PseudoVADD_VV_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVADD_VV_M1_MASK [[COPY3]], [[COPY2]], [[COPY1]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.add.nxv2i32(<8 x i32> %x, <8 x i32> %y, <8 x i1> %mask, i32 %vl) + %m = call <8 x i1> @llvm.vp.icmp.nxv2i32(<8 x i32> %x, <8 x i32> %y, metadata !"eq", <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test vp.select have all-ones mask. +define <8 x i32> @vpselect_vpadd3(<8 x i32> %passthru, <8 x i32> %x, <8 x i32> %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd3: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vadd.vv v8, v9, v10 +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd3 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v9, $v10, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.add.nxv2i32(<8 x i32> %x, <8 x i32> %y, <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %mask, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test float binary operator with vp.select and vp.fadd. +define <8 x float> @vpselect_vpfadd(<8 x float> %passthru, <8 x float> %x, <8 x float> %y, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfadd: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfadd + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: %5:vrnov0 = nofpexcept PseudoVFADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %5 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x float> @llvm.vp.fadd.nxv2f32(<8 x float> %x, <8 x float> %y, <8 x i1> %mask, i32 %vl) + %b = call <8 x float> @llvm.vp.select.nxv2f32(<8 x i1> %m, <8 x float> %a, <8 x float> %passthru, i32 %vl) + ret <8 x float> %b +} + +; Test conversion by fptosi. +define <8 x i16> @vpselect_vpfptosi(<8 x i16> %passthru, <8 x float> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfptosi: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, mu +; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfptosi + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_RTZ_X_F_W_MF2_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 4 /* e16 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i16> @llvm.vp.fptosi.nxv2i16.nxv2f32(<8 x float> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x i16> @llvm.vp.select.nxv2i16(<8 x i1> %m, <8 x i16> %a, <8 x i16> %passthru, i32 %vl) + ret <8 x i16> %b +} + +; Test conversion by sitofp. +define <8 x float> @vpselect_vpsitofp(<8 x float> %passthru, <8 x i64> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpsitofp: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpsitofp + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_X_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x float> @llvm.vp.sitofp.nxv2f32.nxv2i64(<8 x i64> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x float> @llvm.vp.select.nxv2f32(<8 x i1> %m, <8 x float> %a, <8 x float> %passthru, i32 %vl) + ret <8 x float> %b +} + +; Test integer extension by vp.zext. +define <8 x i32> @vpselect_vpzext(<8 x i32> %passthru, <8 x i8> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpzext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vzext.vf4 v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpzext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVZEXT_VF4_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.zext.nxv2i32.nxv2i8(<8 x i8> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test integer truncation by vp.trunc. +define <8 x i32> @vpselect_vptrunc(<8 x i32> %passthru, <8 x i64> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vptrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vptrunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVNSRL_WI_M1_MASK [[COPY3]], [[COPY2]], 0, $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.trunc.nxv2i32.nxv2i64(<8 x i64> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test integer extension by vp.fpext. +define <8 x double> @vpselect_vpfpext(<8 x double> %passthru, <8 x float> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfpext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfpext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8m2, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrm2nov0 = COPY $v8m2 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrm2nov0 = nofpexcept PseudoVFWCVT_F_F_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8m2 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8m2 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x double> @llvm.vp.fpext.nxv2f64.nxv2f32(<8 x float> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x double> @llvm.vp.select.nxv2f64(<8 x i1> %m, <8 x double> %a, <8 x double> %passthru, i32 %vl) + ret <8 x double> %b +} + +; Test integer truncation by vp.trunc. +define <8 x float> @vpselect_vpfptrunc(<8 x float> %passthru, <8 x double> %x, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfptrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfptrunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_F_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x float> @llvm.vp.fptrunc.nxv2f32.nxv2f64(<8 x double> %x, <8 x i1> %mask, i32 %vl) + %b = call <8 x float> @llvm.vp.select.nxv2f32(<8 x i1> %m, <8 x float> %a, <8 x float> %passthru, i32 %vl) + ret <8 x float> %b +} + +; Test load operation by vp.load. +define <8 x i32> @vpselect_vpload(<8 x i32> %passthru, <8 x i32> * %p, <8 x i1> %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpload: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vle32.v v8, (a0), v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpload + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v0, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVLE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLE32_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVLE32_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.load.nxv2i32.p0nxv2i32(<8 x i32> * %p, <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} + +; Test result have chain and glued node. +define <8 x i32> @vpselect_vpload2(<8 x i32> %passthru, <8 x i32> * %p, <8 x i32> %x, <8 x i32> %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpload2: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vmseq.vv v0, v9, v10 +; CHECK-NEXT: vle32.v v8, (a0), v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpload2 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v9, $v10, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: [[PseudoVMSEQ_VV_M1_:%[0-9]+]]:vr = PseudoVMSEQ_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v0 = COPY [[PseudoVMSEQ_VV_M1_]] + ; MIR-NEXT: [[PseudoVLE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLE32_V_M1_MASK [[COPY4]], [[COPY3]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVLE32_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement <8 x i1> poison, i1 -1, i32 0 + %mask = shufflevector <8 x i1> %splat, <8 x i1> poison, <8 x i32> zeroinitializer + %a = call <8 x i32> @llvm.vp.load.nxv2i32.p0nxv2i32(<8 x i32> * %p, <8 x i1> %mask, i32 %vl) + %m = call <8 x i1> @llvm.vp.icmp.nxv2i32(<8 x i32> %x, <8 x i32> %y, metadata !"eq", <8 x i1> %mask, i32 %vl) + %b = call <8 x i32> @llvm.vp.select.nxv2i32(<8 x i1> %m, <8 x i32> %a, <8 x i32> %passthru, i32 %vl) + ret <8 x i32> %b +} diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vselect.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vselect.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vselect.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-vselect.ll @@ -6,10 +6,9 @@ ; CHECK-LABEL: vselect_vv_v8i32: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu -; CHECK-NEXT: vle32.v v8, (a0) ; CHECK-NEXT: vlm.v v0, (a2) -; CHECK-NEXT: vle32.v v10, (a1) -; CHECK-NEXT: vmerge.vvm v8, v10, v8, v0 +; CHECK-NEXT: vle32.v v8, (a1) +; CHECK-NEXT: vle32.v v8, (a0), v0.t ; CHECK-NEXT: vse32.v v8, (a3) ; CHECK-NEXT: ret %va = load <8 x i32>, <8 x i32>* %a @@ -60,10 +59,9 @@ ; CHECK-LABEL: vselect_vv_v8f32: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 8, e32, m2, ta, mu -; CHECK-NEXT: vle32.v v8, (a0) ; CHECK-NEXT: vlm.v v0, (a2) -; CHECK-NEXT: vle32.v v10, (a1) -; CHECK-NEXT: vmerge.vvm v8, v10, v8, v0 +; CHECK-NEXT: vle32.v v8, (a1) +; CHECK-NEXT: vle32.v v8, (a0), v0.t ; CHECK-NEXT: vse32.v v8, (a3) ; CHECK-NEXT: ret %va = load <8 x float>, <8 x float>* %a @@ -114,10 +112,9 @@ ; CHECK-LABEL: vselect_vv_v16i16: ; CHECK: # %bb.0: ; CHECK-NEXT: vsetivli zero, 16, e16, m2, ta, mu -; CHECK-NEXT: vle16.v v8, (a0) ; CHECK-NEXT: vlm.v v0, (a2) -; CHECK-NEXT: vle16.v v10, (a1) -; CHECK-NEXT: vmerge.vvm v8, v10, v8, v0 +; CHECK-NEXT: vle16.v v8, (a1) +; CHECK-NEXT: vle16.v v8, (a0), v0.t ; CHECK-NEXT: vse16.v v8, (a3) ; CHECK-NEXT: ret %va = load <16 x i16>, <16 x i16>* %a @@ -169,10 +166,9 @@ ; CHECK: # %bb.0: ; CHECK-NEXT: li a4, 32 ; CHECK-NEXT: vsetvli zero, a4, e16, m4, ta, mu -; CHECK-NEXT: vle16.v v8, (a0) ; CHECK-NEXT: vlm.v v0, (a2) -; CHECK-NEXT: vle16.v v12, (a1) -; CHECK-NEXT: vmerge.vvm v8, v12, v8, v0 +; CHECK-NEXT: vle16.v v8, (a1) +; CHECK-NEXT: vle16.v v8, (a0), v0.t ; CHECK-NEXT: vse16.v v8, (a3) ; CHECK-NEXT: ret %va = load <32 x half>, <32 x half>* %a diff --git a/llvm/test/CodeGen/RISCV/rvv/fptosi-sat.ll b/llvm/test/CodeGen/RISCV/rvv/fptosi-sat.ll --- a/llvm/test/CodeGen/RISCV/rvv/fptosi-sat.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fptosi-sat.ll @@ -210,20 +210,14 @@ ; CHECK32-NEXT: sw a0, 12(sp) ; CHECK32-NEXT: vsetvli a0, zero, e32, m1, ta, mu ; CHECK32-NEXT: vmfge.vf v9, v8, ft0 -; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v10, (a0), zero ; CHECK32-NEXT: vmnot.m v0, v9 -; CHECK32-NEXT: vfwcvt.rtz.x.f.v v12, v8 -; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu -; CHECK32-NEXT: vmerge.vvm v10, v12, v10, v0 -; CHECK32-NEXT: lui a1, %hi(.LCPI5_1) -; CHECK32-NEXT: flw ft0, %lo(.LCPI5_1)(a1) -; CHECK32-NEXT: vsetvli zero, zero, e32, m1, ta, mu -; CHECK32-NEXT: vlse64.v v12, (a0), zero +; CHECK32-NEXT: vfwcvt.rtz.x.f.v v10, v8 +; CHECK32-NEXT: lui a0, %hi(.LCPI5_1) +; CHECK32-NEXT: flw ft0, %lo(.LCPI5_1)(a0) +; CHECK32-NEXT: addi a0, sp, 8 +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu -; CHECK32-NEXT: vmerge.vvm v10, v10, v12, v0 -; CHECK32-NEXT: vsetvli zero, zero, e32, m1, ta, mu +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t ; CHECK32-NEXT: vmfne.vv v0, v8, v8 ; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu ; CHECK32-NEXT: vmerge.vim v8, v10, 0, v0 @@ -274,20 +268,14 @@ ; CHECK32-NEXT: sw a0, 12(sp) ; CHECK32-NEXT: vsetvli a0, zero, e32, m2, ta, mu ; CHECK32-NEXT: vmfge.vf v10, v8, ft0 -; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v12, (a0), zero ; CHECK32-NEXT: vmnot.m v0, v10 -; CHECK32-NEXT: vfwcvt.rtz.x.f.v v16, v8 -; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu -; CHECK32-NEXT: vmerge.vvm v12, v16, v12, v0 -; CHECK32-NEXT: lui a1, %hi(.LCPI6_1) -; CHECK32-NEXT: flw ft0, %lo(.LCPI6_1)(a1) -; CHECK32-NEXT: vsetvli zero, zero, e32, m2, ta, mu -; CHECK32-NEXT: vlse64.v v16, (a0), zero +; CHECK32-NEXT: vfwcvt.rtz.x.f.v v12, v8 +; CHECK32-NEXT: lui a0, %hi(.LCPI6_1) +; CHECK32-NEXT: flw ft0, %lo(.LCPI6_1)(a0) +; CHECK32-NEXT: addi a0, sp, 8 +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu -; CHECK32-NEXT: vmerge.vvm v12, v12, v16, v0 -; CHECK32-NEXT: vsetvli zero, zero, e32, m2, ta, mu +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t ; CHECK32-NEXT: vmfne.vv v0, v8, v8 ; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu ; CHECK32-NEXT: vmerge.vim v8, v12, 0, v0 @@ -458,18 +446,15 @@ ; CHECK32-NEXT: vsetvli a0, zero, e64, m2, ta, mu ; CHECK32-NEXT: vmfge.vf v10, v8, ft0 ; CHECK32-NEXT: vmnot.m v0, v10 +; CHECK32-NEXT: vfcvt.rtz.x.f.v v10, v8 +; CHECK32-NEXT: lui a0, %hi(.LCPI12_1) +; CHECK32-NEXT: fld ft0, %lo(.LCPI12_1)(a0) ; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v10, (a0), zero -; CHECK32-NEXT: lui a1, %hi(.LCPI12_1) -; CHECK32-NEXT: fld ft0, %lo(.LCPI12_1)(a1) -; CHECK32-NEXT: vfcvt.rtz.x.f.v v12, v8 -; CHECK32-NEXT: vlse64.v v14, (a0), zero -; CHECK32-NEXT: vmerge.vvm v12, v12, v10, v0 +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vmfne.vv v10, v8, v8 -; CHECK32-NEXT: vmerge.vvm v8, v12, v14, v0 -; CHECK32-NEXT: vmv1r.v v0, v10 -; CHECK32-NEXT: vmerge.vim v8, v8, 0, v0 +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t +; CHECK32-NEXT: vmfne.vv v0, v8, v8 +; CHECK32-NEXT: vmerge.vim v8, v10, 0, v0 ; CHECK32-NEXT: addi sp, sp, 16 ; CHECK32-NEXT: ret ; @@ -514,18 +499,15 @@ ; CHECK32-NEXT: vsetvli a0, zero, e64, m4, ta, mu ; CHECK32-NEXT: vmfge.vf v12, v8, ft0 ; CHECK32-NEXT: vmnot.m v0, v12 +; CHECK32-NEXT: vfcvt.rtz.x.f.v v12, v8 +; CHECK32-NEXT: lui a0, %hi(.LCPI13_1) +; CHECK32-NEXT: fld ft0, %lo(.LCPI13_1)(a0) ; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v12, (a0), zero -; CHECK32-NEXT: lui a1, %hi(.LCPI13_1) -; CHECK32-NEXT: fld ft0, %lo(.LCPI13_1)(a1) -; CHECK32-NEXT: vfcvt.rtz.x.f.v v16, v8 -; CHECK32-NEXT: vlse64.v v20, (a0), zero -; CHECK32-NEXT: vmerge.vvm v16, v16, v12, v0 +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vmfne.vv v12, v8, v8 -; CHECK32-NEXT: vmerge.vvm v8, v16, v20, v0 -; CHECK32-NEXT: vmv1r.v v0, v12 -; CHECK32-NEXT: vmerge.vim v8, v8, 0, v0 +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t +; CHECK32-NEXT: vmfne.vv v0, v8, v8 +; CHECK32-NEXT: vmerge.vim v8, v12, 0, v0 ; CHECK32-NEXT: addi sp, sp, 16 ; CHECK32-NEXT: ret ; @@ -831,21 +813,16 @@ ; CHECK32-NEXT: vsetvli a0, zero, e16, mf2, ta, mu ; CHECK32-NEXT: vmfge.vf v9, v8, ft0 ; CHECK32-NEXT: vmnot.m v0, v9 -; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v10, (a0), zero ; CHECK32-NEXT: vfwcvt.f.f.v v9, v8 ; CHECK32-NEXT: vsetvli zero, zero, e32, m1, ta, mu -; CHECK32-NEXT: vfwcvt.rtz.x.f.v v12, v9 -; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu -; CHECK32-NEXT: vmerge.vvm v10, v12, v10, v0 -; CHECK32-NEXT: lui a1, %hi(.LCPI19_1) -; CHECK32-NEXT: flh ft0, %lo(.LCPI19_1)(a1) +; CHECK32-NEXT: vfwcvt.rtz.x.f.v v10, v9 +; CHECK32-NEXT: lui a0, %hi(.LCPI19_1) +; CHECK32-NEXT: flh ft0, %lo(.LCPI19_1)(a0) +; CHECK32-NEXT: addi a0, sp, 8 +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t ; CHECK32-NEXT: vsetvli zero, zero, e16, mf2, ta, mu -; CHECK32-NEXT: vlse64.v v12, (a0), zero ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu -; CHECK32-NEXT: vmerge.vvm v10, v10, v12, v0 -; CHECK32-NEXT: vsetvli zero, zero, e16, mf2, ta, mu +; CHECK32-NEXT: vlse64.v v10, (a0), zero, v0.t ; CHECK32-NEXT: vmfne.vv v0, v8, v8 ; CHECK32-NEXT: vsetvli zero, zero, e64, m2, ta, mu ; CHECK32-NEXT: vmerge.vim v8, v10, 0, v0 @@ -899,21 +876,16 @@ ; CHECK32-NEXT: vsetvli a0, zero, e16, m1, ta, mu ; CHECK32-NEXT: vmfge.vf v9, v8, ft0 ; CHECK32-NEXT: vmnot.m v0, v9 -; CHECK32-NEXT: addi a0, sp, 8 -; CHECK32-NEXT: vlse64.v v12, (a0), zero ; CHECK32-NEXT: vfwcvt.f.f.v v10, v8 ; CHECK32-NEXT: vsetvli zero, zero, e32, m2, ta, mu -; CHECK32-NEXT: vfwcvt.rtz.x.f.v v16, v10 -; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu -; CHECK32-NEXT: vmerge.vvm v12, v16, v12, v0 -; CHECK32-NEXT: lui a1, %hi(.LCPI20_1) -; CHECK32-NEXT: flh ft0, %lo(.LCPI20_1)(a1) +; CHECK32-NEXT: vfwcvt.rtz.x.f.v v12, v10 +; CHECK32-NEXT: lui a0, %hi(.LCPI20_1) +; CHECK32-NEXT: flh ft0, %lo(.LCPI20_1)(a0) +; CHECK32-NEXT: addi a0, sp, 8 +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t ; CHECK32-NEXT: vsetvli zero, zero, e16, m1, ta, mu -; CHECK32-NEXT: vlse64.v v16, (a0), zero ; CHECK32-NEXT: vmfgt.vf v0, v8, ft0 -; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu -; CHECK32-NEXT: vmerge.vvm v12, v12, v16, v0 -; CHECK32-NEXT: vsetvli zero, zero, e16, m1, ta, mu +; CHECK32-NEXT: vlse64.v v12, (a0), zero, v0.t ; CHECK32-NEXT: vmfne.vv v0, v8, v8 ; CHECK32-NEXT: vsetvli zero, zero, e64, m4, ta, mu ; CHECK32-NEXT: vmerge.vim v8, v12, 0, v0 diff --git a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll --- a/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll +++ b/llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll @@ -798,3 +798,779 @@ %b = call @llvm.vp.merge.nxv2i32( %m, %a, %passthru, i32 %vl) ret %b } + +declare @llvm.vp.select.nxv2i16(, , , i32) +declare @llvm.vp.select.nxv2i32(, , , i32) +declare @llvm.vp.select.nxv2f32(, , , i32) +declare @llvm.vp.select.nxv2f64(, , , i32) + +; Test binary operator with vp.select and vp.smax. +define @vpselect_vpadd( %passthru, %x, %y, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVADD_VV_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.add.nxv2i32( %x, %y, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test glued node of select should not be deleted. +define @vpselect_vpadd2( %passthru, %x, %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd2: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vmseq.vv v0, v9, v10 +; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd2 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: [[PseudoVMSEQ_VV_M1_:%[0-9]+]]:vr = PseudoVMSEQ_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v0 = COPY [[PseudoVMSEQ_VV_M1_]] + ; MIR-NEXT: [[PseudoVADD_VV_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVADD_VV_M1_MASK [[COPY3]], [[COPY2]], [[COPY1]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.add.nxv2i32( %x, %y, %mask, i32 %vl) + %m = call @llvm.vp.icmp.nxv2i32( %x, %y, metadata !"eq", %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test vp.select has all-ones mask. +define @vpselect_vpadd3( %passthru, %x, %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpadd3: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vadd.vv v8, v9, v10 +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpadd3 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v9, $v10, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[PseudoVADD_VV_M1_:%[0-9]+]]:vr = PseudoVADD_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.add.nxv2i32( %x, %y, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %mask, %a, %passthru, i32 %vl) + ret %b +} + +; Test float binary operator with vp.select and vp.fadd. +define @vpselect_vpfadd( %passthru, %x, %y, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfadd: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfadd + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: %5:vrnov0 = nofpexcept PseudoVFADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %5 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.fadd.nxv2f32( %x, %y, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test for binary operator with specific EEW by riscv.vrgatherei16. +define @vpselect_vrgatherei16( %passthru, %x, %y, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vrgatherei16: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vrgatherei16.vv v8, v9, v10 +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vrgatherei16 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v9, $v10, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: early-clobber %5:vr = PseudoVRGATHEREI16_VV_M1_MF2 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v8 = COPY %5 + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %2 = tail call @llvm.riscv.vrgatherei16.vv.nxv2i32.i64( undef, %x, %y, i64 %1) + %3 = tail call @llvm.vp.select.nxv2i32( %m, %2, %passthru, i32 %vl) + ret %2 +} + +; Test conversion by fptosi. +define @vpselect_vpfptosi( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfptosi: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, mu +; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfptosi + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_RTZ_X_F_W_MF2_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 4 /* e16 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.fptosi.nxv2i16.nxv2f32( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i16( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test conversion by sitofp. +define @vpselect_vpsitofp( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpsitofp: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpsitofp + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_X_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.sitofp.nxv2f32.nxv2i64( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer extension by vp.zext. +define @vpselect_vpzext( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpzext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vzext.vf4 v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpzext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVZEXT_VF4_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.zext.nxv2i32.nxv2i8( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer truncation by vp.trunc. +define @vpselect_vptrunc( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vptrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vptrunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVNSRL_WI_M1_MASK [[COPY3]], [[COPY2]], 0, $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.trunc.nxv2i32.nxv2i64( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer extension by vp.fpext. +define @vpselect_vpfpext( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfpext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfpext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8m2, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrm2nov0 = COPY $v8m2 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrm2nov0 = nofpexcept PseudoVFWCVT_F_F_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8m2 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8m2 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.fpext.nxv2f64.nxv2f32( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2f64( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer truncation by vp.trunc. +define @vpselect_vpfptrunc( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpfptrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpfptrunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_F_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.fptrunc.nxv2f32.nxv2f64( %x, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test load operation by vp.load. +define @vpselect_vpload( %passthru, * %p, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpload: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vle32.v v8, (a0), v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpload + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v0, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVLE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLE32_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVLE32_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.load.nxv2i32.p0nxv2i32( * %p, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test result has chain and glued node. +define @vpselect_vpload2( %passthru, * %p, %x, %y, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpload2: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vmseq.vv v0, v9, v10 +; CHECK-NEXT: vle32.v v8, (a0), v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpload2 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v9, $v10, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: [[PseudoVMSEQ_VV_M1_:%[0-9]+]]:vr = PseudoVMSEQ_VV_M1 [[COPY2]], [[COPY1]], [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v0 = COPY [[PseudoVMSEQ_VV_M1_]] + ; MIR-NEXT: [[PseudoVLE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLE32_V_M1_MASK [[COPY4]], [[COPY3]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVLE32_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.load.nxv2i32.p0nxv2i32( * %p, %mask, i32 %vl) + %m = call @llvm.vp.icmp.nxv2i32( %x, %y, metadata !"eq", %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test result has chain output of true operand of select.vvm. +define void @vpselect_vpload_store( %passthru, * %p, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vpload_store: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vle32.v v8, (a0), v0.t +; CHECK-NEXT: vs1r.v v8, (a0) +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vpload_store + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v0, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVLE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLE32_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: VS1R_V killed [[PseudoVLE32_V_M1_MASK]], [[COPY2]] :: (store unknown-size into %ir.p, align 8) + ; MIR-NEXT: PseudoRET + %splat = insertelement poison, i1 -1, i32 0 + %mask = shufflevector %splat, poison, zeroinitializer + %a = call @llvm.vp.load.nxv2i32.p0nxv2i32( * %p, %mask, i32 %vl) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + store %b, * %p + ret void +} + +; FIXME: select vselect.vvm and vleffN.v +define @vpselect_vleff( %passthru, * %p, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vleff: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vle32ff.v v9, (a0) +; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu +; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0 +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vleff + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v0, $x11 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x11 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v8 + ; MIR-NEXT: [[PseudoVLE32FF_V_M1_:%[0-9]+]]:vr, [[PseudoVLE32FF_V_M1_1:%[0-9]+]]:gpr = PseudoVLE32FF_V_M1 [[COPY2]], [[COPY]], 5 /* e32 */, implicit-def dead $vl + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVMERGE_VVM_M1_:%[0-9]+]]:vrnov0 = PseudoVMERGE_VVM_M1 [[COPY3]], killed [[PseudoVLE32FF_V_M1_]], $v0, [[COPY]], 5 /* e32 */ + ; MIR-NEXT: $v8 = COPY [[PseudoVMERGE_VVM_M1_]] + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call { , i64 } @llvm.riscv.vleff.nxv2i32( undef, * %p, i64 %1) + %b = extractvalue { , i64 } %a, 0 + %c = call @llvm.vp.select.nxv2i32( %m, %b, %passthru, i32 %vl) + ret %c +} + +; Test strided load by riscv.vlse +define @vpselect_vlse( %passthru, * %p, %m, i64 %s, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vlse: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a2, e32, m1, ta, mu +; CHECK-NEXT: vlse32.v v8, (a0), a1, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vlse + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v0, $x11, $x12 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x11 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY2]] + ; MIR-NEXT: [[PseudoVLSE32_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVLSE32_V_M1_MASK [[COPY4]], [[COPY3]], [[COPY1]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVLSE32_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vlse.nxv2i32( undef, * %p, i64 %s, i64 %1) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test indexed load by riscv.vluxei +define @vpselect_vluxei( %passthru, * %p, %idx, %m, i64 %s, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vluxei: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a2, e32, m1, ta, mu +; CHECK-NEXT: vluxei64.v v8, (a0), v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vluxei + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $x10, $v10m2, $v0, $x12 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x12 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:gpr = COPY $x10 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %6:vrnov0 = PseudoVLUXEI64_V_M2_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %6 + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vluxei.nxv2i32.nxv2i64( undef, * %p, %idx, i64 %1) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test vector index by riscv.vid +define @vpselect_vid( %passthru, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vid: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vid.v v8, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vid + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVID_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVID_V_M1_MASK [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVID_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vid.nxv2i32( undef, i64 %1) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test riscv.viota +define @vpselect_viota( %passthru, %m, %vm, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_viota: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: viota.m v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_viota + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v0, $v9, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY2]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVIOTA_M_M1_MASK [[COPY3]], [[COPY1]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.viota.nxv2i32( undef, %vm, i64 %1) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test riscv.vfclass +define @vpselect_vflcass( %passthru, %vf, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vflcass: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfclass.v v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vflcass + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVFCLASS_V_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVFCLASS_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVFCLASS_V_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vfclass.nxv2i32( undef, %vf, i64 %1) + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test riscv.vfsqrt +define @vpselect_vfsqrt( %passthru, %vf, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vfsqrt: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfsqrt.v v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vfsqrt + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: %4:vrnov0 = nofpexcept PseudoVFSQRT_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vfsqrt.nxv2f32( undef, %vf, i64 %1) + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test reciprocal operation by riscv.vfrec7 +define @vpselect_vfrec7( %passthru, %vf, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_vfrec7: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfrec7.v v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_vfrec7 + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: %4:vrnov0 = nofpexcept PseudoVFREC7_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %1 = zext i32 %vl to i64 + %a = call @llvm.riscv.vfrec7.nxv2f32( undef, %vf, i64 %1) + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test vector operations with VLMAX vector length. + +; Test binary operator with vp.select and add. +define @vpselect_add( %passthru, %x, %y, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_add: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_add + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: [[PseudoVADD_VV_M1_MASK:%[0-9]+]]:vrnov0 = PseudoVADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY [[PseudoVADD_VV_M1_MASK]] + ; MIR-NEXT: PseudoRET implicit $v8 + %a = add %x, %y + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test binary operator with vp.select and fadd. +define @vpselect_fadd( %passthru, %x, %y, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_fadd: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfadd.vv v8, v9, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_fadd + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY4:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: %5:vrnov0 = nofpexcept PseudoVFADD_VV_M1_MASK [[COPY4]], [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %5 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = fadd %x, %y + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test conversion by fptosi. +define @vpselect_fptosi( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_fptosi: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e16, mf2, ta, mu +; CHECK-NEXT: vfncvt.rtz.x.f.w v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_fptosi + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_RTZ_X_F_W_MF2_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 4 /* e16 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = fptosi %x to + %b = call @llvm.vp.select.nxv2i16( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test conversion by sitofp. +define @vpselect_sitofp( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_sitofp: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.x.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_sitofp + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_X_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = sitofp %x to + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test float extension by fpext. +define @vpselect_fpext( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_fpext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfwcvt.f.f.v v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_fpext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8m2, $v10, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v10 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrm2nov0 = COPY $v8m2 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrm2nov0 = nofpexcept PseudoVFWCVT_F_F_V_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8m2 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8m2 + %a = fpext %x to + %b = call @llvm.vp.select.nxv2f64( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test float truncation by fptrunc. +define @vpselect_fptrunc( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_fptrunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vfncvt.f.f.w v8, v10, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_fptrunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = nofpexcept PseudoVFNCVT_F_F_W_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1, implicit $frm + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = fptrunc %x to + %b = call @llvm.vp.select.nxv2f32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer extension by zext. +define @vpselect_zext( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_zext: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vzext.vf4 v8, v9, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_zext + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v9, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vr = COPY $v9 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVZEXT_VF4_M1_MASK [[COPY3]], [[COPY2]], $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = zext %x to + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} + +; Test integer truncation by trunc. +define @vpselect_trunc( %passthru, %x, %m, i32 zeroext %vl) { +; CHECK-LABEL: vpselect_trunc: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, a0, e32, m1, ta, mu +; CHECK-NEXT: vnsrl.wi v8, v10, 0, v0.t +; CHECK-NEXT: ret + ; MIR-LABEL: name: vpselect_trunc + ; MIR: bb.0 (%ir-block.0): + ; MIR-NEXT: liveins: $v8, $v10m2, $v0, $x10 + ; MIR-NEXT: {{ $}} + ; MIR-NEXT: [[COPY:%[0-9]+]]:gprnox0 = COPY $x10 + ; MIR-NEXT: [[COPY1:%[0-9]+]]:vr = COPY $v0 + ; MIR-NEXT: [[COPY2:%[0-9]+]]:vrm2 = COPY $v10m2 + ; MIR-NEXT: [[COPY3:%[0-9]+]]:vrnov0 = COPY $v8 + ; MIR-NEXT: $v0 = COPY [[COPY1]] + ; MIR-NEXT: early-clobber %4:vrnov0 = PseudoVNSRL_WI_M1_MASK [[COPY3]], [[COPY2]], 0, $v0, [[COPY]], 5 /* e32 */, 1 + ; MIR-NEXT: $v8 = COPY %4 + ; MIR-NEXT: PseudoRET implicit $v8 + %a = trunc %x to + %b = call @llvm.vp.select.nxv2i32( %m, %a, %passthru, i32 %vl) + ret %b +} diff --git a/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-rv32.ll b/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-rv32.ll --- a/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-rv32.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vmv.s.x-rv32.ll @@ -244,11 +244,10 @@ ; CHECK-NEXT: sw a1, 12(sp) ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: vsetvli zero, a2, e64, m1, ta, mu +; CHECK-NEXT: vid.v v9 +; CHECK-NEXT: vmseq.vi v0, v9, 0 ; CHECK-NEXT: addi a0, sp, 8 -; CHECK-NEXT: vlse64.v v9, (a0), zero -; CHECK-NEXT: vid.v v10 -; CHECK-NEXT: vmseq.vi v0, v10, 0 -; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret entry: @@ -265,11 +264,10 @@ ; CHECK-NEXT: sw a1, 12(sp) ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: vsetvli zero, a2, e64, m2, ta, mu +; CHECK-NEXT: vid.v v10 +; CHECK-NEXT: vmseq.vi v0, v10, 0 ; CHECK-NEXT: addi a0, sp, 8 -; CHECK-NEXT: vlse64.v v10, (a0), zero -; CHECK-NEXT: vid.v v12 -; CHECK-NEXT: vmseq.vi v0, v12, 0 -; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret entry: @@ -286,11 +284,10 @@ ; CHECK-NEXT: sw a1, 12(sp) ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: vsetvli zero, a2, e64, m4, ta, mu +; CHECK-NEXT: vid.v v12 +; CHECK-NEXT: vmseq.vi v0, v12, 0 ; CHECK-NEXT: addi a0, sp, 8 -; CHECK-NEXT: vlse64.v v12, (a0), zero -; CHECK-NEXT: vid.v v16 -; CHECK-NEXT: vmseq.vi v0, v16, 0 -; CHECK-NEXT: vmerge.vvm v8, v8, v12, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret entry: @@ -307,11 +304,10 @@ ; CHECK-NEXT: sw a1, 12(sp) ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: vsetvli zero, a2, e64, m8, ta, mu +; CHECK-NEXT: vid.v v16 +; CHECK-NEXT: vmseq.vi v0, v16, 0 ; CHECK-NEXT: addi a0, sp, 8 -; CHECK-NEXT: vlse64.v v16, (a0), zero -; CHECK-NEXT: vid.v v24 -; CHECK-NEXT: vmseq.vi v0, v24, 0 -; CHECK-NEXT: vmerge.vvm v8, v8, v16, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret entry: diff --git a/llvm/test/CodeGen/RISCV/rvv/vselect-int-rv32.ll b/llvm/test/CodeGen/RISCV/rvv/vselect-int-rv32.ll --- a/llvm/test/CodeGen/RISCV/rvv/vselect-int-rv32.ll +++ b/llvm/test/CodeGen/RISCV/rvv/vselect-int-rv32.ll @@ -666,8 +666,7 @@ ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetvli a1, zero, e64, m1, ta, mu -; CHECK-NEXT: vlse64.v v9, (a0), zero -; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %head = insertelement poison, i64 %b, i32 0 @@ -707,8 +706,7 @@ ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetvli a1, zero, e64, m2, ta, mu -; CHECK-NEXT: vlse64.v v10, (a0), zero -; CHECK-NEXT: vmerge.vvm v8, v8, v10, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %head = insertelement poison, i64 %b, i32 0 @@ -748,8 +746,7 @@ ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetvli a1, zero, e64, m4, ta, mu -; CHECK-NEXT: vlse64.v v12, (a0), zero -; CHECK-NEXT: vmerge.vvm v8, v8, v12, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %head = insertelement poison, i64 %b, i32 0 @@ -789,8 +786,7 @@ ; CHECK-NEXT: sw a0, 8(sp) ; CHECK-NEXT: addi a0, sp, 8 ; CHECK-NEXT: vsetvli a1, zero, e64, m8, ta, mu -; CHECK-NEXT: vlse64.v v16, (a0), zero -; CHECK-NEXT: vmerge.vvm v8, v8, v16, v0 +; CHECK-NEXT: vlse64.v v8, (a0), zero, v0.t ; CHECK-NEXT: addi sp, sp, 16 ; CHECK-NEXT: ret %head = insertelement poison, i64 %b, i32 0