Skip to content

Commit bb6e94a

Browse files
authored
[RISCV] Custom legalize <N x i128>, <4 x i256>, etc.. shuffles (#122352)
I have a particular user downstream who likes to write shuffles in terms of unions involving _BitInt(128) types. This isn't completely crazy because there's a bunch of code in the wild which was written with SSE in mind, so 128 bits is a common data fragment size. The problem is that generic lowering scalarizes this to ELEN, and we end up with really terrible extract/insert sequences if the i128 shuffle is between other (non-i128) operations. I explored trying to do this via generic lowering infrastructure, and frankly got lost. Doing this a target specific DAG is a bit ugly - really, there's nothing hugely target specific here - but oh well. If reviewers prefer, I could probably phrase this as a generic DAG combine, but I'm not sure that's hugely better. If reviewers have a strong preference on how to handle this, let me know, but I may need a bit of help. A couple notes: * The argument passing weirdness is due to a missing combine to turn a build_vector of adjacent i64 loads back into a vector load. I'm a bit surprised we don't get that, but the isel output clearly has the build_vector at i64. * The splat case I plan to revisit in another patch. That's a relatively common pattern, and the fact I have to scalarize that to avoid an infinite loop is non-ideal.
1 parent 65dc0d4 commit bb6e94a

File tree

3 files changed

+255
-339
lines changed

3 files changed

+255
-339
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1530,7 +1530,8 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
15301530
ISD::BUILD_VECTOR, ISD::CONCAT_VECTORS,
15311531
ISD::EXPERIMENTAL_VP_REVERSE, ISD::MUL,
15321532
ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM,
1533-
ISD::INSERT_VECTOR_ELT, ISD::ABS, ISD::CTPOP});
1533+
ISD::INSERT_VECTOR_ELT, ISD::ABS, ISD::CTPOP,
1534+
ISD::VECTOR_SHUFFLE});
15341535
if (Subtarget.hasVendorXTHeadMemPair())
15351536
setTargetDAGCombine({ISD::LOAD, ISD::STORE});
15361537
if (Subtarget.useRVVForFixedLengthVectors())
@@ -17076,6 +17077,37 @@ static SDValue performCONCAT_VECTORSCombine(SDNode *N, SelectionDAG &DAG,
1707617077
return DAG.getBitcast(VT.getSimpleVT(), StridedLoad);
1707717078
}
1707817079

17080+
/// Custom legalize <N x i128> or <N x i256> to <M x ELEN>. This runs
17081+
/// during the combine phase before type legalization, and relies on
17082+
/// DAGCombine not undoing the transform if isShuffleMaskLegal returns false
17083+
/// for the source mask.
17084+
static SDValue performVECTOR_SHUFFLECombine(SDNode *N, SelectionDAG &DAG,
17085+
const RISCVSubtarget &Subtarget,
17086+
const RISCVTargetLowering &TLI) {
17087+
SDLoc DL(N);
17088+
EVT VT = N->getValueType(0);
17089+
const unsigned ElementSize = VT.getScalarSizeInBits();
17090+
SDValue V1 = N->getOperand(0);
17091+
SDValue V2 = N->getOperand(1);
17092+
ArrayRef<int> Mask = cast<ShuffleVectorSDNode>(N)->getMask();
17093+
17094+
if (TLI.isTypeLegal(VT) || ElementSize <= Subtarget.getELen() ||
17095+
!isPowerOf2_64(ElementSize) || VT.getVectorNumElements() % 2 != 0 ||
17096+
VT.isFloatingPoint() || TLI.isShuffleMaskLegal(Mask, VT))
17097+
return SDValue();
17098+
17099+
SmallVector<int, 8> NewMask;
17100+
narrowShuffleMaskElts(2, Mask, NewMask);
17101+
17102+
LLVMContext &C = *DAG.getContext();
17103+
EVT NewEltVT = EVT::getIntegerVT(C, ElementSize / 2);
17104+
EVT NewVT = EVT::getVectorVT(C, NewEltVT, VT.getVectorNumElements() * 2);
17105+
SDValue Res = DAG.getVectorShuffle(NewVT, DL, DAG.getBitcast(NewVT, V1),
17106+
DAG.getBitcast(NewVT, V2), NewMask);
17107+
return DAG.getBitcast(VT, Res);
17108+
}
17109+
17110+
1707917111
static SDValue combineToVWMACC(SDNode *N, SelectionDAG &DAG,
1708017112
const RISCVSubtarget &Subtarget) {
1708117113

@@ -18305,6 +18337,10 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
1830518337
if (SDValue V = performCONCAT_VECTORSCombine(N, DAG, Subtarget, *this))
1830618338
return V;
1830718339
break;
18340+
case ISD::VECTOR_SHUFFLE:
18341+
if (SDValue V = performVECTOR_SHUFFLECombine(N, DAG, Subtarget, *this))
18342+
return V;
18343+
break;
1830818344
case ISD::INSERT_VECTOR_ELT:
1830918345
if (SDValue V = performINSERT_VECTOR_ELTCombine(N, DAG, Subtarget, *this))
1831018346
return V;

0 commit comments

Comments
 (0)