[RISCV] Add merge operands to more RISCVISD::*_VL opcodes.

This adds a merge operand to all of the binary _VL nodes. Including
integer and widening. They all share multiclasses in tablegen
so doing them all at once was easiest.

I plan to use FADD_VL in an upcoming patch. The rest are just for
consistency to keep tablegen working.

This does reduce the isel table size by about 25k so that's nice.

Reviewed By: reames

Differential Revision: https://reviews.llvm.org/D130816
This commit is contained in:
Craig Topper 2022-07-30 09:58:31 -07:00
parent 9bf305fe2b
commit a23f07fb1d
3 changed files with 205 additions and 155 deletions

View File

@ -1929,8 +1929,8 @@ static SDValue lowerFROUND(SDValue Op, SelectionDAG &DAG,
DAG.getUNDEF(ContainerVT), SplatVal, VL); DAG.getUNDEF(ContainerVT), SplatVal, VL);
// Add the adjustment. // Add the adjustment.
SDValue Adjust = SDValue Adjust = DAG.getNode(RISCVISD::FADD_VL, DL, ContainerVT, Abs, Splat,
DAG.getNode(RISCVISD::FADD_VL, DL, ContainerVT, Abs, Splat, Mask, VL); DAG.getUNDEF(ContainerVT), Mask, VL);
// Truncate to integer and convert back to fp. // Truncate to integer and convert back to fp.
MVT IntVT = ContainerVT.changeVectorElementTypeToInteger(); MVT IntVT = ContainerVT.changeVectorElementTypeToInteger();
@ -2798,19 +2798,21 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
TrueMask = getAllOnesMask(HalfContainerVT, VL, DL, DAG); TrueMask = getAllOnesMask(HalfContainerVT, VL, DL, DAG);
// Widen V1 and V2 with 0s and add one copy of V2 to V1. // Widen V1 and V2 with 0s and add one copy of V2 to V1.
SDValue Add = DAG.getNode(RISCVISD::VWADDU_VL, DL, WideIntContainerVT, V1, SDValue Add =
V2, TrueMask, VL); DAG.getNode(RISCVISD::VWADDU_VL, DL, WideIntContainerVT, V1, V2,
DAG.getUNDEF(WideIntContainerVT), TrueMask, VL);
// Create 2^eltbits - 1 copies of V2 by multiplying by the largest integer. // Create 2^eltbits - 1 copies of V2 by multiplying by the largest integer.
SDValue Multiplier = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, IntHalfVT, SDValue Multiplier = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, IntHalfVT,
DAG.getUNDEF(IntHalfVT), DAG.getUNDEF(IntHalfVT),
DAG.getAllOnesConstant(DL, XLenVT)); DAG.getAllOnesConstant(DL, XLenVT));
SDValue WidenMul = DAG.getNode(RISCVISD::VWMULU_VL, DL, WideIntContainerVT, SDValue WidenMul =
V2, Multiplier, TrueMask, VL); DAG.getNode(RISCVISD::VWMULU_VL, DL, WideIntContainerVT, V2, Multiplier,
DAG.getUNDEF(WideIntContainerVT), TrueMask, VL);
// Add the new copies to our previous addition giving us 2^eltbits copies of // Add the new copies to our previous addition giving us 2^eltbits copies of
// V2. This is equivalent to shifting V2 left by eltbits. This should // V2. This is equivalent to shifting V2 left by eltbits. This should
// combine with the vwmulu.vv above to form vwmaccu.vv. // combine with the vwmulu.vv above to form vwmaccu.vv.
Add = DAG.getNode(RISCVISD::ADD_VL, DL, WideIntContainerVT, Add, WidenMul, Add = DAG.getNode(RISCVISD::ADD_VL, DL, WideIntContainerVT, Add, WidenMul,
TrueMask, VL); DAG.getUNDEF(WideIntContainerVT), TrueMask, VL);
// Cast back to ContainerVT. We need to re-create a new ContainerVT in case // Cast back to ContainerVT. We need to re-create a new ContainerVT in case
// WideIntContainerVT is a larger fractional LMUL than implied by the fixed // WideIntContainerVT is a larger fractional LMUL than implied by the fixed
// vector VT. // vector VT.
@ -3534,15 +3536,15 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
case ISD::SETCC: case ISD::SETCC:
return lowerFixedLengthVectorSetccToRVV(Op, DAG); return lowerFixedLengthVectorSetccToRVV(Op, DAG);
case ISD::ADD: case ISD::ADD:
return lowerToScalableOp(Op, DAG, RISCVISD::ADD_VL); return lowerToScalableOp(Op, DAG, RISCVISD::ADD_VL, /*HasMergeOp*/ true);
case ISD::SUB: case ISD::SUB:
return lowerToScalableOp(Op, DAG, RISCVISD::SUB_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SUB_VL, /*HasMergeOp*/ true);
case ISD::MUL: case ISD::MUL:
return lowerToScalableOp(Op, DAG, RISCVISD::MUL_VL); return lowerToScalableOp(Op, DAG, RISCVISD::MUL_VL, /*HasMergeOp*/ true);
case ISD::MULHS: case ISD::MULHS:
return lowerToScalableOp(Op, DAG, RISCVISD::MULHS_VL); return lowerToScalableOp(Op, DAG, RISCVISD::MULHS_VL, /*HasMergeOp*/ true);
case ISD::MULHU: case ISD::MULHU:
return lowerToScalableOp(Op, DAG, RISCVISD::MULHU_VL); return lowerToScalableOp(Op, DAG, RISCVISD::MULHU_VL, /*HasMergeOp*/ true);
case ISD::AND: case ISD::AND:
return lowerFixedLengthVectorLogicOpToRVV(Op, DAG, RISCVISD::VMAND_VL, return lowerFixedLengthVectorLogicOpToRVV(Op, DAG, RISCVISD::VMAND_VL,
RISCVISD::AND_VL); RISCVISD::AND_VL);
@ -3553,13 +3555,13 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
return lowerFixedLengthVectorLogicOpToRVV(Op, DAG, RISCVISD::VMXOR_VL, return lowerFixedLengthVectorLogicOpToRVV(Op, DAG, RISCVISD::VMXOR_VL,
RISCVISD::XOR_VL); RISCVISD::XOR_VL);
case ISD::SDIV: case ISD::SDIV:
return lowerToScalableOp(Op, DAG, RISCVISD::SDIV_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SDIV_VL, /*HasMergeOp*/ true);
case ISD::SREM: case ISD::SREM:
return lowerToScalableOp(Op, DAG, RISCVISD::SREM_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SREM_VL, /*HasMergeOp*/ true);
case ISD::UDIV: case ISD::UDIV:
return lowerToScalableOp(Op, DAG, RISCVISD::UDIV_VL); return lowerToScalableOp(Op, DAG, RISCVISD::UDIV_VL, /*HasMergeOp*/ true);
case ISD::UREM: case ISD::UREM:
return lowerToScalableOp(Op, DAG, RISCVISD::UREM_VL); return lowerToScalableOp(Op, DAG, RISCVISD::UREM_VL, /*HasMergeOp*/ true);
case ISD::SHL: case ISD::SHL:
case ISD::SRA: case ISD::SRA:
case ISD::SRL: case ISD::SRL:
@ -3570,21 +3572,25 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
"Unexpected custom legalisation"); "Unexpected custom legalisation");
return SDValue(); return SDValue();
case ISD::SADDSAT: case ISD::SADDSAT:
return lowerToScalableOp(Op, DAG, RISCVISD::SADDSAT_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SADDSAT_VL,
/*HasMergeOp*/ true);
case ISD::UADDSAT: case ISD::UADDSAT:
return lowerToScalableOp(Op, DAG, RISCVISD::UADDSAT_VL); return lowerToScalableOp(Op, DAG, RISCVISD::UADDSAT_VL,
/*HasMergeOp*/ true);
case ISD::SSUBSAT: case ISD::SSUBSAT:
return lowerToScalableOp(Op, DAG, RISCVISD::SSUBSAT_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SSUBSAT_VL,
/*HasMergeOp*/ true);
case ISD::USUBSAT: case ISD::USUBSAT:
return lowerToScalableOp(Op, DAG, RISCVISD::USUBSAT_VL); return lowerToScalableOp(Op, DAG, RISCVISD::USUBSAT_VL,
/*HasMergeOp*/ true);
case ISD::FADD: case ISD::FADD:
return lowerToScalableOp(Op, DAG, RISCVISD::FADD_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FADD_VL, /*HasMergeOp*/ true);
case ISD::FSUB: case ISD::FSUB:
return lowerToScalableOp(Op, DAG, RISCVISD::FSUB_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FSUB_VL, /*HasMergeOp*/ true);
case ISD::FMUL: case ISD::FMUL:
return lowerToScalableOp(Op, DAG, RISCVISD::FMUL_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FMUL_VL, /*HasMergeOp*/ true);
case ISD::FDIV: case ISD::FDIV:
return lowerToScalableOp(Op, DAG, RISCVISD::FDIV_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FDIV_VL, /*HasMergeOp*/ true);
case ISD::FNEG: case ISD::FNEG:
return lowerToScalableOp(Op, DAG, RISCVISD::FNEG_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FNEG_VL);
case ISD::FABS: case ISD::FABS:
@ -3594,17 +3600,19 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
case ISD::FMA: case ISD::FMA:
return lowerToScalableOp(Op, DAG, RISCVISD::VFMADD_VL); return lowerToScalableOp(Op, DAG, RISCVISD::VFMADD_VL);
case ISD::SMIN: case ISD::SMIN:
return lowerToScalableOp(Op, DAG, RISCVISD::SMIN_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SMIN_VL, /*HasMergeOp*/ true);
case ISD::SMAX: case ISD::SMAX:
return lowerToScalableOp(Op, DAG, RISCVISD::SMAX_VL); return lowerToScalableOp(Op, DAG, RISCVISD::SMAX_VL, /*HasMergeOp*/ true);
case ISD::UMIN: case ISD::UMIN:
return lowerToScalableOp(Op, DAG, RISCVISD::UMIN_VL); return lowerToScalableOp(Op, DAG, RISCVISD::UMIN_VL, /*HasMergeOp*/ true);
case ISD::UMAX: case ISD::UMAX:
return lowerToScalableOp(Op, DAG, RISCVISD::UMAX_VL); return lowerToScalableOp(Op, DAG, RISCVISD::UMAX_VL, /*HasMergeOp*/ true);
case ISD::FMINNUM: case ISD::FMINNUM:
return lowerToScalableOp(Op, DAG, RISCVISD::FMINNUM_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FMINNUM_VL,
/*HasMergeOp*/ true);
case ISD::FMAXNUM: case ISD::FMAXNUM:
return lowerToScalableOp(Op, DAG, RISCVISD::FMAXNUM_VL); return lowerToScalableOp(Op, DAG, RISCVISD::FMAXNUM_VL,
/*HasMergeOp*/ true);
case ISD::ABS: case ISD::ABS:
return lowerABS(Op, DAG); return lowerABS(Op, DAG);
case ISD::CTLZ_ZERO_UNDEF: case ISD::CTLZ_ZERO_UNDEF:
@ -3631,19 +3639,19 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
case ISD::VP_MERGE: case ISD::VP_MERGE:
return lowerVPOp(Op, DAG, RISCVISD::VP_MERGE_VL); return lowerVPOp(Op, DAG, RISCVISD::VP_MERGE_VL);
case ISD::VP_ADD: case ISD::VP_ADD:
return lowerVPOp(Op, DAG, RISCVISD::ADD_VL); return lowerVPOp(Op, DAG, RISCVISD::ADD_VL, /*HasMergeOp*/ true);
case ISD::VP_SUB: case ISD::VP_SUB:
return lowerVPOp(Op, DAG, RISCVISD::SUB_VL); return lowerVPOp(Op, DAG, RISCVISD::SUB_VL, /*HasMergeOp*/ true);
case ISD::VP_MUL: case ISD::VP_MUL:
return lowerVPOp(Op, DAG, RISCVISD::MUL_VL); return lowerVPOp(Op, DAG, RISCVISD::MUL_VL, /*HasMergeOp*/ true);
case ISD::VP_SDIV: case ISD::VP_SDIV:
return lowerVPOp(Op, DAG, RISCVISD::SDIV_VL); return lowerVPOp(Op, DAG, RISCVISD::SDIV_VL, /*HasMergeOp*/ true);
case ISD::VP_UDIV: case ISD::VP_UDIV:
return lowerVPOp(Op, DAG, RISCVISD::UDIV_VL); return lowerVPOp(Op, DAG, RISCVISD::UDIV_VL, /*HasMergeOp*/ true);
case ISD::VP_SREM: case ISD::VP_SREM:
return lowerVPOp(Op, DAG, RISCVISD::SREM_VL); return lowerVPOp(Op, DAG, RISCVISD::SREM_VL, /*HasMergeOp*/ true);
case ISD::VP_UREM: case ISD::VP_UREM:
return lowerVPOp(Op, DAG, RISCVISD::UREM_VL); return lowerVPOp(Op, DAG, RISCVISD::UREM_VL, /*HasMergeOp*/ true);
case ISD::VP_AND: case ISD::VP_AND:
return lowerLogicVPOp(Op, DAG, RISCVISD::VMAND_VL, RISCVISD::AND_VL); return lowerLogicVPOp(Op, DAG, RISCVISD::VMAND_VL, RISCVISD::AND_VL);
case ISD::VP_OR: case ISD::VP_OR:
@ -3651,19 +3659,19 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
case ISD::VP_XOR: case ISD::VP_XOR:
return lowerLogicVPOp(Op, DAG, RISCVISD::VMXOR_VL, RISCVISD::XOR_VL); return lowerLogicVPOp(Op, DAG, RISCVISD::VMXOR_VL, RISCVISD::XOR_VL);
case ISD::VP_ASHR: case ISD::VP_ASHR:
return lowerVPOp(Op, DAG, RISCVISD::SRA_VL); return lowerVPOp(Op, DAG, RISCVISD::SRA_VL, /*HasMergeOp*/ true);
case ISD::VP_LSHR: case ISD::VP_LSHR:
return lowerVPOp(Op, DAG, RISCVISD::SRL_VL); return lowerVPOp(Op, DAG, RISCVISD::SRL_VL, /*HasMergeOp*/ true);
case ISD::VP_SHL: case ISD::VP_SHL:
return lowerVPOp(Op, DAG, RISCVISD::SHL_VL); return lowerVPOp(Op, DAG, RISCVISD::SHL_VL, /*HasMergeOp*/ true);
case ISD::VP_FADD: case ISD::VP_FADD:
return lowerVPOp(Op, DAG, RISCVISD::FADD_VL); return lowerVPOp(Op, DAG, RISCVISD::FADD_VL, /*HasMergeOp*/ true);
case ISD::VP_FSUB: case ISD::VP_FSUB:
return lowerVPOp(Op, DAG, RISCVISD::FSUB_VL); return lowerVPOp(Op, DAG, RISCVISD::FSUB_VL, /*HasMergeOp*/ true);
case ISD::VP_FMUL: case ISD::VP_FMUL:
return lowerVPOp(Op, DAG, RISCVISD::FMUL_VL); return lowerVPOp(Op, DAG, RISCVISD::FMUL_VL, /*HasMergeOp*/ true);
case ISD::VP_FDIV: case ISD::VP_FDIV:
return lowerVPOp(Op, DAG, RISCVISD::FDIV_VL); return lowerVPOp(Op, DAG, RISCVISD::FDIV_VL, /*HasMergeOp*/ true);
case ISD::VP_FNEG: case ISD::VP_FNEG:
return lowerVPOp(Op, DAG, RISCVISD::FNEG_VL); return lowerVPOp(Op, DAG, RISCVISD::FNEG_VL);
case ISD::VP_FMA: case ISD::VP_FMA:
@ -4343,8 +4351,8 @@ SDValue RISCVTargetLowering::lowerVectorMaskTruncLike(SDValue Op,
DAG.getUNDEF(ContainerVT), SplatZero, VL); DAG.getUNDEF(ContainerVT), SplatZero, VL);
MVT MaskContainerVT = ContainerVT.changeVectorElementType(MVT::i1); MVT MaskContainerVT = ContainerVT.changeVectorElementType(MVT::i1);
SDValue Trunc = SDValue Trunc = DAG.getNode(RISCVISD::AND_VL, DL, ContainerVT, Src, SplatOne,
DAG.getNode(RISCVISD::AND_VL, DL, ContainerVT, Src, SplatOne, Mask, VL); DAG.getUNDEF(ContainerVT), Mask, VL);
Trunc = DAG.getNode(RISCVISD::SETCC_VL, DL, MaskContainerVT, Trunc, SplatZero, Trunc = DAG.getNode(RISCVISD::SETCC_VL, DL, MaskContainerVT, Trunc, SplatZero,
DAG.getCondCode(ISD::SETNE), Mask, VL); DAG.getCondCode(ISD::SETNE), Mask, VL);
if (MaskVT.isFixedLengthVector()) if (MaskVT.isFixedLengthVector())
@ -5807,8 +5815,8 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
VLMinus1, DAG.getRegister(RISCV::X0, XLenVT)); VLMinus1, DAG.getRegister(RISCV::X0, XLenVT));
SDValue VID = DAG.getNode(RISCVISD::VID_VL, DL, IntVT, Mask, VL); SDValue VID = DAG.getNode(RISCVISD::VID_VL, DL, IntVT, Mask, VL);
SDValue Indices = SDValue Indices = DAG.getNode(RISCVISD::SUB_VL, DL, IntVT, SplatVL, VID,
DAG.getNode(RISCVISD::SUB_VL, DL, IntVT, SplatVL, VID, Mask, VL); DAG.getUNDEF(IntVT), Mask, VL);
return DAG.getNode(GatherOpc, DL, VecVT, Op.getOperand(0), Indices, return DAG.getNode(GatherOpc, DL, VecVT, Op.getOperand(0), Indices,
DAG.getUNDEF(VecVT), Mask, VL); DAG.getUNDEF(VecVT), Mask, VL);
@ -6071,9 +6079,10 @@ SDValue RISCVTargetLowering::lowerFixedLengthVectorLogicOpToRVV(
MVT VT = Op.getSimpleValueType(); MVT VT = Op.getSimpleValueType();
if (VT.getVectorElementType() == MVT::i1) if (VT.getVectorElementType() == MVT::i1)
return lowerToScalableOp(Op, DAG, MaskOpc, /*HasMask*/ false); return lowerToScalableOp(Op, DAG, MaskOpc, /*HasMergeOp*/ false,
/*HasMask*/ false);
return lowerToScalableOp(Op, DAG, VecOpc, /*HasMask*/ true); return lowerToScalableOp(Op, DAG, VecOpc, /*HasMergeOp*/ true);
} }
SDValue SDValue
@ -6087,7 +6096,7 @@ RISCVTargetLowering::lowerFixedLengthVectorShiftToRVV(SDValue Op,
case ISD::SRL: Opc = RISCVISD::SRL_VL; break; case ISD::SRL: Opc = RISCVISD::SRL_VL; break;
} }
return lowerToScalableOp(Op, DAG, Opc); return lowerToScalableOp(Op, DAG, Opc, /*HasMergeOp*/ true);
} }
// Lower vector ABS to smax(X, sub(0, X)). // Lower vector ABS to smax(X, sub(0, X)).
@ -6107,10 +6116,10 @@ SDValue RISCVTargetLowering::lowerABS(SDValue Op, SelectionDAG &DAG) const {
SDValue SplatZero = DAG.getNode( SDValue SplatZero = DAG.getNode(
RISCVISD::VMV_V_X_VL, DL, ContainerVT, DAG.getUNDEF(ContainerVT), RISCVISD::VMV_V_X_VL, DL, ContainerVT, DAG.getUNDEF(ContainerVT),
DAG.getConstant(0, DL, Subtarget.getXLenVT())); DAG.getConstant(0, DL, Subtarget.getXLenVT()));
SDValue NegX = SDValue NegX = DAG.getNode(RISCVISD::SUB_VL, DL, ContainerVT, SplatZero, X,
DAG.getNode(RISCVISD::SUB_VL, DL, ContainerVT, SplatZero, X, Mask, VL); DAG.getUNDEF(ContainerVT), Mask, VL);
SDValue Max = SDValue Max = DAG.getNode(RISCVISD::SMAX_VL, DL, ContainerVT, X, NegX,
DAG.getNode(RISCVISD::SMAX_VL, DL, ContainerVT, X, NegX, Mask, VL); DAG.getUNDEF(ContainerVT), Mask, VL);
return convertFromScalableVector(VT, Max, DAG, Subtarget); return convertFromScalableVector(VT, Max, DAG, Subtarget);
} }
@ -6163,7 +6172,7 @@ SDValue RISCVTargetLowering::lowerFixedLengthVectorSelectToRVV(
} }
SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op, SelectionDAG &DAG, SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op, SelectionDAG &DAG,
unsigned NewOpc, unsigned NewOpc, bool HasMergeOp,
bool HasMask) const { bool HasMask) const {
MVT VT = Op.getSimpleValueType(); MVT VT = Op.getSimpleValueType();
MVT ContainerVT = getContainerForFixedLengthVector(VT); MVT ContainerVT = getContainerForFixedLengthVector(VT);
@ -6188,6 +6197,8 @@ SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op, SelectionDAG &DAG,
SDLoc DL(Op); SDLoc DL(Op);
SDValue Mask, VL; SDValue Mask, VL;
std::tie(Mask, VL) = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget); std::tie(Mask, VL) = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
if (HasMergeOp)
Ops.push_back(DAG.getUNDEF(ContainerVT));
if (HasMask) if (HasMask)
Ops.push_back(Mask); Ops.push_back(Mask);
Ops.push_back(VL); Ops.push_back(VL);
@ -6202,14 +6213,22 @@ SDValue RISCVTargetLowering::lowerToScalableOp(SDValue Op, SelectionDAG &DAG,
// * Fixed-length vectors are converted to their scalable-vector container // * Fixed-length vectors are converted to their scalable-vector container
// types. // types.
SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG, SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG,
unsigned RISCVISDOpc) const { unsigned RISCVISDOpc,
bool HasMergeOp) const {
SDLoc DL(Op); SDLoc DL(Op);
MVT VT = Op.getSimpleValueType(); MVT VT = Op.getSimpleValueType();
SmallVector<SDValue, 4> Ops; SmallVector<SDValue, 4> Ops;
MVT ContainerVT = VT;
if (VT.isFixedLengthVector())
ContainerVT = getContainerForFixedLengthVector(VT);
for (const auto &OpIdx : enumerate(Op->ops())) { for (const auto &OpIdx : enumerate(Op->ops())) {
SDValue V = OpIdx.value(); SDValue V = OpIdx.value();
assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!"); assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!");
// Add dummy merge value before the mask.
if (HasMergeOp && *ISD::getVPMaskIdx(Op.getOpcode()) == OpIdx.index())
Ops.push_back(DAG.getUNDEF(ContainerVT));
// Pass through operands which aren't fixed-length vectors. // Pass through operands which aren't fixed-length vectors.
if (!V.getValueType().isFixedLengthVector()) { if (!V.getValueType().isFixedLengthVector()) {
Ops.push_back(V); Ops.push_back(V);
@ -6226,8 +6245,6 @@ SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG,
if (!VT.isFixedLengthVector()) if (!VT.isFixedLengthVector())
return DAG.getNode(RISCVISDOpc, DL, VT, Ops, Op->getFlags()); return DAG.getNode(RISCVISDOpc, DL, VT, Ops, Op->getFlags());
MVT ContainerVT = getContainerForFixedLengthVector(VT);
SDValue VPOp = DAG.getNode(RISCVISDOpc, DL, ContainerVT, Ops, Op->getFlags()); SDValue VPOp = DAG.getNode(RISCVISDOpc, DL, ContainerVT, Ops, Op->getFlags());
return convertFromScalableVector(VT, VPOp, DAG, Subtarget); return convertFromScalableVector(VT, VPOp, DAG, Subtarget);
@ -6483,7 +6500,7 @@ SDValue RISCVTargetLowering::lowerLogicVPOp(SDValue Op, SelectionDAG &DAG,
unsigned VecOpc) const { unsigned VecOpc) const {
MVT VT = Op.getSimpleValueType(); MVT VT = Op.getSimpleValueType();
if (VT.getVectorElementType() != MVT::i1) if (VT.getVectorElementType() != MVT::i1)
return lowerVPOp(Op, DAG, VecOpc); return lowerVPOp(Op, DAG, VecOpc, true);
// It is safe to drop mask parameter as masked-off elements are undef. // It is safe to drop mask parameter as masked-off elements are undef.
SDValue Op1 = Op->getOperand(0); SDValue Op1 = Op->getOperand(0);
@ -7281,8 +7298,9 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
SDValue ThirtyTwoV = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT, SDValue ThirtyTwoV = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, ContainerVT,
DAG.getUNDEF(ContainerVT), DAG.getUNDEF(ContainerVT),
DAG.getConstant(32, DL, XLenVT), VL); DAG.getConstant(32, DL, XLenVT), VL);
SDValue LShr32 = DAG.getNode(RISCVISD::SRL_VL, DL, ContainerVT, Vec, SDValue LShr32 =
ThirtyTwoV, Mask, VL); DAG.getNode(RISCVISD::SRL_VL, DL, ContainerVT, Vec, ThirtyTwoV,
DAG.getUNDEF(ContainerVT), Mask, VL);
SDValue EltHi = DAG.getNode(RISCVISD::VMV_X_S, DL, XLenVT, LShr32); SDValue EltHi = DAG.getNode(RISCVISD::VMV_X_S, DL, XLenVT, LShr32);
@ -7389,8 +7407,8 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
SDValue ThirtyTwoV = SDValue ThirtyTwoV =
DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, DAG.getUNDEF(VecVT), DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VecVT, DAG.getUNDEF(VecVT),
DAG.getConstant(32, DL, XLenVT), VL); DAG.getConstant(32, DL, XLenVT), VL);
SDValue LShr32 = SDValue LShr32 = DAG.getNode(RISCVISD::SRL_VL, DL, VecVT, Vec, ThirtyTwoV,
DAG.getNode(RISCVISD::SRL_VL, DL, VecVT, Vec, ThirtyTwoV, Mask, VL); DAG.getUNDEF(VecVT), Mask, VL);
SDValue EltHi = DAG.getNode(RISCVISD::VMV_X_S, DL, XLenVT, LShr32); SDValue EltHi = DAG.getNode(RISCVISD::VMV_X_S, DL, XLenVT, LShr32);
Results.push_back( Results.push_back(
@ -8298,8 +8316,9 @@ static SDValue combineADDSUB_VLToVWADDSUB_VL(SDNode *N, SelectionDAG &DAG,
MVT NarrowVT = MVT::getVectorVT(MVT::getIntegerVT(NarrowSize), MVT NarrowVT = MVT::getVectorVT(MVT::getIntegerVT(NarrowSize),
VT.getVectorElementCount()); VT.getVectorElementCount());
SDValue Mask = N->getOperand(2); SDValue Merge = N->getOperand(2);
SDValue VL = N->getOperand(3); SDValue Mask = N->getOperand(3);
SDValue VL = N->getOperand(4);
SDLoc DL(N); SDLoc DL(N);
@ -8319,7 +8338,7 @@ static SDValue combineADDSUB_VLToVWADDSUB_VL(SDNode *N, SelectionDAG &DAG,
else else
WOpc = IsAdd ? RISCVISD::VWADDU_W_VL : RISCVISD::VWSUBU_W_VL; WOpc = IsAdd ? RISCVISD::VWADDU_W_VL : RISCVISD::VWSUBU_W_VL;
return DAG.getNode(WOpc, DL, VT, Op0, Op1, Mask, VL); return DAG.getNode(WOpc, DL, VT, Op0, Op1, Merge, Mask, VL);
} }
// FIXME: Is it useful to form a vwadd.wx or vwsub.wx if it removes a scalar // FIXME: Is it useful to form a vwadd.wx or vwsub.wx if it removes a scalar
@ -8333,8 +8352,9 @@ static SDValue combineADDSUB_VLToVWADDSUB_VL(SDNode *N, SelectionDAG &DAG,
static SDValue combineVWADD_W_VL_VWSUB_W_VL(SDNode *N, SelectionDAG &DAG) { static SDValue combineVWADD_W_VL_VWSUB_W_VL(SDNode *N, SelectionDAG &DAG) {
SDValue Op0 = N->getOperand(0); SDValue Op0 = N->getOperand(0);
SDValue Op1 = N->getOperand(1); SDValue Op1 = N->getOperand(1);
SDValue Mask = N->getOperand(2); SDValue Merge = N->getOperand(2);
SDValue VL = N->getOperand(3); SDValue Mask = N->getOperand(3);
SDValue VL = N->getOperand(4);
MVT VT = N->getSimpleValueType(0); MVT VT = N->getSimpleValueType(0);
MVT NarrowVT = Op1.getSimpleValueType(); MVT NarrowVT = Op1.getSimpleValueType();
@ -8364,7 +8384,7 @@ static SDValue combineVWADD_W_VL_VWSUB_W_VL(SDNode *N, SelectionDAG &DAG) {
// Re-introduce narrower extends if needed. // Re-introduce narrower extends if needed.
if (Op0.getValueType() != NarrowVT) if (Op0.getValueType() != NarrowVT)
Op0 = DAG.getNode(ExtOpc, DL, NarrowVT, Op0, Mask, VL); Op0 = DAG.getNode(ExtOpc, DL, NarrowVT, Op0, Mask, VL);
return DAG.getNode(VOpc, DL, VT, Op0, Op1, Mask, VL); return DAG.getNode(VOpc, DL, VT, Op0, Op1, Merge, Mask, VL);
} }
bool IsAdd = N->getOpcode() == RISCVISD::VWADD_W_VL || bool IsAdd = N->getOpcode() == RISCVISD::VWADD_W_VL ||
@ -8396,7 +8416,7 @@ static SDValue combineVWADD_W_VL_VWSUB_W_VL(SDNode *N, SelectionDAG &DAG) {
Op0 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, NarrowVT, Op0 = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, NarrowVT,
DAG.getUNDEF(NarrowVT), Op0, VL); DAG.getUNDEF(NarrowVT), Op0, VL);
return DAG.getNode(VOpc, DL, VT, Op1, Op0, Mask, VL); return DAG.getNode(VOpc, DL, VT, Op1, Op0, Merge, Mask, VL);
} }
return SDValue(); return SDValue();
@ -8418,8 +8438,9 @@ static SDValue combineMUL_VLToVWMUL_VL(SDNode *N, SelectionDAG &DAG,
if ((!IsSignExt && !IsZeroExt) || !Op0.hasOneUse()) if ((!IsSignExt && !IsZeroExt) || !Op0.hasOneUse())
return SDValue(); return SDValue();
SDValue Mask = N->getOperand(2); SDValue Merge = N->getOperand(2);
SDValue VL = N->getOperand(3); SDValue Mask = N->getOperand(3);
SDValue VL = N->getOperand(4);
// Make sure the mask and VL match. // Make sure the mask and VL match.
if (Op0.getOperand(1) != Mask || Op0.getOperand(2) != VL) if (Op0.getOperand(1) != Mask || Op0.getOperand(2) != VL)
@ -8497,7 +8518,7 @@ static SDValue combineMUL_VLToVWMUL_VL(SDNode *N, SelectionDAG &DAG,
unsigned WMulOpc = RISCVISD::VWMULSU_VL; unsigned WMulOpc = RISCVISD::VWMULSU_VL;
if (!IsVWMULSU) if (!IsVWMULSU)
WMulOpc = IsSignExt ? RISCVISD::VWMUL_VL : RISCVISD::VWMULU_VL; WMulOpc = IsSignExt ? RISCVISD::VWMUL_VL : RISCVISD::VWMULU_VL;
return DAG.getNode(WMulOpc, DL, VT, Op0, Op1, Mask, VL); return DAG.getNode(WMulOpc, DL, VT, Op0, Op1, Merge, Mask, VL);
} }
static RISCVFPRndMode::RoundingMode matchRoundingOp(SDValue Op) { static RISCVFPRndMode::RoundingMode matchRoundingOp(SDValue Op) {
@ -9230,7 +9251,7 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
ShAmt = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, DAG.getUNDEF(VT), ShAmt = DAG.getNode(RISCVISD::VMV_V_X_VL, DL, VT, DAG.getUNDEF(VT),
ShAmt.getOperand(1), VL); ShAmt.getOperand(1), VL);
return DAG.getNode(N->getOpcode(), DL, VT, N->getOperand(0), ShAmt, return DAG.getNode(N->getOpcode(), DL, VT, N->getOperand(0), ShAmt,
N->getOperand(2), N->getOperand(3)); N->getOperand(2), N->getOperand(3), N->getOperand(4));
} }
break; break;
} }

