mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[VP][SelectionDAG] Add a target-configurable EVL operand type
This patch adds a way for the target to configure the type it uses for the explicit vector length operands of VP SDNodes. The type must be a legal integer type (there is still no target-independent legalization of this operand) and must currently be at least as big as i32, the type used by the IR intrinsics. An implicit zero-extension takes place on targets which choose a larger type. All VP nodes should be created with this type used for the EVL operand. This allows 64-bit RISC-V to avoid custom legalization of all VP nodes, keeping them in their target-independent form for that bit longer. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D103027
This commit is contained in:
parent
caa14ae743
commit
58a6d02787
@ -393,6 +393,12 @@ public:
|
||||
return getPointerTy(DL);
|
||||
}
|
||||
|
||||
/// Returns the type to be used for the EVL/AVL operand of VP nodes:
|
||||
/// ISD::VP_ADD, ISD::VP_SUB, etc. It must be a legal scalar integer type,
|
||||
/// and must be at least as large as i32. The EVL is implicitly zero-extended
|
||||
/// to any larger type.
|
||||
virtual MVT getVPExplicitVectorLengthTy() const { return MVT::i32; }
|
||||
|
||||
/// This callback is used to inspect load/store instructions and add
|
||||
/// target-specific MachineMemOperand flags to them. The default
|
||||
/// implementation does nothing.
|
||||
|
@ -7296,6 +7296,7 @@ static unsigned getISDForVPIntrinsic(const VPIntrinsic &VPIntrin) {
|
||||
|
||||
void SelectionDAGBuilder::visitVectorPredicationIntrinsic(
|
||||
const VPIntrinsic &VPIntrin) {
|
||||
SDLoc DL = getCurSDLoc();
|
||||
unsigned Opcode = getISDForVPIntrinsic(VPIntrin);
|
||||
|
||||
SmallVector<EVT, 4> ValueVTs;
|
||||
@ -7303,12 +7304,22 @@ void SelectionDAGBuilder::visitVectorPredicationIntrinsic(
|
||||
ComputeValueVTs(TLI, DAG.getDataLayout(), VPIntrin.getType(), ValueVTs);
|
||||
SDVTList VTs = DAG.getVTList(ValueVTs);
|
||||
|
||||
auto EVLParamPos =
|
||||
VPIntrinsic::GetVectorLengthParamPos(VPIntrin.getIntrinsicID());
|
||||
|
||||
MVT EVLParamVT = TLI.getVPExplicitVectorLengthTy();
|
||||
assert(EVLParamVT.isScalarInteger() && EVLParamVT.bitsGE(MVT::i32) &&
|
||||
"Unexpected target EVL type");
|
||||
|
||||
// Request operands.
|
||||
SmallVector<SDValue, 7> OpValues;
|
||||
for (int i = 0; i < (int)VPIntrin.getNumArgOperands(); ++i)
|
||||
OpValues.push_back(getValue(VPIntrin.getArgOperand(i)));
|
||||
for (int I = 0; I < (int)VPIntrin.getNumArgOperands(); ++I) {
|
||||
auto Op = getValue(VPIntrin.getArgOperand(I));
|
||||
if (I == EVLParamPos)
|
||||
Op = DAG.getNode(ISD::ZERO_EXTEND, DL, EVLParamVT, Op);
|
||||
OpValues.push_back(Op);
|
||||
}
|
||||
|
||||
SDLoc DL = getCurSDLoc();
|
||||
SDValue Result = DAG.getNode(Opcode, DL, VTs, OpValues);
|
||||
setValue(&VPIntrin, Result);
|
||||
}
|
||||
|
@ -506,12 +506,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
|
||||
setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
|
||||
|
||||
for (unsigned VPOpc : IntegerVPOps) {
|
||||
for (unsigned VPOpc : IntegerVPOps)
|
||||
setOperationAction(VPOpc, VT, Custom);
|
||||
// RV64 must custom-legalize the i32 EVL parameter.
|
||||
if (Subtarget.is64Bit())
|
||||
setOperationAction(VPOpc, MVT::i32, Custom);
|
||||
}
|
||||
|
||||
setOperationAction(ISD::MLOAD, VT, Custom);
|
||||
setOperationAction(ISD::MSTORE, VT, Custom);
|
||||
@ -722,12 +718,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::VECREDUCE_UMAX, VT, Custom);
|
||||
setOperationAction(ISD::VECREDUCE_UMIN, VT, Custom);
|
||||
|
||||
for (unsigned VPOpc : IntegerVPOps) {
|
||||
for (unsigned VPOpc : IntegerVPOps)
|
||||
setOperationAction(VPOpc, VT, Custom);
|
||||
// RV64 must custom-legalize the i32 EVL parameter.
|
||||
if (Subtarget.is64Bit())
|
||||
setOperationAction(VPOpc, MVT::i32, Custom);
|
||||
}
|
||||
}
|
||||
|
||||
for (MVT VT : MVT::fp_fixedlen_vector_valuetypes()) {
|
||||
@ -835,6 +827,10 @@ EVT RISCVTargetLowering::getSetCCResultType(const DataLayout &DL,
|
||||
return VT.changeVectorElementTypeToInteger();
|
||||
}
|
||||
|
||||
MVT RISCVTargetLowering::getVPExplicitVectorLengthTy() const {
|
||||
return Subtarget.getXLenVT();
|
||||
}
|
||||
|
||||
bool RISCVTargetLowering::getTgtMemIntrinsic(IntrinsicInfo &Info,
|
||||
const CallInst &I,
|
||||
MachineFunction &MF,
|
||||
@ -4282,17 +4278,10 @@ SDValue RISCVTargetLowering::lowerVPOp(SDValue Op, SelectionDAG &DAG,
|
||||
unsigned RISCVISDOpc) const {
|
||||
SDLoc DL(Op);
|
||||
MVT VT = Op.getSimpleValueType();
|
||||
Optional<unsigned> EVLIdx = ISD::getVPExplicitVectorLengthIdx(Op.getOpcode());
|
||||
|
||||
SmallVector<SDValue, 4> Ops;
|
||||
MVT XLenVT = Subtarget.getXLenVT();
|
||||
|
||||
for (const auto &OpIdx : enumerate(Op->ops())) {
|
||||
SDValue V = OpIdx.value();
|
||||
if ((unsigned)OpIdx.index() == EVLIdx) {
|
||||
Ops.push_back(DAG.getZExtOrTrunc(V, DL, XLenVT));
|
||||
continue;
|
||||
}
|
||||
assert(!isa<VTSDNode>(V) && "Unexpected VTSDNode node!");
|
||||
// Pass through operands which aren't fixed-length vectors.
|
||||
if (!V.getValueType().isFixedLengthVector()) {
|
||||
|
@ -561,6 +561,8 @@ private:
|
||||
|
||||
bool useRVVForFixedLengthVectorVT(MVT VT) const;
|
||||
|
||||
MVT getVPExplicitVectorLengthTy() const override;
|
||||
|
||||
/// RVV code generation for fixed length vectors does not lower all
|
||||
/// BUILD_VECTORs. This makes BUILD_VECTOR legalisation a source of stores to
|
||||
/// merge. However, merging them creates a BUILD_VECTOR that is just as
|
||||
|
Loading…
Reference in New Issue
Block a user