mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[RISCV] Manually split vector operands to VECREDUCE when handling vXi64 vectors on RV32.
The type legalizer will visit the result before the operands. To avoid creating an illegal target specific node or falling back to scalarization, we need to manually split vector operands. This still doesn't handle the case of non-power of 2 operands which need to be widened. I'm not sure the type legalizer is ready for it. I think we would need to insert an INSERT_SUBVECTOR with the power of 2 type we want, with an undef first operand, and the non-power of 2 orignal operand as the vector to insert. Then fill in the neutral elements into the elements the padded elements. Alternatively we INSERT_SUBVECTOR into a neutral vector. From there we carry on splitting if needed to get to a legal type then do the target specific code. The problem with this is the type legalizer doesn't know how to widen an insert_subvector yet. We would need to add that including the handling for a non-undef first vector. Reviewed By: frasercrmck Differential Revision: https://reviews.llvm.org/D98292
This commit is contained in:
parent
95819d3c63
commit
0cac1b0df2
@ -2443,17 +2443,30 @@ static unsigned getRVVReductionOp(unsigned ISDOpcode) {
|
||||
SDValue RISCVTargetLowering::lowerVECREDUCE(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
SDLoc DL(Op);
|
||||
MVT VecVT = Op.getOperand(0).getSimpleValueType();
|
||||
MVT VecEltVT = VecVT.getVectorElementType();
|
||||
SDValue Vec = Op.getOperand(0);
|
||||
EVT VecEVT = Vec.getValueType();
|
||||
|
||||
// Avoid creating vectors with illegal type.
|
||||
if (!isTypeLegal(VecVT))
|
||||
unsigned BaseOpc = ISD::getVecReduceBaseOpcode(Op.getOpcode());
|
||||
|
||||
// Due to ordering in legalize types we may have a vector type that needs to
|
||||
// be split. Do that manually so we can get down to a legal type.
|
||||
while (getTypeAction(*DAG.getContext(), VecEVT) ==
|
||||
TargetLowering::TypeSplitVector) {
|
||||
SDValue Lo, Hi;
|
||||
std::tie(Lo, Hi) = DAG.SplitVector(Vec, DL);
|
||||
VecEVT = Lo.getValueType();
|
||||
Vec = DAG.getNode(BaseOpc, DL, VecEVT, Lo, Hi);
|
||||
}
|
||||
|
||||
// TODO: The type may need to be widened rather than split. Or widened before
|
||||
// it can be split.
|
||||
if (!isTypeLegal(VecEVT))
|
||||
return SDValue();
|
||||
|
||||
MVT VecVT = VecEVT.getSimpleVT();
|
||||
MVT VecEltVT = VecVT.getVectorElementType();
|
||||
unsigned RVVOpcode = getRVVReductionOp(Op.getOpcode());
|
||||
|
||||
SDValue Vec = Op.getOperand(0);
|
||||
|
||||
MVT ContainerVT = VecVT;
|
||||
if (VecVT.isFixedLengthVector()) {
|
||||
ContainerVT = getContainerForFixedLengthVector(VecVT);
|
||||
@ -2467,8 +2480,8 @@ SDValue RISCVTargetLowering::lowerVECREDUCE(SDValue Op,
|
||||
|
||||
// FIXME: This is a VLMAX splat which might be too large and can prevent
|
||||
// vsetvli removal.
|
||||
SDValue NeutralElem = DAG.getNeutralElement(
|
||||
ISD::getVecReduceBaseOpcode(Op.getOpcode()), DL, VecEltVT, SDNodeFlags());
|
||||
SDValue NeutralElem =
|
||||
DAG.getNeutralElement(BaseOpc, DL, VecEltVT, SDNodeFlags());
|
||||
SDValue IdentitySplat = DAG.getSplatVector(M1VT, DL, NeutralElem);
|
||||
SDValue Reduction =
|
||||
DAG.getNode(RVVOpcode, DL, M1VT, Vec, IdentitySplat, Mask, VL);
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user