1
0
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:
Fraser Cormack 2021-05-24 15:24:54 +01:00
parent caa14ae743
commit 58a6d02787
4 changed files with 28 additions and 20 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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()) {

View File

@ -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