diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2638,10 +2638,19 @@ SDValue SelectionDAG::getSplatValue(SDValue V) { int SplatIdx; - if (SDValue SrcVector = getSplatSourceVector(V, SplatIdx)) - return getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), - SrcVector.getValueType().getScalarType(), SrcVector, + if (SDValue SrcVector = getSplatSourceVector(V, SplatIdx)) { + EVT SVT = SrcVector.getValueType().getScalarType(); + EVT LegalSVT = SVT; + if (NewNodesMustHaveLegalTypes && !TLI->isTypeLegal(SVT)) { + if (!SVT.isInteger()) + return SDValue(); + LegalSVT = TLI->getTypeToTransformTo(*getContext(), LegalSVT); + if (LegalSVT.bitsLT(SVT)) + return SDValue(); + } + return getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), LegalSVT, SrcVector, getVectorIdxConstant(SplatIdx, SDLoc(V))); + } return SDValue(); } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -28090,6 +28090,17 @@ return SDValue(); } +// A version of SelectionDAG::getSplatValue which may return illegal types, +// even after type legalization. +static SDValue getSplatValue(SDValue V, SelectionDAG &DAG) { + int SplatIdx; + if (SDValue SrcVector = DAG.getSplatSourceVector(V, SplatIdx)) + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SDLoc(V), + SrcVector.getValueType().getScalarType(), SrcVector, + DAG.getVectorIdxConstant(SplatIdx, SDLoc(V))); + return SDValue(); +} + static SDValue LowerScalarVariableShift(SDValue Op, SelectionDAG &DAG, const X86Subtarget &Subtarget) { MVT VT = Op.getSimpleValueType(); @@ -28100,7 +28111,7 @@ unsigned X86OpcI = getTargetVShiftUniformOpcode(Opcode, false); unsigned X86OpcV = getTargetVShiftUniformOpcode(Opcode, true); - if (SDValue BaseShAmt = DAG.getSplatValue(Amt)) { + if (SDValue BaseShAmt = getSplatValue(Amt, DAG)) { if (SupportedVectorShiftWithBaseAmnt(VT, Subtarget, Opcode)) { MVT EltVT = VT.getVectorElementType(); assert(EltVT.bitsLE(MVT::i64) && "Unexpected element type!"); diff --git a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll --- a/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll +++ b/llvm/test/CodeGen/RISCV/rvv/fixed-vectors-int-shuffles.ll @@ -347,3 +347,29 @@ %s = shufflevector <8 x i64> %x, <8 x i64> , <8 x i32> ret <8 x i64> %s } + +define <4 x i8> @interleave_shuffles(<4 x i8> %x) { +; CHECK-LABEL: interleave_shuffles: +; CHECK: # %bb.0: +; CHECK-NEXT: vsetvli zero, zero, e8,mf4,ta,mu +; CHECK-NEXT: vmv.x.s a0, v8 +; CHECK-NEXT: vsetivli a1, 4, e8,mf4,ta,mu +; CHECK-NEXT: vrgather.vi v25, v8, 1 +; CHECK-NEXT: addi a1, zero, 1 +; CHECK-NEXT: vmv.s.x v26, a1 +; CHECK-NEXT: vmv.v.i v27, 0 +; CHECK-NEXT: vsetivli a1, 4, e8,mf4,tu,mu +; CHECK-NEXT: vslideup.vi v27, v26, 3 +; CHECK-NEXT: addi a1, zero, 10 +; CHECK-NEXT: vsetivli a2, 1, e8,mf8,ta,mu +; CHECK-NEXT: vmv.s.x v0, a1 +; CHECK-NEXT: vsetivli a1, 4, e8,mf4,ta,mu +; CHECK-NEXT: vmv.v.x v8, a0 +; CHECK-NEXT: vsetivli a0, 4, e8,mf4,tu,mu +; CHECK-NEXT: vrgather.vv v8, v25, v27, v0.t +; CHECK-NEXT: ret + %y = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> + %z = shufflevector <4 x i8> %x, <4 x i8> undef, <4 x i32> + %w = shufflevector <4 x i8> %y, <4 x i8> %z, <4 x i32> + ret <4 x i8> %w +}