[PATCH] D102687: [RISCV] Ensure shuffle splat operands are type-legal
Fraser Cormack via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue May 18 06:26:56 PDT 2021
frasercrmck created this revision.
frasercrmck added reviewers: craig.topper, rogfer01, HsiangKai, khchen.
Herald added subscribers: vkmr, evandro, luismarques, apazos, sameer.abuasal, s.egerton, Jim, benna, psnobl, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, hiraditya.
frasercrmck requested review of this revision.
Herald added subscribers: llvm-commits, MaskRay.
Herald added a project: LLVM.
The use of `SelectionDAG::getSplatValue` isn't guaranteed to return a
type-legal splat value as it may implicitly extract a vector element
from another shuffle. It is not permitted to introduce an illegal type
when lowering shuffles.
This patch addresses the crash by ensuring the splat value is legal or
constant, in which case we know we can constant-fold right it up to
XLenVT.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D102687
Files:
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
llvm/lib/Target/RISCV/RISCVISelLowering.h
llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll
Index: llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll
===================================================================
--- llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll
+++ llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll
@@ -347,3 +347,31 @@
%s = shufflevector <8 x i64> %x, <8 x i64> <i64 5, i64 5, i64 5, i64 5, i64 5, i64 5, i64 5, i64 5>, <8 x i32> <i32 0, i32 3, i32 10, i32 9, i32 4, i32 1, i32 7, i32 14>
ret <8 x i64> %s
}
+
+define <4 x i8> @interleave_shuffles(<4 x i8> %x) {
+; CHECK-LABEL: interleave_shuffles:
+; CHECK: # %bb.0:
+; CHECK-NEXT: vsetivli a0, 4, e8,mf4,ta,mu
+; CHECK-NEXT: vrgather.vi v25, v8, 0
+; CHECK-NEXT: vrgather.vi v26, v8, 1
+; CHECK-NEXT: addi a0, zero, 1
+; CHECK-NEXT: vmv.s.x v27, a0
+; CHECK-NEXT: vmv.v.i v28, 0
+; CHECK-NEXT: vsetivli a0, 4, e8,mf4,tu,mu
+; CHECK-NEXT: vmv1r.v v29, v28
+; CHECK-NEXT: vslideup.vi v29, v27, 3
+; CHECK-NEXT: vsetivli a0, 3, e8,mf4,tu,mu
+; CHECK-NEXT: vslideup.vi v28, v27, 2
+; CHECK-NEXT: vsetivli a0, 4, e8,mf4,ta,mu
+; CHECK-NEXT: vrgather.vv v8, v25, v28
+; CHECK-NEXT: addi a0, zero, 10
+; CHECK-NEXT: vsetivli a1, 1, e8,mf8,ta,mu
+; CHECK-NEXT: vmv.s.x v0, a0
+; CHECK-NEXT: vsetivli a0, 4, e8,mf4,tu,mu
+; CHECK-NEXT: vrgather.vv v8, v26, v29, v0.t
+; CHECK-NEXT: ret
+ %y = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 0, i32 0, i32 0, i32 0>
+ %z = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ %w = shufflevector <4 x i8> %y, <4 x i8> %z, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
+ ret <4 x i8> %w
+}
Index: llvm/lib/Target/RISCV/RISCVISelLowering.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -508,6 +508,7 @@
SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
SDValue lowerSPLAT_VECTOR_PARTS(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVectorMaskSplat(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerVectorMaskExt(SDValue Op, SelectionDAG &DAG,
int64_t ExtTrueVal) const;
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -1686,8 +1686,8 @@
return splatSplitI64WithVL(DL, VT, Scalar, VL, DAG);
}
-static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
- const RISCVSubtarget &Subtarget) {
+SDValue RISCVTargetLowering::lowerVECTOR_SHUFFLE(SDValue Op,
+ SelectionDAG &DAG) const {
SDValue V1 = Op.getOperand(0);
SDValue V2 = Op.getOperand(1);
SDLoc DL(Op);
@@ -1696,7 +1696,7 @@
unsigned NumElts = VT.getVectorNumElements();
ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op.getNode());
- MVT ContainerVT = getContainerForFixedLengthVector(DAG, VT, Subtarget);
+ MVT ContainerVT = getContainerForFixedLengthVector(VT);
SDValue TrueMask, VL;
std::tie(TrueMask, VL) = getDefaultVLOps(VT, ContainerVT, DL, DAG, Subtarget);
@@ -1845,9 +1845,14 @@
ContainerVT.changeVectorElementType(IndexVT.getScalarType());
SDValue Gather;
+ // We can't introduce illegal types, so ensure that a splatted element is
+ // either a constant integer (and can be freely extended to XLenVT) or
+ // type-legal.
// TODO: This doesn't trigger for i64 vectors on RV32, since there we
// encounter a bitcasted BUILD_VECTOR with low/high i32 values.
- if (SDValue SplatValue = DAG.getSplatValue(V1)) {
+ SDValue SplatValue = DAG.getSplatValue(V1);
+ if (SplatValue && (isa<ConstantSDNode>(SplatValue) ||
+ isTypeLegal(SplatValue.getValueType()))) {
Gather = lowerScalarSplat(SplatValue, VL, ContainerVT, DL, DAG, Subtarget);
} else {
SDValue LHSIndices = DAG.getBuildVector(IndexVT, DL, GatherIndicesLHS);
@@ -2298,7 +2303,7 @@
return lowerVectorMaskSplat(Op, DAG);
return lowerSPLAT_VECTOR(Op, DAG, Subtarget);
case ISD::VECTOR_SHUFFLE:
- return lowerVECTOR_SHUFFLE(Op, DAG, Subtarget);
+ return lowerVECTOR_SHUFFLE(Op, DAG);
case ISD::CONCAT_VECTORS: {
// Split CONCAT_VECTORS into a series of INSERT_SUBVECTOR nodes. This is
// better than going through the stack, as the default expansion does.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D102687.346158.patch
Type: text/x-patch
Size: 4646 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210518/bc19e31f/attachment.bin>
More information about the llvm-commits
mailing list