View File

@ -213,9 +213,8 @@ enum NodeType : unsigned {
VECREDUCE_FMIN_VL, VECREDUCE_FMIN_VL,
VECREDUCE_FMAX_VL, VECREDUCE_FMAX_VL,
// Vector binary and unary ops with a mask as a third operand, and VL as a // Vector binary ops with a merge as a third operand, a mask as a fourth
// fourth operand. // operand, and VL as a fifth operand.
// FIXME: Can we replace these with ISD::VP_*?
ADD_VL, ADD_VL,
AND_VL, AND_VL,
MUL_VL, MUL_VL,
@ -229,32 +228,30 @@ enum NodeType : unsigned {
UDIV_VL, UDIV_VL,
UREM_VL, UREM_VL,
XOR_VL, XOR_VL,
SMIN_VL,
SMAX_VL,
UMIN_VL,
UMAX_VL,
SADDSAT_VL, SADDSAT_VL,
UADDSAT_VL, UADDSAT_VL,
SSUBSAT_VL, SSUBSAT_VL,
USUBSAT_VL, USUBSAT_VL,
MULHS_VL,
MULHU_VL,
FADD_VL, FADD_VL,
FSUB_VL, FSUB_VL,
FMUL_VL, FMUL_VL,
FDIV_VL, FDIV_VL,
FMINNUM_VL,
FMAXNUM_VL,
// Vector unary ops with a mask as a second operand and VL as a third operand.
FNEG_VL, FNEG_VL,
FABS_VL, FABS_VL,
FSQRT_VL, FSQRT_VL,
VFMADD_VL,
VFNMADD_VL,
VFMSUB_VL,
VFNMSUB_VL,
FCOPYSIGN_VL, FCOPYSIGN_VL,
SMIN_VL,
SMAX_VL,
UMIN_VL,
UMAX_VL,
FMINNUM_VL,
FMAXNUM_VL,
MULHS_VL,
MULHU_VL,
FP_TO_SINT_VL, FP_TO_SINT_VL,
FP_TO_UINT_VL, FP_TO_UINT_VL,
SINT_TO_FP_VL, SINT_TO_FP_VL,
@ -262,7 +259,14 @@ enum NodeType : unsigned {
FP_ROUND_VL, FP_ROUND_VL,
FP_EXTEND_VL, FP_EXTEND_VL,
// Widening instructions // Vector FMA ops with a mask as a fourth operand and VL as a fifth operand.
VFMADD_VL,
VFNMADD_VL,
VFMSUB_VL,
VFNMSUB_VL,
// Widening instructions with a merge value a third operand, a mask as a
// fourth operand, and VL as a fifth operand.
VWMUL_VL, VWMUL_VL,
VWMULU_VL, VWMULU_VL,
VWMULSU_VL, VWMULSU_VL,
@ -679,8 +683,9 @@ private:
SDValue lowerFixedLengthVectorSelectToRVV(SDValue Op, SDValue lowerFixedLengthVectorSelectToRVV(SDValue Op,
SelectionDAG &DAG) const; SelectionDAG &DAG) const;
SDValue lowerToScalableOp(SDValue Op, SelectionDAG &DAG, unsigned NewOpc, SDValue lowerToScalableOp(SDValue Op, SelectionDAG &DAG, unsigned NewOpc,
bool HasMask = true) const; bool HasMergeOp = false, bool HasMask = true) const;
SDValue lowerVPOp(SDValue Op, SelectionDAG &DAG, unsigned RISCVISDOpc) const; SDValue lowerVPOp(SDValue Op, SelectionDAG &DAG, unsigned RISCVISDOpc,
bool HasMergeOp = false) const;
SDValue lowerLogicVPOp(SDValue Op, SelectionDAG &DAG, unsigned MaskOpc, SDValue lowerLogicVPOp(SDValue Op, SelectionDAG &DAG, unsigned MaskOpc,
unsigned VecOpc) const; unsigned VecOpc) const;
SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const; SDValue lowerVPExtMaskOp(SDValue Op, SelectionDAG &DAG) const;

View File

@ -21,24 +21,26 @@
// Helpers to define the VL patterns. // Helpers to define the VL patterns.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
def SDT_RISCVIntBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, def SDT_RISCVIntBinOp_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>, SDTCisSameAs<0, 2>,
SDTCisVec<0>, SDTCisInt<0>, SDTCisVec<0>, SDTCisInt<0>,
SDTCVecEltisVT<3, i1>, SDTCisSameAs<0, 3>,
SDTCisSameNumEltsAs<0, 3>, SDTCVecEltisVT<4, i1>,
SDTCisVT<4, XLenVT>]>; SDTCisSameNumEltsAs<0, 4>,
SDTCisVT<5, XLenVT>]>;
def SDT_RISCVFPUnOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, def SDT_RISCVFPUnOp_VL : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>,
SDTCisVec<0>, SDTCisFP<0>, SDTCisVec<0>, SDTCisFP<0>,
SDTCVecEltisVT<2, i1>, SDTCVecEltisVT<2, i1>,
SDTCisSameNumEltsAs<0, 2>, SDTCisSameNumEltsAs<0, 2>,
SDTCisVT<3, XLenVT>]>; SDTCisVT<3, XLenVT>]>;
def SDT_RISCVFPBinOp_VL : SDTypeProfile<1, 4, [SDTCisSameAs<0, 1>, def SDT_RISCVFPBinOp_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>, SDTCisSameAs<0, 2>,
SDTCisVec<0>, SDTCisFP<0>, SDTCisVec<0>, SDTCisFP<0>,
SDTCVecEltisVT<3, i1>, SDTCisSameAs<0, 3>,
SDTCisSameNumEltsAs<0, 3>, SDTCVecEltisVT<4, i1>,
SDTCisVT<4, XLenVT>]>; SDTCisSameNumEltsAs<0, 4>,
SDTCisVT<5, XLenVT>]>;
def SDT_RISCVCopySign_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>, def SDT_RISCVCopySign_VL : SDTypeProfile<1, 5, [SDTCisSameAs<0, 1>,
SDTCisSameAs<0, 2>, SDTCisSameAs<0, 2>,
@ -230,12 +232,13 @@ def riscv_trunc_vector_vl : SDNode<"RISCVISD::TRUNCATE_VECTOR_VL",
SDTCVecEltisVT<2, i1>, SDTCVecEltisVT<2, i1>,
SDTCisVT<3, XLenVT>]>>; SDTCisVT<3, XLenVT>]>>;
def SDT_RISCVVWBinOp_VL : SDTypeProfile<1, 4, [SDTCisVec<0>, def SDT_RISCVVWBinOp_VL : SDTypeProfile<1, 5, [SDTCisVec<0>,
SDTCisSameNumEltsAs<0, 1>, SDTCisSameNumEltsAs<0, 1>,
SDTCisSameAs<1, 2>, SDTCisSameAs<1, 2>,
SDTCisSameNumEltsAs<1, 3>, SDTCisSameAs<0, 3>,
SDTCVecEltisVT<3, i1>, SDTCisSameNumEltsAs<1, 4>,
SDTCisVT<4, XLenVT>]>; SDTCVecEltisVT<4, i1>,
SDTCisVT<5, XLenVT>]>;
def riscv_vwmul_vl : SDNode<"RISCVISD::VWMUL_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>; def riscv_vwmul_vl : SDNode<"RISCVISD::VWMUL_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>;
def riscv_vwmulu_vl : SDNode<"RISCVISD::VWMULU_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>; def riscv_vwmulu_vl : SDNode<"RISCVISD::VWMULU_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>;
def riscv_vwmulsu_vl : SDNode<"RISCVISD::VWMULSU_VL", SDT_RISCVVWBinOp_VL>; def riscv_vwmulsu_vl : SDNode<"RISCVISD::VWMULSU_VL", SDT_RISCVVWBinOp_VL>;
@ -244,13 +247,14 @@ def riscv_vwaddu_vl : SDNode<"RISCVISD::VWADDU_VL", SDT_RISCVVWBinOp_VL, [SDNPCo
def riscv_vwsub_vl : SDNode<"RISCVISD::VWSUB_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>; def riscv_vwsub_vl : SDNode<"RISCVISD::VWSUB_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>;
def riscv_vwsubu_vl : SDNode<"RISCVISD::VWSUBU_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>; def riscv_vwsubu_vl : SDNode<"RISCVISD::VWSUBU_VL", SDT_RISCVVWBinOp_VL, [SDNPCommutative]>;
def SDT_RISCVVWBinOpW_VL : SDTypeProfile<1, 4, [SDTCisVec<0>, def SDT_RISCVVWBinOpW_VL : SDTypeProfile<1, 5, [SDTCisVec<0>,
SDTCisSameAs<0, 1>, SDTCisSameAs<0, 1>,
SDTCisSameNumEltsAs<1, 2>, SDTCisSameNumEltsAs<1, 2>,
SDTCisOpSmallerThanOp<2, 1>, SDTCisOpSmallerThanOp<2, 1>,
SDTCisSameNumEltsAs<1, 3>, SDTCisSameAs<0, 3>,
SDTCVecEltisVT<3, i1>, SDTCisSameNumEltsAs<1, 4>,
SDTCisVT<4, XLenVT>]>; SDTCVecEltisVT<4, i1>,
SDTCisVT<5, XLenVT>]>;
def riscv_vwadd_w_vl : SDNode<"RISCVISD::VWADD_W_VL", SDT_RISCVVWBinOpW_VL>; def riscv_vwadd_w_vl : SDNode<"RISCVISD::VWADD_W_VL", SDT_RISCVVWBinOpW_VL>;
def riscv_vwaddu_w_vl : SDNode<"RISCVISD::VWADDU_W_VL", SDT_RISCVVWBinOpW_VL>; def riscv_vwaddu_w_vl : SDNode<"RISCVISD::VWADDU_W_VL", SDT_RISCVVWBinOpW_VL>;
def riscv_vwsub_w_vl : SDNode<"RISCVISD::VWSUB_W_VL", SDT_RISCVVWBinOpW_VL>; def riscv_vwsub_w_vl : SDNode<"RISCVISD::VWSUB_W_VL", SDT_RISCVVWBinOpW_VL>;
@ -261,27 +265,31 @@ def SDTRVVVecReduce : SDTypeProfile<1, 5, [
SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<2, 4>, SDTCisVT<5, XLenVT> SDTCVecEltisVT<4, i1>, SDTCisSameNumEltsAs<2, 4>, SDTCisVT<5, XLenVT>
]>; ]>;
def riscv_mul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D), def riscv_mul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
node:$E),
(riscv_mul_vl node:$A, node:$B, node:$C, (riscv_mul_vl node:$A, node:$B, node:$C,
node:$D), [{ node:$D, node:$E), [{
return N->hasOneUse(); return N->hasOneUse();
}]>; }]>;
def riscv_vwmul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D), def riscv_vwmul_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
node:$E),
(riscv_vwmul_vl node:$A, node:$B, node:$C, (riscv_vwmul_vl node:$A, node:$B, node:$C,
node:$D), [{ node:$D, node:$E), [{
return N->hasOneUse(); return N->hasOneUse();
}]>; }]>;
def riscv_vwmulu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D), def riscv_vwmulu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
node:$E),
(riscv_vwmulu_vl node:$A, node:$B, node:$C, (riscv_vwmulu_vl node:$A, node:$B, node:$C,
node:$D), [{ node:$D, node:$E), [{
return N->hasOneUse(); return N->hasOneUse();
}]>; }]>;
def riscv_vwmulsu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D), def riscv_vwmulsu_vl_oneuse : PatFrag<(ops node:$A, node:$B, node:$C, node:$D,
node:$E),
(riscv_vwmulsu_vl node:$A, node:$B, node:$C, (riscv_vwmulsu_vl node:$A, node:$B, node:$C,
node:$D), [{ node:$D, node:$E), [{
return N->hasOneUse(); return N->hasOneUse();
}]>; }]>;
@ -331,15 +339,17 @@ multiclass VPatBinaryVL_V<SDNode vop,
ValueType mask_type, ValueType mask_type,
int sew, int sew,
LMULInfo vlmul, LMULInfo vlmul,
VReg result_reg_class,
VReg op1_reg_class, VReg op1_reg_class,
VReg op2_reg_class> { VReg op2_reg_class> {
def : Pat<(result_type (vop def : Pat<(result_type (vop
(op1_type op1_reg_class:$rs1), (op1_type op1_reg_class:$rs1),
(op2_type op2_reg_class:$rs2), (op2_type op2_reg_class:$rs2),
(result_type result_reg_class:$merge),
(mask_type V0), (mask_type V0),
VLOpFrag)), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_MASK") (!cast<Instruction>(instruction_name#"_"#suffix#"_"# vlmul.MX#"_MASK")
(result_type (IMPLICIT_DEF)), result_reg_class:$merge,
op1_reg_class:$rs1, op1_reg_class:$rs1,
op2_reg_class:$rs2, op2_reg_class:$rs2,
(mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>; (mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>;
@ -354,16 +364,18 @@ multiclass VPatBinaryVL_XI<SDNode vop,
ValueType mask_type, ValueType mask_type,
int sew, int sew,
LMULInfo vlmul, LMULInfo vlmul,
VReg result_reg_class,
VReg vop_reg_class, VReg vop_reg_class,
ComplexPattern SplatPatKind, ComplexPattern SplatPatKind,
DAGOperand xop_kind> { DAGOperand xop_kind> {
def : Pat<(result_type (vop def : Pat<(result_type (vop
(vop1_type vop_reg_class:$rs1), (vop1_type vop_reg_class:$rs1),
(vop2_type (SplatPatKind (XLenVT xop_kind:$rs2))), (vop2_type (SplatPatKind (XLenVT xop_kind:$rs2))),
(result_type result_reg_class:$merge),
(mask_type V0), (mask_type V0),
VLOpFrag)), VLOpFrag)),
(!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX#"_MASK") (!cast<Instruction>(instruction_name#_#suffix#_# vlmul.MX#"_MASK")
(result_type (IMPLICIT_DEF)), result_reg_class:$merge,
vop_reg_class:$rs1, vop_reg_class:$rs1,
xop_kind:$rs2, xop_kind:$rs2,
(mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>; (mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>;
@ -373,10 +385,12 @@ multiclass VPatBinaryVL_VV_VX<SDNode vop, string instruction_name> {
foreach vti = AllIntegerVectors in { foreach vti = AllIntegerVectors in {
defm : VPatBinaryVL_V<vop, instruction_name, "VV", defm : VPatBinaryVL_V<vop, instruction_name, "VV",
vti.Vector, vti.Vector, vti.Vector, vti.Mask, vti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass,
vti.RegClass>;
defm : VPatBinaryVL_XI<vop, instruction_name, "VX", defm : VPatBinaryVL_XI<vop, instruction_name, "VX",
vti.Vector, vti.Vector, vti.Vector, vti.Mask, vti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, SplatPat, GPR>; vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass,
SplatPat, GPR>;
} }
} }
@ -386,7 +400,7 @@ multiclass VPatBinaryVL_VV_VX_VI<SDNode vop, string instruction_name,
foreach vti = AllIntegerVectors in { foreach vti = AllIntegerVectors in {
defm : VPatBinaryVL_XI<vop, instruction_name, "VI", defm : VPatBinaryVL_XI<vop, instruction_name, "VI",
vti.Vector, vti.Vector, vti.Vector, vti.Mask, vti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass,
!cast<ComplexPattern>(SplatPat#_#ImmType), !cast<ComplexPattern>(SplatPat#_#ImmType),
ImmType>; ImmType>;
} }
@ -398,10 +412,12 @@ multiclass VPatBinaryWVL_VV_VX<SDNode vop, string instruction_name> {
defvar wti = VtiToWti.Wti; defvar wti = VtiToWti.Wti;
defm : VPatBinaryVL_V<vop, instruction_name, "VV", defm : VPatBinaryVL_V<vop, instruction_name, "VV",
wti.Vector, vti.Vector, vti.Vector, vti.Mask, wti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass,
vti.RegClass>;
defm : VPatBinaryVL_XI<vop, instruction_name, "VX", defm : VPatBinaryVL_XI<vop, instruction_name, "VX",
wti.Vector, vti.Vector, vti.Vector, vti.Mask, wti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, SplatPat, GPR>; vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass,
SplatPat, GPR>;
} }
} }
multiclass VPatBinaryWVL_VV_VX_WV_WX<SDNode vop, SDNode vop_w, multiclass VPatBinaryWVL_VV_VX_WV_WX<SDNode vop, SDNode vop_w,
@ -412,10 +428,12 @@ multiclass VPatBinaryWVL_VV_VX_WV_WX<SDNode vop, SDNode vop_w,
defvar wti = VtiToWti.Wti; defvar wti = VtiToWti.Wti;
defm : VPatBinaryVL_V<vop_w, instruction_name, "WV", defm : VPatBinaryVL_V<vop_w, instruction_name, "WV",
wti.Vector, wti.Vector, vti.Vector, vti.Mask, wti.Vector, wti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, wti.RegClass, vti.RegClass>; vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass,
vti.RegClass>;
defm : VPatBinaryVL_XI<vop_w, instruction_name, "WX", defm : VPatBinaryVL_XI<vop_w, instruction_name, "WX",
wti.Vector, wti.Vector, vti.Vector, vti.Mask, wti.Vector, wti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, wti.RegClass, SplatPat, GPR>; vti.Log2SEW, vti.LMul, wti.RegClass, wti.RegClass,
SplatPat, GPR>;
} }
} }
@ -426,14 +444,16 @@ multiclass VPatBinaryVL_VF<SDNode vop,
ValueType mask_type, ValueType mask_type,
int sew, int sew,
LMULInfo vlmul, LMULInfo vlmul,
VReg result_reg_class,
VReg vop_reg_class, VReg vop_reg_class,
RegisterClass scalar_reg_class> { RegisterClass scalar_reg_class> {
def : Pat<(result_type (vop (vop_type vop_reg_class:$rs1), def : Pat<(result_type (vop (vop_type vop_reg_class:$rs1),
(vop_type (SplatFPOp scalar_reg_class:$rs2)), (vop_type (SplatFPOp scalar_reg_class:$rs2)),
(result_type result_reg_class:$merge),
(mask_type V0), (mask_type V0),
VLOpFrag)), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_"#vlmul.MX#"_MASK") (!cast<Instruction>(instruction_name#"_"#vlmul.MX#"_MASK")
(result_type (IMPLICIT_DEF)), result_reg_class:$merge,
vop_reg_class:$rs1, vop_reg_class:$rs1,
scalar_reg_class:$rs2, scalar_reg_class:$rs2,
(mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>; (mask_type V0), GPR:$vl, sew, TAIL_AGNOSTIC)>;
@ -443,10 +463,12 @@ multiclass VPatBinaryFPVL_VV_VF<SDNode vop, string instruction_name> {
foreach vti = AllFloatVectors in { foreach vti = AllFloatVectors in {
defm : VPatBinaryVL_V<vop, instruction_name, "VV", defm : VPatBinaryVL_V<vop, instruction_name, "VV",
vti.Vector, vti.Vector, vti.Vector, vti.Mask, vti.Vector, vti.Vector, vti.Vector, vti.Mask,
vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass>; vti.Log2SEW, vti.LMul, vti.RegClass, vti.RegClass,
vti.RegClass>;
defm : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix, defm : VPatBinaryVL_VF<vop, instruction_name#"_V"#vti.ScalarSuffix,
vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW, vti.Vector, vti.Vector, vti.Mask, vti.Log2SEW,
vti.LMul, vti.RegClass, vti.ScalarRegClass>; vti.LMul, vti.RegClass, vti.RegClass,
vti.ScalarRegClass>;
} }
} }
@ -454,10 +476,11 @@ multiclass VPatBinaryFPVL_R_VF<SDNode vop, string instruction_name> {
foreach fvti = AllFloatVectors in { foreach fvti = AllFloatVectors in {
def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2), def : Pat<(fvti.Vector (vop (SplatFPOp fvti.ScalarRegClass:$rs2),
fvti.RegClass:$rs1, fvti.RegClass:$rs1,
(fvti.Vector fvti.RegClass:$merge),
(fvti.Mask V0), (fvti.Mask V0),
VLOpFrag)), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK") (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX#"_MASK")
(fvti.Vector (IMPLICIT_DEF)), fvti.RegClass:$merge,
fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2, fvti.RegClass:$rs1, fvti.ScalarRegClass:$rs2,
(fvti.Mask V0), GPR:$vl, fvti.Log2SEW, TAIL_AGNOSTIC)>; (fvti.Mask V0), GPR:$vl, fvti.Log2SEW, TAIL_AGNOSTIC)>;
} }
@ -786,7 +809,7 @@ multiclass VPatWidenBinaryFPVL_VV_VF<SDNode op, PatFrags extop, string instructi
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Vector (extop (fvti.Vector fvti.RegClass:$rs1), (fwti.Vector (extop (fvti.Vector fvti.RegClass:$rs1),
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Mask true_mask), VLOpFrag)), srcvalue, (fwti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_VV_"#fvti.LMul.MX) (!cast<Instruction>(instruction_name#"_VV_"#fvti.LMul.MX)
fvti.RegClass:$rs2, fvti.RegClass:$rs1, fvti.RegClass:$rs2, fvti.RegClass:$rs1,
GPR:$vl, fvti.Log2SEW)>; GPR:$vl, fvti.Log2SEW)>;
@ -794,7 +817,7 @@ multiclass VPatWidenBinaryFPVL_VV_VF<SDNode op, PatFrags extop, string instructi
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Vector (extop (fvti.Vector (SplatFPOp fvti.ScalarRegClass:$rs1)), (fwti.Vector (extop (fvti.Vector (SplatFPOp fvti.ScalarRegClass:$rs1)),
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Mask true_mask), VLOpFrag)), srcvalue, (fwti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) (!cast<Instruction>(instruction_name#"_V"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
fvti.RegClass:$rs2, fvti.ScalarRegClass:$rs1, fvti.RegClass:$rs2, fvti.ScalarRegClass:$rs1,
GPR:$vl, fvti.Log2SEW)>; GPR:$vl, fvti.Log2SEW)>;
@ -808,14 +831,14 @@ multiclass VPatWidenBinaryFPVL_WV_WF<SDNode op, PatFrags extop, string instructi
def : Pat<(fwti.Vector (op (fwti.Vector fwti.RegClass:$rs2), def : Pat<(fwti.Vector (op (fwti.Vector fwti.RegClass:$rs2),
(fwti.Vector (extop (fvti.Vector fvti.RegClass:$rs1), (fwti.Vector (extop (fvti.Vector fvti.RegClass:$rs1),
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Mask true_mask), VLOpFrag)), srcvalue, (fwti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_WV_"#fvti.LMul.MX) (!cast<Instruction>(instruction_name#"_WV_"#fvti.LMul.MX)
fwti.RegClass:$rs2, fvti.RegClass:$rs1, fwti.RegClass:$rs2, fvti.RegClass:$rs1,
GPR:$vl, fvti.Log2SEW)>; GPR:$vl, fvti.Log2SEW)>;
def : Pat<(fwti.Vector (op (fwti.Vector fwti.RegClass:$rs2), def : Pat<(fwti.Vector (op (fwti.Vector fwti.RegClass:$rs2),
(fwti.Vector (extop (fvti.Vector (SplatFPOp fvti.ScalarRegClass:$rs1)), (fwti.Vector (extop (fvti.Vector (SplatFPOp fvti.ScalarRegClass:$rs1)),
(fvti.Mask true_mask), VLOpFrag)), (fvti.Mask true_mask), VLOpFrag)),
(fwti.Mask true_mask), VLOpFrag)), srcvalue, (fwti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_W"#fvti.ScalarSuffix#"_"#fvti.LMul.MX) (!cast<Instruction>(instruction_name#"_W"#fvti.ScalarSuffix#"_"#fvti.LMul.MX)
fwti.RegClass:$rs2, fvti.ScalarRegClass:$rs1, fwti.RegClass:$rs2, fvti.ScalarRegClass:$rs1,
GPR:$vl, fvti.Log2SEW)>; GPR:$vl, fvti.Log2SEW)>;
@ -837,7 +860,7 @@ multiclass VPatNarrowShiftSplatExt_WX<SDNode op, PatFrags extop, string instruct
(op (wti.Vector wti.RegClass:$rs2), (op (wti.Vector wti.RegClass:$rs2),
(wti.Vector (extop (vti.Vector (SplatPat GPR:$rs1)), (wti.Vector (extop (vti.Vector (SplatPat GPR:$rs1)),
(vti.Mask true_mask), VLOpFrag)), (vti.Mask true_mask), VLOpFrag)),
(wti.Mask true_mask), VLOpFrag), srcvalue, (wti.Mask true_mask), VLOpFrag),
(vti.Mask true_mask), VLOpFrag)), (vti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX)
wti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW)>; wti.RegClass:$rs2, GPR:$rs1, GPR:$vl, vti.Log2SEW)>;
@ -853,8 +876,8 @@ multiclass VPatMultiplyAddVL_VV_VX<SDNode op, string instruction_name> {
(op vti.RegClass:$rs2, (op vti.RegClass:$rs2,
(riscv_mul_vl_oneuse vti.RegClass:$rs1, (riscv_mul_vl_oneuse vti.RegClass:$rs1,
vti.RegClass:$rd, vti.RegClass:$rd,
(vti.Mask true_mask), VLOpFrag), srcvalue, (vti.Mask true_mask), VLOpFrag),
(vti.Mask true_mask), VLOpFrag)), srcvalue, (vti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_VV_"# suffix) (!cast<Instruction>(instruction_name#"_VV_"# suffix)
vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, vti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
@ -864,8 +887,8 @@ multiclass VPatMultiplyAddVL_VV_VX<SDNode op, string instruction_name> {
(op vti.RegClass:$rs2, (op vti.RegClass:$rs2,
(riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1), (riscv_mul_vl_oneuse (SplatPat XLenVT:$rs1),
vti.RegClass:$rd, vti.RegClass:$rd,
(vti.Mask true_mask), VLOpFrag), srcvalue, (vti.Mask true_mask), VLOpFrag),
(vti.Mask true_mask), VLOpFrag)), srcvalue, (vti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_VX_" # suffix) (!cast<Instruction>(instruction_name#"_VX_" # suffix)
vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, vti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
@ -880,8 +903,8 @@ multiclass VPatWidenMultiplyAddVL_VV_VX<PatFrag op1, string instruction_name> {
(riscv_add_vl wti.RegClass:$rd, (riscv_add_vl wti.RegClass:$rd,
(op1 vti.RegClass:$rs1, (op1 vti.RegClass:$rs1,
(vti.Vector vti.RegClass:$rs2), (vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), VLOpFrag), srcvalue, (vti.Mask true_mask), VLOpFrag),
(vti.Mask true_mask), VLOpFrag)), srcvalue, (vti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_VV_" # vti.LMul.MX) (!cast<Instruction>(instruction_name#"_VV_" # vti.LMul.MX)
wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2, wti.RegClass:$rd, vti.RegClass:$rs1, vti.RegClass:$rs2,
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
@ -889,8 +912,8 @@ multiclass VPatWidenMultiplyAddVL_VV_VX<PatFrag op1, string instruction_name> {
(riscv_add_vl wti.RegClass:$rd, (riscv_add_vl wti.RegClass:$rd,
(op1 (SplatPat XLenVT:$rs1), (op1 (SplatPat XLenVT:$rs1),
(vti.Vector vti.RegClass:$rs2), (vti.Vector vti.RegClass:$rs2),
(vti.Mask true_mask), VLOpFrag), srcvalue, (vti.Mask true_mask), VLOpFrag),
(vti.Mask true_mask), VLOpFrag)), srcvalue, (vti.Mask true_mask), VLOpFrag)),
(!cast<Instruction>(instruction_name#"_VX_" # vti.LMul.MX) (!cast<Instruction>(instruction_name#"_VX_" # vti.LMul.MX)
wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2, wti.RegClass:$rd, vti.ScalarRegClass:$rs1, vti.RegClass:$rs2,
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
@ -903,12 +926,12 @@ multiclass VPatNarrowShiftSplat_WX_WI<SDNode op, string instruction_name> {
defvar wti = vtiTowti.Wti; defvar wti = vtiTowti.Wti;
def : Pat<(vti.Vector (riscv_trunc_vector_vl def : Pat<(vti.Vector (riscv_trunc_vector_vl
(wti.Vector (op wti.RegClass:$rs1, (SplatPat XLenVT:$rs2), (wti.Vector (op wti.RegClass:$rs1, (SplatPat XLenVT:$rs2),
true_mask, VLOpFrag)), true_mask, VLOpFrag)), srcvalue, true_mask, VLOpFrag)), true_mask, VLOpFrag)),
(!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX) (!cast<Instruction>(instruction_name#"_WX_"#vti.LMul.MX)
wti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>; wti.RegClass:$rs1, GPR:$rs2, GPR:$vl, vti.Log2SEW)>;
def : Pat<(vti.Vector (riscv_trunc_vector_vl def : Pat<(vti.Vector (riscv_trunc_vector_vl
(wti.Vector (op wti.RegClass:$rs1, (SplatPat_uimm5 uimm5:$rs2), (wti.Vector (op wti.RegClass:$rs1, (SplatPat_uimm5 uimm5:$rs2),
true_mask, VLOpFrag)), true_mask, VLOpFrag)), srcvalue, true_mask, VLOpFrag)), true_mask, VLOpFrag)),
(!cast<Instruction>(instruction_name#"_WI_"#vti.LMul.MX) (!cast<Instruction>(instruction_name#"_WI_"#vti.LMul.MX)
wti.RegClass:$rs1, uimm5:$rs2, GPR:$vl, vti.Log2SEW)>; wti.RegClass:$rs1, uimm5:$rs2, GPR:$vl, vti.Log2SEW)>;
} }
@ -991,16 +1014,16 @@ defm : VPatBinaryVL_VV_VX<riscv_sub_vl, "PseudoVSUB">;
// pattern operands // pattern operands
foreach vti = AllIntegerVectors in { foreach vti = AllIntegerVectors in {
def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))), def : Pat<(riscv_sub_vl (vti.Vector (SplatPat (XLenVT GPR:$rs2))),
(vti.Vector vti.RegClass:$rs1), (vti.Mask V0), (vti.Vector vti.RegClass:$rs1),
VLOpFrag), vti.RegClass:$merge, (vti.Mask V0), VLOpFrag),
(!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX#"_MASK") (!cast<Instruction>("PseudoVRSUB_VX_"# vti.LMul.MX#"_MASK")
(vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, GPR:$rs2, vti.RegClass:$merge, vti.RegClass:$rs1, GPR:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)), def : Pat<(riscv_sub_vl (vti.Vector (SplatPat_simm5 simm5:$rs2)),
(vti.Vector vti.RegClass:$rs1), (vti.Mask V0), (vti.Vector vti.RegClass:$rs1),
VLOpFrag), vti.RegClass:$merge, (vti.Mask V0), VLOpFrag),
(!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX#"_MASK") (!cast<Instruction>("PseudoVRSUB_VI_"# vti.LMul.MX#"_MASK")
(vti.Vector (IMPLICIT_DEF)), vti.RegClass:$rs1, simm5:$rs2, vti.RegClass:$merge, vti.RegClass:$rs1, simm5:$rs2,
(vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; (vti.Mask V0), GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;
} }
@ -1038,8 +1061,7 @@ foreach vti = AllIntegerVectors in {
// Emit shift by 1 as an add since it might be faster. // Emit shift by 1 as an add since it might be faster.
def : Pat<(riscv_shl_vl (vti.Vector vti.RegClass:$rs1), def : Pat<(riscv_shl_vl (vti.Vector vti.RegClass:$rs1),
(riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)), (riscv_vmv_v_x_vl (vti.Vector undef), 1, (XLenVT srcvalue)),
(vti.Mask true_mask), srcvalue, (vti.Mask true_mask), VLOpFrag),
VLOpFrag),
(!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX) (!cast<Instruction>("PseudoVADD_VV_"# vti.LMul.MX)
vti.RegClass:$rs1, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>; vti.RegClass:$rs1, vti.RegClass:$rs1, GPR:$vl, vti.Log2SEW)>;
} }
@ -1140,8 +1162,10 @@ foreach vtiTowti = AllWidenableIntVectors in {
(riscv_add_vl wti.RegClass:$rd, (riscv_add_vl wti.RegClass:$rd,
(riscv_vwmulsu_vl_oneuse (vti.Vector vti.RegClass:$rs1), (riscv_vwmulsu_vl_oneuse (vti.Vector vti.RegClass:$rs1),
(SplatPat XLenVT:$rs2), (SplatPat XLenVT:$rs2),
(vti.Mask true_mask), VLOpFrag), srcvalue,
(vti.Mask true_mask), VLOpFrag)), (vti.Mask true_mask),
VLOpFrag),
srcvalue, (vti.Mask true_mask),VLOpFrag)),
(!cast<Instruction>("PseudoVWMACCUS_VX_" # vti.LMul.MX) (!cast<Instruction>("PseudoVWMACCUS_VX_" # vti.LMul.MX)
wti.RegClass:$rd, vti.ScalarRegClass:$rs2, vti.RegClass:$rs1, wti.RegClass:$rd, vti.ScalarRegClass:$rs2, vti.RegClass:$rs1,
GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>; GPR:$vl, vti.Log2SEW, TAIL_AGNOSTIC)>;