[llvm] [GlobalISel] Make scalar G_SHUFFLE_VECTOR illegal. (PR #140508)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Mon May 19 00:27:01 PDT 2025
https://github.com/davemgreen updated https://github.com/llvm/llvm-project/pull/140508
>From ac071613d61fc4b3d64aedd101bf2a18e28428b9 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 19 May 2025 08:26:52 +0100
Subject: [PATCH] [GlobalISel] Make scalar G_SHUFFLE_VECTOR illegal.
I'm not sure if this is the best design or not, but we have a lot of issues
with forgetting that shuffle_vectors can be scalar again and again. (There is
another example from the recent known-bits code added recently). As a
scalar-dst shuffle vector is just an extract, and a scalar-source shuffle
vector is just a build vector, this patch makes scalar shuffle vector illegal
and adjusts the irbuilder to create the correct node as required.
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 -
.../include/llvm/Target/GlobalISel/Combine.td | 10 +-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 58 +---------
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 2 +
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp | 45 ++++++++
.../CodeGen/GlobalISel/LegalizerHelper.cpp | 26 +++--
.../CodeGen/GlobalISel/MachineIRBuilder.cpp | 6 +-
llvm/lib/CodeGen/MachineVerifier.cpp | 16 ++-
llvm/lib/Target/AArch64/AArch64Combine.td | 1 -
.../GISel/AArch64InstructionSelector.cpp | 10 --
.../AArch64/GISel/AArch64LegalizerInfo.cpp | 16 +--
.../AArch64/GlobalISel/arm64-irtranslator.ll | 6 +-
.../GlobalISel/legalize-shuffle-vector.mir | 30 +-----
...rcombiner-shuffle-vector-disjoint-mask.mir | 19 ----
...lizercombiner-shuffle-vector-undef-rhs.mir | 20 ----
.../prelegalizercombiner-shuffle-vector.mir | 102 +-----------------
.../GlobalISel/legalize-shuffle-vector.mir | 48 +--------
.../ARM/GlobalISel/arm-irtranslator.ll | 6 +-
.../CodeGen/MIR/AArch64/parse-shufflemask.mir | 51 ---------
.../MachineVerifier/test_g_shuffle_vector.mir | 9 +-
20 files changed, 102 insertions(+), 382 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index c15263e0b06f8..fcefcb2452818 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -262,7 +262,6 @@ class CombinerHelper {
SmallVector<Register> &Ops) const;
/// Replace \p MI with a build_vector.
- bool matchCombineShuffleToBuildVector(MachineInstr &MI) const;
void applyCombineShuffleToBuildVector(MachineInstr &MI) const;
/// Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
@@ -281,8 +280,6 @@ class CombinerHelper {
/// Replace \p MI with a concat_vectors with \p Ops.
void applyCombineShuffleVector(MachineInstr &MI,
const ArrayRef<Register> Ops) const;
- bool matchShuffleToExtract(MachineInstr &MI) const;
- void applyShuffleToExtract(MachineInstr &MI) const;
/// Optimize memcpy intrinsics et al, e.g. constant len calls.
/// /p MaxLen if non-zero specifies the max length of a mem libcall to inline.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index efd88524a159e..49b49bba8e17a 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -471,13 +471,6 @@ def propagate_undef_shuffle_mask: GICombineRule<
[{ return Helper.matchUndefShuffleVectorMask(*${root}); }]),
(apply [{ Helper.replaceInstWithUndef(*${root}); }])>;
-// Replace a G_SHUFFLE_VECTOR with a G_EXTRACT_VECTOR_ELT.
-def shuffle_to_extract: GICombineRule<
- (defs root:$root),
- (match (wip_match_opcode G_SHUFFLE_VECTOR):$root,
- [{ return Helper.matchShuffleToExtract(*${root}); }]),
- (apply [{ Helper.applyShuffleToExtract(*${root}); }])>;
-
// Replace an insert/extract element of an out of bounds index with undef.
def insert_extract_vec_elt_out_of_bounds : GICombineRule<
(defs root:$root),
@@ -1575,8 +1568,7 @@ def combine_shuffle_concat : GICombineRule<
// Combines shuffles of vector into build_vector
def combine_shuffle_vector_to_build_vector : GICombineRule<
(defs root:$root),
- (match (G_SHUFFLE_VECTOR $dst, $src1, $src2, $mask):$root,
- [{ return Helper.matchCombineShuffleToBuildVector(*${root}); }]),
+ (match (G_SHUFFLE_VECTOR $dst, $src1, $src2, $mask):$root),
(apply [{ Helper.applyCombineShuffleToBuildVector(*${root}); }])>;
def insert_vector_element_idx_undef : GICombineRule<
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 5191360c7718a..e0bfeb0c35a59 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -386,19 +386,6 @@ void CombinerHelper::applyCombineConcatVectors(
MI.eraseFromParent();
}
-bool CombinerHelper::matchCombineShuffleToBuildVector(MachineInstr &MI) const {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
- "Invalid instruction");
- auto &Shuffle = cast<GShuffleVector>(MI);
-
- Register SrcVec1 = Shuffle.getSrc1Reg();
- Register SrcVec2 = Shuffle.getSrc2Reg();
-
- LLT SrcVec1Type = MRI.getType(SrcVec1);
- LLT SrcVec2Type = MRI.getType(SrcVec2);
- return SrcVec1Type.isVector() && SrcVec2Type.isVector();
-}
-
void CombinerHelper::applyCombineShuffleToBuildVector(MachineInstr &MI) const {
auto &Shuffle = cast<GShuffleVector>(MI);
@@ -527,11 +514,9 @@ bool CombinerHelper::matchCombineShuffleVector(
LLT DstType = MRI.getType(MI.getOperand(0).getReg());
Register Src1 = MI.getOperand(1).getReg();
LLT SrcType = MRI.getType(Src1);
- // As bizarre as it may look, shuffle vector can actually produce
- // scalar! This is because at the IR level a <1 x ty> shuffle
- // vector is perfectly valid.
- unsigned DstNumElts = DstType.isVector() ? DstType.getNumElements() : 1;
- unsigned SrcNumElts = SrcType.isVector() ? SrcType.getNumElements() : 1;
+
+ unsigned DstNumElts = DstType.getNumElements();
+ unsigned SrcNumElts = SrcType.getNumElements();
// If the resulting vector is smaller than the size of the source
// vectors being concatenated, we won't be able to replace the
@@ -548,7 +533,7 @@ bool CombinerHelper::matchCombineShuffleVector(
//
// TODO: If the size between the source and destination don't match
// we could still emit an extract vector element in that case.
- if (DstNumElts < 2 * SrcNumElts && DstNumElts != 1)
+ if (DstNumElts < 2 * SrcNumElts)
return false;
// Check that the shuffle mask can be broken evenly between the
@@ -611,39 +596,6 @@ void CombinerHelper::applyCombineShuffleVector(
MI.eraseFromParent();
}
-bool CombinerHelper::matchShuffleToExtract(MachineInstr &MI) const {
- assert(MI.getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR &&
- "Invalid instruction kind");
-
- ArrayRef<int> Mask = MI.getOperand(3).getShuffleMask();
- return Mask.size() == 1;
-}
-
-void CombinerHelper::applyShuffleToExtract(MachineInstr &MI) const {
- Register DstReg = MI.getOperand(0).getReg();
- Builder.setInsertPt(*MI.getParent(), MI);
-
- int I = MI.getOperand(3).getShuffleMask()[0];
- Register Src1 = MI.getOperand(1).getReg();
- LLT Src1Ty = MRI.getType(Src1);
- int Src1NumElts = Src1Ty.isVector() ? Src1Ty.getNumElements() : 1;
- Register SrcReg;
- if (I >= Src1NumElts) {
- SrcReg = MI.getOperand(2).getReg();
- I -= Src1NumElts;
- } else if (I >= 0)
- SrcReg = Src1;
-
- if (I < 0)
- Builder.buildUndef(DstReg);
- else if (!MRI.getType(SrcReg).isVector())
- Builder.buildCopy(DstReg, SrcReg);
- else
- Builder.buildExtractVectorElementConstant(DstReg, SrcReg, I);
-
- MI.eraseFromParent();
-}
-
namespace {
/// Select a preference between two uses. CurrentUse is the current preference
@@ -7942,7 +7894,7 @@ bool CombinerHelper::matchShuffleDisjointMask(MachineInstr &MI,
return false;
ArrayRef<int> Mask = Shuffle.getMask();
- const unsigned NumSrcElems = Src1Ty.isVector() ? Src1Ty.getNumElements() : 1;
+ const unsigned NumSrcElems = Src1Ty.getNumElements();
bool TouchesSrc1 = false;
bool TouchesSrc2 = false;
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index 748ecbd767c3e..e51a2fd92f770 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -591,6 +591,8 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
Depth + 1);
computeKnownBitsImpl(MI.getOperand(3).getReg(), WidthKnown, DemandedElts,
Depth + 1);
+ OffsetKnown = OffsetKnown.sext(BitWidth);
+ WidthKnown = WidthKnown.sext(BitWidth);
Known = extractBits(BitWidth, SrcOpKnown, OffsetKnown, WidthKnown);
// Sign extend the extracted value using shift left and arithmetic shift
// right.
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 8ab2533afc15f..6078288c1823e 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -3330,6 +3330,51 @@ bool IRTranslator::translateShuffleVector(const User &U,
Mask = SVI->getShuffleMask();
else
Mask = cast<ConstantExpr>(U).getShuffleMask();
+
+ unsigned DstElts = cast<FixedVectorType>(U.getType())->getNumElements();
+ unsigned SrcElts =
+ cast<FixedVectorType>(U.getOperand(0)->getType())->getNumElements();
+ if (DstElts == 1) {
+ int M = Mask[0];
+ if (SrcElts == 1) {
+ if (M == 0 || M == 1) {
+ return translateCopy(U, *U.getOperand(M), MIRBuilder);
+ }
+ MIRBuilder.buildUndef(getOrCreateVReg(U));
+ return true;
+ } else {
+ if (M < SrcElts) {
+ MIRBuilder.buildExtractVectorElementConstant(
+ getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(0)), M);
+ } else if (M < SrcElts * 2) {
+ MIRBuilder.buildExtractVectorElementConstant(
+ getOrCreateVReg(U), getOrCreateVReg(*U.getOperand(1)), M - SrcElts);
+ } else {
+ MIRBuilder.buildUndef(getOrCreateVReg(U));
+ }
+ return true;
+ }
+ }
+
+ if (SrcElts == 1) {
+ SmallVector<Register> Ops;
+ for (int M : Mask) {
+ Register Undef = 0;
+ LLT SrcTy = getLLTForType(*U.getOperand(0)->getType(), *DL);
+ if (M == 0 || M == 1) {
+ Ops.push_back(getOrCreateVReg(*U.getOperand(M)));
+ } else {
+ if (Undef.isValid()) {
+ Undef = MRI->createGenericVirtualRegister(SrcTy);
+ MIRBuilder.buildUndef(Undef);
+ }
+ Ops.push_back(Undef);
+ }
+ }
+ MIRBuilder.buildBuildVector(getOrCreateVReg(U), Ops);
+ return true;
+ }
+
ArrayRef<int> MaskAlloc = MF->allocateShuffleMask(Mask);
MIRBuilder
.buildInstr(TargetOpcode::G_SHUFFLE_VECTOR, {getOrCreateVReg(U)},
diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 72f2ba75c927e..0138f625d0c68 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -5626,6 +5626,8 @@ LegalizerHelper::LegalizeResult LegalizerHelper::fewerElementsVectorShuffle(
} else if (InputUsed[0] == -1U) {
// No input vectors were used! The result is undefined.
Output = MIRBuilder.buildUndef(NarrowTy).getReg(0);
+ } else if (NewElts == 1) {
+ Output = MIRBuilder.buildCopy(NarrowTy, Inputs[InputUsed[0]]).getReg(0);
} else {
Register Op0 = Inputs[InputUsed[0]];
// If only one input was used, use an undefined vector for the other.
@@ -8407,22 +8409,18 @@ LegalizerHelper::lowerShuffleVector(MachineInstr &MI) {
continue;
}
- if (Src0Ty.isScalar()) {
- BuildVec.push_back(Idx == 0 ? Src0Reg : Src1Reg);
- } else {
- int NumElts = Src0Ty.getNumElements();
- Register SrcVec = Idx < NumElts ? Src0Reg : Src1Reg;
- int ExtractIdx = Idx < NumElts ? Idx : Idx - NumElts;
- auto IdxK = MIRBuilder.buildConstant(IdxTy, ExtractIdx);
- auto Extract = MIRBuilder.buildExtractVectorElement(EltTy, SrcVec, IdxK);
- BuildVec.push_back(Extract.getReg(0));
- }
+ assert(!Src0Ty.isScalar() && "Unexpected scalar G_SHUFFLE_VECTOR");
+
+ int NumElts = Src0Ty.getNumElements();
+ Register SrcVec = Idx < NumElts ? Src0Reg : Src1Reg;
+ int ExtractIdx = Idx < NumElts ? Idx : Idx - NumElts;
+ auto IdxK = MIRBuilder.buildConstant(IdxTy, ExtractIdx);
+ auto Extract = MIRBuilder.buildExtractVectorElement(EltTy, SrcVec, IdxK);
+ BuildVec.push_back(Extract.getReg(0));
}
- if (DstTy.isScalar())
- MIRBuilder.buildCopy(DstReg, BuildVec[0]);
- else
- MIRBuilder.buildBuildVector(DstReg, BuildVec);
+ assert(!DstTy.isScalar() && "Unexpected scalar G_SHUFFLE_VECTOR");
+ MIRBuilder.buildBuildVector(DstReg, BuildVec);
MI.eraseFromParent();
return Legalized;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
index 121d7e80251c7..4961a96b9ca48 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineIRBuilder.cpp
@@ -784,9 +784,9 @@ MachineInstrBuilder MachineIRBuilder::buildShuffleVector(const DstOp &Res,
LLT DstTy = Res.getLLTTy(*getMRI());
LLT Src1Ty = Src1.getLLTTy(*getMRI());
LLT Src2Ty = Src2.getLLTTy(*getMRI());
- const LLT DstElemTy = DstTy.isVector() ? DstTy.getElementType() : DstTy;
- const LLT ElemTy1 = Src1Ty.isVector() ? Src1Ty.getElementType() : Src1Ty;
- const LLT ElemTy2 = Src2Ty.isVector() ? Src2Ty.getElementType() : Src2Ty;
+ const LLT DstElemTy = DstTy.getScalarType();
+ const LLT ElemTy1 = Src1Ty.getScalarType();
+ const LLT ElemTy2 = Src2Ty.getScalarType();
assert(DstElemTy == ElemTy1 && DstElemTy == ElemTy2);
(void)DstElemTy;
(void)ElemTy1;
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index a7dbceb88c4c8..f2e19a9c62b4a 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -1926,13 +1926,23 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
if (Src0Ty != Src1Ty)
report("Source operands must be the same type", MI);
- if (Src0Ty.getScalarType() != DstTy.getScalarType())
+ if (Src0Ty.getScalarType() != DstTy.getScalarType()) {
report("G_SHUFFLE_VECTOR cannot change element type", MI);
+ break;
+ }
+ if (!Src0Ty.isVector()) {
+ report("G_SHUFFLE_VECTOR must have vector src", MI);
+ break;
+ }
+ if (!DstTy.isVector()) {
+ report("G_SHUFFLE_VECTOR must have vector dst", MI);
+ break;
+ }
// Don't check that all operands are vector because scalars are used in
// place of 1 element vectors.
- int SrcNumElts = Src0Ty.isVector() ? Src0Ty.getNumElements() : 1;
- int DstNumElts = DstTy.isVector() ? DstTy.getNumElements() : 1;
+ int SrcNumElts = Src0Ty.getNumElements();
+ int DstNumElts = DstTy.getNumElements();
ArrayRef<int> MaskIdxes = MaskOp.getShuffleMask();
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index f84e83816bf33..492441d1aebee 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -70,7 +70,6 @@ def AArch64PreLegalizerCombiner: GICombiner<
fconstant_to_constant,
icmp_redundant_trunc,
fold_global_offset,
- shuffle_to_extract,
ext_addv_to_udot_addv,
ext_uaddv_to_uaddlv,
push_sub_through_zext,
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index e0c693bff3c0a..389a3fb500bbd 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -5191,23 +5191,13 @@ bool AArch64InstructionSelector::selectShuffleVector(
MachineInstr &I, MachineRegisterInfo &MRI) {
const LLT DstTy = MRI.getType(I.getOperand(0).getReg());
Register Src1Reg = I.getOperand(1).getReg();
- const LLT Src1Ty = MRI.getType(Src1Reg);
Register Src2Reg = I.getOperand(2).getReg();
- const LLT Src2Ty = MRI.getType(Src2Reg);
ArrayRef<int> Mask = I.getOperand(3).getShuffleMask();
MachineBasicBlock &MBB = *I.getParent();
MachineFunction &MF = *MBB.getParent();
LLVMContext &Ctx = MF.getFunction().getContext();
- // G_SHUFFLE_VECTOR is weird in that the source operands can be scalars, if
- // it's originated from a <1 x T> type. Those should have been lowered into
- // G_BUILD_VECTOR earlier.
- if (!Src1Ty.isVector() || !Src2Ty.isVector()) {
- LLVM_DEBUG(dbgs() << "Could not select a \"scalar\" G_SHUFFLE_VECTOR\n");
- return false;
- }
-
unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
SmallVector<Constant *, 64> CstIdxs;
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index 7ff2e55e802c5..9262f0c84ca55 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -1175,25 +1175,17 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
return llvm::is_contained(
{v8s8, v16s8, v4s16, v8s16, v2s32, v4s32, v2s64}, DstTy);
})
- // G_SHUFFLE_VECTOR can have scalar sources (from 1 x s vectors) or scalar
- // destinations, we just want those lowered into G_BUILD_VECTOR or
- // G_EXTRACT_ELEMENT.
- .lowerIf([=](const LegalityQuery &Query) {
- return !Query.Types[0].isVector() || !Query.Types[1].isVector();
- })
.moreElementsIf(
[](const LegalityQuery &Query) {
- return Query.Types[0].isVector() && Query.Types[1].isVector() &&
- Query.Types[0].getNumElements() >
- Query.Types[1].getNumElements();
+ return Query.Types[0].getNumElements() >
+ Query.Types[1].getNumElements();
},
changeTo(1, 0))
.moreElementsToNextPow2(0)
.moreElementsIf(
[](const LegalityQuery &Query) {
- return Query.Types[0].isVector() && Query.Types[1].isVector() &&
- Query.Types[0].getNumElements() <
- Query.Types[1].getNumElements();
+ return Query.Types[0].getNumElements() <
+ Query.Types[1].getNumElements();
},
changeTo(0, 1))
.widenScalarOrEltToNextPow2OrMinSize(0, 8)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
index d457418720f47..1c68812615f65 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/arm64-irtranslator.ll
@@ -1727,8 +1727,7 @@ define float @test_different_call_conv_target(float %x) {
define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $w0
-; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
-; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
+; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ARG]](s32), [[ARG]](s32)
; CHECK: $d0 = COPY [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%res = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
@@ -1738,7 +1737,8 @@ define <2 x i32> @test_shufflevector_s32_v2s32(i32 %arg) {
define i32 @test_shufflevector_v2s32_s32(<2 x i32> %arg) {
; CHECK-LABEL: name: test_shufflevector_v2s32_s32
; CHECK: [[ARG:%[0-9]+]]:_(<2 x s32>) = COPY $d0
-; CHECK: [[RES:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](<2 x s32>), [[UNDEF]], shufflemask(1)
+; CHECK: [[IDX:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
+; CHECK: [[RES:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[ARG]](<2 x s32>), [[IDX]](s64)
; CHECK: $w0 = COPY [[RES]](s32)
%vec = shufflevector <2 x i32> %arg, <2 x i32> undef, <1 x i32> <i32 1>
%res = extractelement <1 x i32> %vec, i32 0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector.mir
index af03a21806982..abd8fd75048f8 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-shuffle-vector.mir
@@ -117,33 +117,6 @@ body: |
$q0 = COPY %2(<8 x s16>)
RET_ReallyLR implicit $q0
-...
----
-name: shuffle_1elt_mask
-alignment: 4
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $d0, $d1
-
- ; CHECK-LABEL: name: shuffle_1elt_mask
- ; CHECK: liveins: $d0, $d1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $d0
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $d1
- ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY [[COPY]](s64)
- ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY [[COPY1]](s64)
- ; CHECK-NEXT: $d0 = COPY [[COPY2]](s64)
- ; CHECK-NEXT: $d1 = COPY [[COPY3]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit $d0, implicit $d1
- %0:_(s64) = COPY $d0
- %1:_(s64) = COPY $d1
- %3:_(s64) = G_SHUFFLE_VECTOR %0:_(s64), %1:_, shufflemask(0)
- %4:_(s64) = G_SHUFFLE_VECTOR %0:_(s64), %1:_, shufflemask(1)
- $d0 = COPY %3(s64)
- $d1 = COPY %4(s64)
- RET_ReallyLR implicit $d0, implicit $d1
-
...
---
name: oversize_shuffle_v4i64
@@ -641,7 +614,8 @@ body: |
%0:_(<8 x s1>) = G_TRUNC %2:_(<8 x s8>)
%3:_(<8 x s8>) = COPY $d1
%1:_(<8 x s1>) = G_TRUNC %3:_(<8 x s8>)
- %4:_(s1) = G_SHUFFLE_VECTOR %0:_(<8 x s1>), %1:_, shufflemask(12)
+ %7:_(s64) = G_CONSTANT i64 4
+ %4:_(s1) = G_EXTRACT_VECTOR_ELT %1:_(<8 x s1>), %7(s64)
%5:_(s8) = G_ZEXT %4:_(s1)
%6:_(s32) = G_ANYEXT %5:_(s8)
$w0 = COPY %6:_(s32)
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-disjoint-mask.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-disjoint-mask.mir
index 9261d7af41c69..914dfa0c58d59 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-disjoint-mask.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-disjoint-mask.mir
@@ -80,22 +80,3 @@ body: |
%2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(-1,0,1,-1)
RET_ReallyLR implicit %2
...
-
----
-name: shuffle_vector_scalar
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0, $x1
-
- ; CHECK-LABEL: name: shuffle_vector_scalar
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
- ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s64>) = G_BUILD_VECTOR [[COPY]](s64), [[COPY]](s64), [[COPY]](s64), [[COPY]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit [[BUILD_VECTOR]](<4 x s64>)
- %0:_(s64) = COPY $x0
- %1:_(s64) = COPY $x1
- %2:_(<4 x s64>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 0, 0, 0)
- RET_ReallyLR implicit %2
-...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-undef-rhs.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-undef-rhs.mir
index 9bf79936463c3..7a314ba9ab358 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-undef-rhs.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector-undef-rhs.mir
@@ -20,23 +20,3 @@ body: |
%2:_(<4 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1(<2 x s32>), shufflemask(0, 2, 1, 3)
RET_ReallyLR implicit %2
...
-
----
-name: shuffle_vector_undef_rhs_scalar
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0
-
- ; CHECK-LABEL: name: shuffle_vector_undef_rhs_scalar
- ; CHECK: liveins: $x0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[COPY]](s64), [[DEF]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit [[BUILD_VECTOR]](<2 x s64>)
- %0:_(s64) = COPY $x0
- %1:_(s64) = G_IMPLICIT_DEF
- %2:_(<2 x s64>) = G_SHUFFLE_VECTOR %0(s64), %1(s64), shufflemask(0, 1)
- RET_ReallyLR implicit %2
-...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector.mir
index 2c9ae5b06b62e..901341003d495 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/prelegalizercombiner-shuffle-vector.mir
@@ -386,7 +386,7 @@ body: |
; CHECK-NEXT: RET_ReallyLR implicit [[BUILD_VECTOR]](<4 x p0>)
%0:_(p0) = COPY $x0
%1:_(p0) = COPY $x1
- %6:_(<4 x p0>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0,1,0,1)
+ %6:_(<4 x p0>) = G_BUILD_VECTOR %0, %1, %0, %1
RET_ReallyLR implicit %6
...
@@ -408,104 +408,6 @@ body: |
; CHECK-NEXT: RET_ReallyLR implicit [[BUILD_VECTOR]](<2 x p0>)
%0:_(p0) = COPY $x0
%1:_(p0) = COPY $x1
- %6:_(<2 x p0>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(1,0)
- RET_ReallyLR implicit %6
-...
-
-# Check that we properly use undef values when shuffle_vector
-# on scalars gets lowered to build_vector.
----
-name: shuffle_vector_on_scalars_to_build_vector_with_undef
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0, $x1
-
- ; CHECK-LABEL: name: shuffle_vector_on_scalars_to_build_vector_with_undef
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
- ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s64>) = G_BUILD_VECTOR [[COPY]](s64), [[DEF]](s64), [[DEF]](s64), [[COPY1]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit [[BUILD_VECTOR]](<4 x s64>)
- %0:_(s64) = COPY $x0
- %1:_(s64) = COPY $x1
- %6:_(<4 x s64>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0,-1,-1,1)
- RET_ReallyLR implicit %6
-...
-
-# Check that shuffle_vector on scalars gets combined into a plain
-# copy when the resulting type is a scalar as well and the sizes
-# are compatible.
----
-name: shuffle_vector_on_scalars_to_copy_ptr
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0
-
- ; CHECK-LABEL: name: shuffle_vector_on_scalars_to_copy_ptr
- ; CHECK: liveins: $x0
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
- ; CHECK-NEXT: RET_ReallyLR implicit [[COPY]](p0)
- %0:_(p0) = COPY $x0
- %6:_(p0) = G_SHUFFLE_VECTOR %0, %0, shufflemask(0)
- RET_ReallyLR implicit %6
-...
----
-name: shuffle_vector_to_copy_lhs
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0, $x1
-
- ; CHECK-LABEL: name: shuffle_vector_to_copy_lhs
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $x0
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 1
- ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit [[EVEC]](s32)
- %0:_(<2 x s32>) = COPY $x0
- %1:_(<2 x s32>) = COPY $x1
- %6:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(1)
- RET_ReallyLR implicit %6
-...
----
-name: shuffle_vector_to_copy_rhs
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0, $x1
-
- ; CHECK-LABEL: name: shuffle_vector_to_copy_rhs
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $x1
- ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
- ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[COPY]](<2 x s32>), [[C]](s64)
- ; CHECK-NEXT: RET_ReallyLR implicit [[EVEC]](s32)
- %0:_(<2 x s32>) = COPY $x0
- %1:_(<2 x s32>) = COPY $x1
- %6:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(2)
- RET_ReallyLR implicit %6
-...
----
-name: shuffle_vector_to_copy_undef
-tracksRegLiveness: true
-body: |
- bb.1:
- liveins: $x0, $x1
-
- ; CHECK-LABEL: name: shuffle_vector_to_copy_undef
- ; CHECK: liveins: $x0, $x1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
- ; CHECK-NEXT: RET_ReallyLR implicit [[DEF]](s32)
- %0:_(<2 x s32>) = COPY $x0
- %1:_(<2 x s32>) = COPY $x1
- %6:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(-1)
+ %6:_(<2 x p0>) = G_BUILD_VECTOR %1, %0
RET_ReallyLR implicit %6
...
diff --git a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.mir b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.mir
index c8bd8ab33f18c..423ce8219ecba 100644
--- a/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.mir
+++ b/llvm/test/CodeGen/AMDGPU/GlobalISel/legalize-shuffle-vector.mir
@@ -18,57 +18,11 @@ body: |
; CHECK-NEXT: $vgpr0_vgpr1 = COPY [[BUILD_VECTOR]](<2 x s32>)
%0:_(s32) = COPY $vgpr0
%1:_(s32) = COPY $vgpr1
- %2:_(<2 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 1)
+ %2:_(<2 x s32>) = G_BUILD_VECTOR %0, %1
$vgpr0_vgpr1 = COPY %2
...
----
-name: shufflevector_scalar_src_dst
-tracksRegLiveness: true
-
-body: |
- bb.0:
- liveins: $vgpr0, $vgpr1
-
- ; CHECK-LABEL: name: shufflevector_scalar_src_dst
- ; CHECK: liveins: $vgpr0, $vgpr1
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $vgpr0
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s32) = COPY $vgpr1
- ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY [[COPY1]](s32)
- ; CHECK-NEXT: $vgpr0 = COPY [[COPY2]](s32)
- %0:_(s32) = COPY $vgpr0
- %1:_(s32) = COPY $vgpr1
- %2:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(1)
- $vgpr0 = COPY %2
-
-...
-
----
-name: shufflevector_scalar_dst
-tracksRegLiveness: true
-
-body: |
- bb.0:
- liveins: $vgpr0_vgpr1, $vgpr2_vgpr3
-
- ; CHECK-LABEL: name: shufflevector_scalar_dst
- ; CHECK: liveins: $vgpr0_vgpr1, $vgpr2_vgpr3
- ; CHECK-NEXT: {{ $}}
- ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $vgpr0_vgpr1
- ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $vgpr2_vgpr3
- ; CHECK-NEXT: [[UV:%[0-9]+]]:_(s32), [[UV1:%[0-9]+]]:_(s32) = G_UNMERGE_VALUES [[COPY1]](<2 x s32>)
- ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s32) = COPY [[UV]](s32)
- ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s32) = COPY [[COPY2]](s32)
- ; CHECK-NEXT: $vgpr0 = COPY [[COPY3]](s32)
- %0:_(<2 x s32>) = COPY $vgpr0_vgpr1
- %1:_(<2 x s32>) = COPY $vgpr2_vgpr3
- %2:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(2)
- $vgpr0 = COPY %2
-
-...
-
---
name: shufflevector_v2s32_0_1
tracksRegLiveness: true
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
index dc1d4b289c2ab..d2f36effcbc67 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll
@@ -441,8 +441,7 @@ entry:
define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_v2s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
-; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
-; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0, 0)
+; CHECK: [[VEC:%[0-9]+]]:_(<2 x s32>) = G_BUILD_VECTOR [[ARG]](s32), [[ARG]](s32)
; CHECK: G_EXTRACT_VECTOR_ELT [[VEC]](<2 x s32>)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <2 x i32> zeroinitializer
@@ -453,8 +452,7 @@ define i32 @test_shufflevector_s32_v2s32(i32 %arg) {
define i32 @test_shufflevector_s32_s32_s32(i32 %arg) {
; CHECK-LABEL: name: test_shufflevector_s32_s32_s32
; CHECK: [[ARG:%[0-9]+]]:_(s32) = COPY $r0
-; CHECK-DAG: [[UNDEF:%[0-9]+]]:_(s32) = G_IMPLICIT_DEF
-; CHECK: [[VEC:%[0-9]+]]:_(s32) = G_SHUFFLE_VECTOR [[ARG]](s32), [[UNDEF]], shufflemask(0)
+; CHECK: r0 = COPY [[ARG]](s32)
%vec = insertelement <1 x i32> undef, i32 %arg, i32 0
%shuffle = shufflevector <1 x i32> %vec, <1 x i32> undef, <1 x i32> zeroinitializer
%res = extractelement <1 x i32> %shuffle, i32 0
diff --git a/llvm/test/CodeGen/MIR/AArch64/parse-shufflemask.mir b/llvm/test/CodeGen/MIR/AArch64/parse-shufflemask.mir
index c529d63d6b548..4cc3bc6b4c2d9 100644
--- a/llvm/test/CodeGen/MIR/AArch64/parse-shufflemask.mir
+++ b/llvm/test/CodeGen/MIR/AArch64/parse-shufflemask.mir
@@ -122,54 +122,3 @@ body: |
RET_ReallyLR implicit $d0
...
-
-# CHECK-LABEL: name: test_shuffle_0
-# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(0)
----
-name: test_shuffle_0
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $d0
-
- %0:_(<2 x s32>) = COPY $d0
- %2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(0)
- $w0 = COPY %1
- RET_ReallyLR implicit $w0
-
-...
-
-# CHECK-LABEL: name: test_shuffle_1
-# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1)
----
-name: test_shuffle_1
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $d0
-
- %0:_(<2 x s32>) = COPY $d0
- %2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(1)
- $w0 = COPY %1
- RET_ReallyLR implicit $w0
-
-...
-
-# CHECK-LABEL: name: test_shuffle_undef
-# CHECK: G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(undef)
----
-name: test_shuffle_undef
-tracksRegLiveness: true
-body: |
- bb.0:
- liveins: $d0
-
- %0:_(<2 x s32>) = COPY $d0
- %2:_(<2 x s32>) = G_IMPLICIT_DEF
- %1:_(s32) = G_SHUFFLE_VECTOR %0(<2 x s32>), %2, shufflemask(undef)
- $w0 = COPY %1
- RET_ReallyLR implicit $w0
-
-...
diff --git a/llvm/test/MachineVerifier/test_g_shuffle_vector.mir b/llvm/test/MachineVerifier/test_g_shuffle_vector.mir
index 6aba6731c9fee..9c5db7589bac3 100644
--- a/llvm/test/MachineVerifier/test_g_shuffle_vector.mir
+++ b/llvm/test/MachineVerifier/test_g_shuffle_vector.mir
@@ -52,8 +52,13 @@ body: |
; CHECK: Bad machine code: G_SHUFFLE_VECTOR cannot change element type
%21:_(s16) = G_SHUFFLE_VECTOR %3, %4, shufflemask(0)
+ ; CHECK: Bad machine code: G_SHUFFLE_VECTOR must have vector src
+ %22:_(<2 x s32>) = G_SHUFFLE_VECTOR %3, %4, shufflemask(0, 0)
+
+ ; CHECK: Bad machine code: G_SHUFFLE_VECTOR must have vector dst
+ %23:_(s32) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0)
+
; CHECK: Bad machine code: Out of bounds shuffle index
- %22:_(s32) = G_IMPLICIT_DEF
- %20:_(<2 x s32>) = G_SHUFFLE_VECTOR %22, %22, shufflemask(0, 2)
+ %20:_(<2 x s32>) = G_SHUFFLE_VECTOR %0, %1, shufflemask(0, 7)
...
More information about the llvm-commits
mailing list