[RISCV] Lower VECTOR_SPLICE to RVV instructions.
This lowers VECTOR_SPLICE of scalable vectors to a slidedown follow by a slideup. Fixed vectors are encouraged to use shufflevector instruction. The equivalent patch for fixed vectors is D119039. I've used a tail agnostic slidedown and limited the VL to only the elements that will not be overwritten by the slideup. The slideup uses VLMax for its VL. It unfortunately uses tail undisturbed policy but it isn't required as there is no tail. We just need the merge operand to carry the bits for the lower portion of the result. Care was taken to ensure that either the slideup or slidedown will be able to use a .vi instruction when the immediate is small. Which one uses the immediate depends on the sign of the immediate. Reviewed By: frasercrmck, ABataev Differential Revision: https://reviews.llvm.org/D119303
This commit is contained in:
parent
7bc6667845
commit
b9d6e8c441
|
@ -675,6 +675,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
setLoadExtAction(ISD::ZEXTLOAD, OtherVT, VT, Expand);
|
||||
}
|
||||
|
||||
// Splice
|
||||
setOperationAction(ISD::VECTOR_SPLICE, VT, Custom);
|
||||
|
||||
// Lower CTLZ_ZERO_UNDEF and CTTZ_ZERO_UNDEF if we have a floating point
|
||||
// type that can represent the value exactly.
|
||||
if (VT.getVectorElementType() != MVT::i64) {
|
||||
|
@ -753,6 +756,7 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
|||
setOperationAction(ISD::EXTRACT_SUBVECTOR, VT, Custom);
|
||||
|
||||
setOperationAction(ISD::VECTOR_REVERSE, VT, Custom);
|
||||
setOperationAction(ISD::VECTOR_SPLICE, VT, Custom);
|
||||
|
||||
for (unsigned VPOpc : FloatingPointVPOps)
|
||||
setOperationAction(VPOpc, VT, Custom);
|
||||
|
@ -3507,6 +3511,8 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
|
|||
return lowerSTEP_VECTOR(Op, DAG);
|
||||
case ISD::VECTOR_REVERSE:
|
||||
return lowerVECTOR_REVERSE(Op, DAG);
|
||||
case ISD::VECTOR_SPLICE:
|
||||
return lowerVECTOR_SPLICE(Op, DAG);
|
||||
case ISD::BUILD_VECTOR:
|
||||
return lowerBUILD_VECTOR(Op, DAG, Subtarget);
|
||||
case ISD::SPLAT_VECTOR:
|
||||
|
@ -5628,6 +5634,43 @@ SDValue RISCVTargetLowering::lowerVECTOR_REVERSE(SDValue Op,
|
|||
return DAG.getNode(GatherOpc, DL, VecVT, Op.getOperand(0), Indices, Mask, VL);
|
||||
}
|
||||
|
||||
SDValue RISCVTargetLowering::lowerVECTOR_SPLICE(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
SDValue V1 = Op.getOperand(0);
|
||||
SDValue V2 = Op.getOperand(1);
|
||||
MVT XLenVT = Subtarget.getXLenVT();
|
||||
MVT VecVT = Op.getSimpleValueType();
|
||||
|
||||
unsigned MinElts = VecVT.getVectorMinNumElements();
|
||||
SDValue VLMax = DAG.getNode(ISD::VSCALE, DL, XLenVT,
|
||||
DAG.getConstant(MinElts, DL, XLenVT));
|
||||
|
||||
int64_t ImmValue = cast<ConstantSDNode>(Op.getOperand(2))->getSExtValue();
|
||||
SDValue DownOffset, UpOffset;
|
||||
if (ImmValue >= 0) {
|
||||
// The operand is a TargetConstant, we need to rebuild it as a regular
|
||||
// constant.
|
||||
DownOffset = DAG.getConstant(ImmValue, DL, XLenVT);
|
||||
UpOffset = DAG.getNode(ISD::SUB, DL, XLenVT, VLMax, DownOffset);
|
||||
} else {
|
||||
// The operand is a TargetConstant, we need to rebuild it as a regular
|
||||
// constant rather than negating the original operand.
|
||||
UpOffset = DAG.getConstant(-ImmValue, DL, XLenVT);
|
||||
DownOffset = DAG.getNode(ISD::SUB, DL, XLenVT, VLMax, UpOffset);
|
||||
}
|
||||
|
||||
MVT MaskVT = MVT::getVectorVT(MVT::i1, VecVT.getVectorElementCount());
|
||||
SDValue TrueMask = DAG.getNode(RISCVISD::VMSET_VL, DL, MaskVT, VLMax);
|
||||
|
||||
SDValue SlideDown =
|
||||
DAG.getNode(RISCVISD::VSLIDEDOWN_VL, DL, VecVT, DAG.getUNDEF(VecVT), V1,
|
||||
DownOffset, TrueMask, UpOffset);
|
||||
return DAG.getNode(RISCVISD::VSLIDEUP_VL, DL, VecVT, SlideDown, V2, UpOffset,
|
||||
TrueMask,
|
||||
DAG.getTargetConstant(RISCV::VLMaxSentinel, DL, XLenVT));
|
||||
}
|
||||
|
||||
SDValue
|
||||
RISCVTargetLowering::lowerFixedLengthVectorLoadToRVV(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
|
|
|
@ -615,6 +615,7 @@ private:
|
|||
SDValue lowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerSTEP_VECTOR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVECTOR_REVERSE(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerVECTOR_SPLICE(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerABS(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerMaskedLoad(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue lowerMaskedStore(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
|
2034
llvm/test/CodeGen/RISCV/rvv/vector-splice.ll
Normal file
2034
llvm/test/CodeGen/RISCV/rvv/vector-splice.ll
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue