[llvm] [AArch64][GlobalISel] Fold G_SHUFFLE to single-element TBL with zero elements. (PR #200938)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 13:48:19 PDT 2026
https://github.com/davemgreen created https://github.com/llvm/llvm-project/pull/200938
A TBL with out-of-range values will place zero into the respective vector lane. Use this to generate a more efficient 1 operand TBL where possible.
>From 4804b677d9c0137aeb0a93978fda58563beb224c Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 1 Jun 2026 18:56:22 +0100
Subject: [PATCH 1/2] [GlobalISel] Add known-bits for G_INSERT_VECTOR_ELT.
Mostly a copy of the SDAG equivalent code.
---
.../CodeGen/GlobalISel/GISelValueTracking.cpp | 30 +++++++
.../GlobalISel/knownbits-insert-vector.mir | 81 +++++++++++++++++++
2 files changed, 111 insertions(+)
create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir
diff --git a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
index ea4ab73700cf0..bf8d5e9fde619 100644
--- a/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/GISelValueTracking.cpp
@@ -870,6 +870,36 @@ void GISelValueTracking::computeKnownBitsImpl(Register R, KnownBits &Known,
computeKnownBitsImpl(InVec, Known, DemandedSrcElts, Depth + 1);
break;
}
+ case TargetOpcode::G_INSERT_VECTOR_ELT: {
+ GInsertVectorElement &Insert = cast<GInsertVectorElement>(MI);
+ Register InVec = Insert.getVectorReg();
+ Register InVal = Insert.getElementReg();
+ Register EltNo = Insert.getIndexReg();
+ LLT VecVT = MRI.getType(InVec);
+
+ if (VecVT.isScalableVector())
+ break;
+
+ auto ConstEltNo = getIConstantVRegVal(EltNo, MRI);
+
+ bool DemandedVal = true;
+ APInt DemandedVecElts = DemandedElts;
+ if (ConstEltNo) {
+ unsigned EltIdx = ConstEltNo->getZExtValue();
+ DemandedVal = !!DemandedElts[EltIdx];
+ DemandedVecElts.clearBit(EltIdx);
+ }
+ Known.setAllConflict();
+ if (DemandedVal) {
+ computeKnownBitsImpl(InVal, Known2, APInt(1, 1), Depth + 1);
+ Known = Known.intersectWith(Known2.zextOrTrunc(BitWidth));
+ }
+ if (!!DemandedVecElts) {
+ computeKnownBitsImpl(InVec, Known2, DemandedVecElts, Depth + 1);
+ Known = Known.intersectWith(Known2);
+ }
+ break;
+ }
case TargetOpcode::G_SHUFFLE_VECTOR: {
APInt DemandedLHS, DemandedRHS;
// Collect the known bits that are shared by every vector element referenced
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir
new file mode 100644
index 0000000000000..a148f301bfadf
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/knownbits-insert-vector.mir
@@ -0,0 +1,81 @@
+# NOTE: Assertions have been autogenerated by utils/update_givaluetracking_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -mtriple aarch64 -passes="print<gisel-value-tracking>" %s -filetype=null 2>&1 | FileCheck %s
+
+---
+name: all_knownbits_const_idx
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @all_knownbits_const_idx
+ ; CHECK-NEXT: %idx:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
+ ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+ ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4
+ ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4
+ ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5
+ ; CHECK-NEXT: %5:_ KnownBits:00000?1? SignBits:5
+ %idx:_(i64) = G_CONSTANT i64 1
+ %0:_(i8) = G_CONSTANT i8 3
+ %1:_(i8) = G_CONSTANT i8 15
+ %2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
+ %3:_(i8) = G_CONSTANT i8 6
+ %4:_(<2 x i8>) = G_INSERT_VECTOR_ELT %2, %3, %idx
+...
+---
+name: all_knownbits_unknown_lane
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @all_knownbits_unknown_lane
+ ; CHECK-NEXT: %idx:_ KnownBits:???????????????????????????????????????????????????????????????? SignBits:1
+ ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+ ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4
+ ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4
+ ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5
+ ; CHECK-NEXT: %5:_ KnownBits:0000??1? SignBits:4
+ %idx:_(i64) = COPY $x0
+ %0:_(i8) = G_CONSTANT i8 3
+ %1:_(i8) = G_CONSTANT i8 15
+ %2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
+ %3:_(i8) = G_CONSTANT i8 6
+ %4:_(<2 x i8>) = G_INSERT_VECTOR_ELT %2, %3, %idx
+...
+---
+name: all_knownbits_const_idx_demand_0
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @all_knownbits_const_idx_demand_0
+ ; CHECK-NEXT: %idx0:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64
+ ; CHECK-NEXT: %1:_ KnownBits:00000011 SignBits:6
+ ; CHECK-NEXT: %2:_ KnownBits:00001111 SignBits:4
+ ; CHECK-NEXT: %3:_ KnownBits:0000??11 SignBits:4
+ ; CHECK-NEXT: %4:_ KnownBits:00000110 SignBits:5
+ ; CHECK-NEXT: %5:_ KnownBits:0000?11? SignBits:4
+ ; CHECK-NEXT: %6:_ KnownBits:00000110 SignBits:5
+ %idx0:_(i64) = G_CONSTANT i64 0
+ %0:_(i8) = G_CONSTANT i8 3
+ %1:_(i8) = G_CONSTANT i8 15
+ %2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
+ %3:_(i8) = G_CONSTANT i8 6
+ %4:_(<2 x i8>) = G_INSERT_VECTOR_ELT %2, %3, %idx0
+ %5:_(i8) = G_EXTRACT_VECTOR_ELT %4, %idx0
+...
+---
+name: all_knownbits_const_idx_demand_1
+body: |
+ bb.0:
+ ; CHECK-LABEL: name: @all_knownbits_const_idx_demand_1
+ ; CHECK-NEXT: %idx0:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000000 SignBits:64
+ ; CHECK-NEXT: %idx1:_ KnownBits:0000000000000000000000000000000000000000000000000000000000000001 SignBits:63
+ ; CHECK-NEXT: %2:_ KnownBits:00000011 SignBits:6
+ ; CHECK-NEXT: %3:_ KnownBits:00001111 SignBits:4
+ ; CHECK-NEXT: %4:_ KnownBits:0000??11 SignBits:4
+ ; CHECK-NEXT: %5:_ KnownBits:00000110 SignBits:5
+ ; CHECK-NEXT: %6:_ KnownBits:0000?11? SignBits:4
+ ; CHECK-NEXT: %7:_ KnownBits:00001111 SignBits:4
+ %idx0:_(i64) = G_CONSTANT i64 0
+ %idx1:_(i64) = G_CONSTANT i64 1
+ %0:_(i8) = G_CONSTANT i8 3
+ %1:_(i8) = G_CONSTANT i8 15
+ %2:_(<2 x i8>) = G_BUILD_VECTOR %0, %1
+ %3:_(i8) = G_CONSTANT i8 6
+ %4:_(<2 x i8>) = G_INSERT_VECTOR_ELT %2, %3, %idx0
+ %5:_(i8) = G_EXTRACT_VECTOR_ELT %4, %idx1
+...
>From bd0fdda35678f521d3c2ce03b1bc487a869dc4b7 Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Mon, 1 Jun 2026 21:45:52 +0100
Subject: [PATCH 2/2] [AArch64][GlobalISel] Fold G_SHUFFLE to single-element
TBL with zero elements.
A TBL with out-of-range values will place zero into the respective vector
lane. Use this to generate a more efficient 1 operand TBL where possible.
---
.../GISel/AArch64InstructionSelector.cpp | 51 ++++++++++--
.../GlobalISel/select-shuffle-vector.mir | 78 +++++++++----------
.../AArch64/aarch64-matrix-umull-smull.ll | 2 +-
llvm/test/CodeGen/AArch64/arm64-dup.ll | 11 ++-
.../CodeGen/AArch64/arm64-neon-aba-abd.ll | 28 +++----
.../extend_inreg_of_concat_subvectors.ll | 22 +++---
.../AArch64/neon-bitwise-instructions.ll | 33 +++-----
7 files changed, 124 insertions(+), 101 deletions(-)
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
index cf650fd5c4e72..c1e6f05174d4b 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp
@@ -5134,25 +5134,54 @@ bool AArch64InstructionSelector::selectShuffleVector(
Register Src1Reg = I.getOperand(1).getReg();
Register Src2Reg = I.getOperand(2).getReg();
ArrayRef<int> Mask = I.getOperand(3).getShuffleMask();
+ assert(DstTy == MRI.getType(Src1Reg) &&
+ "Expected equal shuffle types during selection");
MachineBasicBlock &MBB = *I.getParent();
MachineFunction &MF = *MBB.getParent();
LLVMContext &Ctx = MF.getFunction().getContext();
unsigned BytesPerElt = DstTy.getElementType().getSizeInBits() / 8;
+ int NumElts = DstTy.getNumElements();
+
+ SmallVector<int> NewMask;
+ bool FirstUsed = false;
+ bool SecondUsed = false;
+ for (int M : Mask) {
+ // Map any undef or zero lanes to 255.
+ if (M < 0 || VT->getKnownBits(M < NumElts ? Src1Reg : Src2Reg,
+ APInt::getOneBitSet(NumElts, M % NumElts))
+ .isZero()) {
+ for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte)
+ NewMask.push_back(255);
+ continue;
+ }
- SmallVector<Constant *, 64> CstIdxs;
- for (int Val : Mask) {
- // For now, any undef indexes we'll just assume to be 0. This should be
- // optimized in future, e.g. to select DUP etc.
- Val = Val < 0 ? 0 : Val;
+ FirstUsed |= M < NumElts;
+ SecondUsed |= M >= NumElts;
for (unsigned Byte = 0; Byte < BytesPerElt; ++Byte) {
- unsigned Offset = Byte + Val * BytesPerElt;
- CstIdxs.emplace_back(ConstantInt::get(Type::getInt8Ty(Ctx), Offset));
+ unsigned Offset = Byte + M * BytesPerElt;
+ NewMask.push_back(Offset);
+ }
+ }
+
+ // If the first is unused or all zeros, use the second src in a tbl1.
+ if (!FirstUsed) {
+ int ByteLanes = DstTy.getSizeInBits() == 128 ? 16 : 8;
+ for (int &M : NewMask) {
+ if (M != 255) {
+ assert(M >= ByteLanes && M < 2 * ByteLanes);
+ M -= ByteLanes;
+ }
}
+ std::swap(Src1Reg, Src2Reg);
+ std::swap(FirstUsed, SecondUsed);
}
// Use a constant pool to load the index vector for TBL.
+ SmallVector<Constant *> CstIdxs;
+ transform(NewMask, std::back_inserter(CstIdxs),
+ [&Ctx](int M) { return ConstantInt::get(Type::getInt8Ty(Ctx), M); });
Constant *CPVal = ConstantVector::get(CstIdxs);
MachineInstr *IndexLoad = emitLoadFromConstantPool(CPVal, MIB);
if (!IndexLoad) {
@@ -5187,6 +5216,14 @@ bool AArch64InstructionSelector::selectShuffleVector(
return true;
}
+ if (!SecondUsed) {
+ auto TBL1 = MIB.buildInstr(AArch64::TBLv16i8One, {I.getOperand(0)},
+ {Src1Reg, IndexLoad->getOperand(0)});
+ constrainSelectedInstRegOperands(*TBL1, TII, TRI, RBI);
+ I.eraseFromParent();
+ return true;
+ }
+
// For TBL2 we need to emit a REG_SEQUENCE to tie together two consecutive
// Q registers for regalloc.
SmallVector<Register, 2> Regs = {Src1Reg, Src2Reg};
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir
index 345cc774f9963..3e64b69d19eb3 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/select-shuffle-vector.mir
@@ -44,21 +44,22 @@ body: |
; CHECK: value: '<8 x i8> <i8 4, i8 5, i8 6, i8 7, i8 0, i8 1, i8 2, i8 3>'
; CHECK: alignment: 8
; CHECK: liveins: $d0, $d1
- ; CHECK: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
- ; CHECK: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1
- ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
- ; CHECK: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
- ; CHECK: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF
- ; CHECK: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.dsub
- ; CHECK: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF
- ; CHECK: [[INSERT_SUBREG1:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF1]], [[COPY1]], %subreg.dsub
- ; CHECK: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0
- ; CHECK: [[DEF2:%[0-9]+]]:fpr128 = IMPLICIT_DEF
- ; CHECK: [[INSERT_SUBREG2:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF2]], [[LDRDui]], %subreg.dsub
- ; CHECK: [[TBLv16i8One:%[0-9]+]]:fpr128 = TBLv16i8One [[INSvi64lane]], [[INSERT_SUBREG2]]
- ; CHECK: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub
- ; CHECK: $d0 = COPY [[COPY2]]
- ; CHECK: RET_ReallyLR implicit $d0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr64 = COPY $d0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr64 = COPY $d1
+ ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+ ; CHECK-NEXT: [[LDRDui:%[0-9]+]]:fpr64 = LDRDui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s64) from constant-pool)
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[INSERT_SUBREG:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF]], [[COPY]], %subreg.dsub
+ ; CHECK-NEXT: [[DEF1:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[INSERT_SUBREG1:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF1]], [[COPY1]], %subreg.dsub
+ ; CHECK-NEXT: [[INSvi64lane:%[0-9]+]]:fpr128 = INSvi64lane [[INSERT_SUBREG]], 1, [[INSERT_SUBREG1]], 0
+ ; CHECK-NEXT: [[DEF2:%[0-9]+]]:fpr128 = IMPLICIT_DEF
+ ; CHECK-NEXT: [[INSERT_SUBREG2:%[0-9]+]]:fpr128 = INSERT_SUBREG [[DEF2]], [[LDRDui]], %subreg.dsub
+ ; CHECK-NEXT: [[TBLv16i8One:%[0-9]+]]:fpr128 = TBLv16i8One [[INSvi64lane]], [[INSERT_SUBREG2]]
+ ; CHECK-NEXT: [[COPY2:%[0-9]+]]:fpr64 = COPY [[TBLv16i8One]].dsub
+ ; CHECK-NEXT: $d0 = COPY [[COPY2]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $d0
%0:fpr(<2 x s32>) = COPY $d0
%1:fpr(<2 x s32>) = COPY $d1
%2:fpr(<2 x s32>) = G_SHUFFLE_VECTOR %0(<2 x s32>), %1, shufflemask(1, 0)
@@ -82,14 +83,13 @@ body: |
; CHECK: alignment: 16
; CHECK: isTargetSpecific: false
; CHECK: liveins: $q0, $q1
- ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
- ; CHECK: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1
- ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
- ; CHECK: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
- ; CHECK: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE [[COPY]], %subreg.qsub0, [[COPY1]], %subreg.qsub1
- ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]]
- ; CHECK: $q0 = COPY [[TBLv16i8Two]]
- ; CHECK: RET_ReallyLR implicit $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+ ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+ ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+ ; CHECK-NEXT: [[TBLv16i8One:%[0-9]+]]:fpr128 = TBLv16i8One [[COPY]], [[LDRQui]]
+ ; CHECK-NEXT: $q0 = COPY [[TBLv16i8One]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
%0:fpr(<4 x s32>) = COPY $q0
%1:fpr(<4 x s32>) = COPY $q1
%2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(0, 1, 3, 0)
@@ -113,14 +113,15 @@ body: |
; CHECK: alignment: 16
; CHECK: isTargetSpecific: false
; CHECK: liveins: $q0, $q1
- ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
- ; CHECK: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1
- ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
- ; CHECK: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
- ; CHECK: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE [[COPY]], %subreg.qsub0, [[COPY1]], %subreg.qsub1
- ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]]
- ; CHECK: $q0 = COPY [[TBLv16i8Two]]
- ; CHECK: RET_ReallyLR implicit $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+ ; CHECK-NEXT: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1
+ ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+ ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+ ; CHECK-NEXT: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE [[COPY]], %subreg.qsub0, [[COPY1]], %subreg.qsub1
+ ; CHECK-NEXT: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]]
+ ; CHECK-NEXT: $q0 = COPY [[TBLv16i8Two]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
%0:fpr(<4 x s32>) = COPY $q0
%1:fpr(<4 x s32>) = COPY $q1
%2:fpr(<4 x s32>) = G_SHUFFLE_VECTOR %0(<4 x s32>), %1, shufflemask(5, 7, 1, 0)
@@ -144,14 +145,13 @@ body: |
; CHECK: alignment: 16
; CHECK: isTargetSpecific: false
; CHECK: liveins: $q0, $q1
- ; CHECK: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
- ; CHECK: [[COPY1:%[0-9]+]]:fpr128 = COPY $q1
- ; CHECK: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
- ; CHECK: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0
- ; CHECK: [[REG_SEQUENCE:%[0-9]+]]:qq = REG_SEQUENCE [[COPY]], %subreg.qsub0, [[COPY1]], %subreg.qsub1
- ; CHECK: [[TBLv16i8Two:%[0-9]+]]:fpr128 = TBLv16i8Two [[REG_SEQUENCE]], [[LDRQui]]
- ; CHECK: $q0 = COPY [[TBLv16i8Two]]
- ; CHECK: RET_ReallyLR implicit $q0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:fpr128 = COPY $q0
+ ; CHECK-NEXT: [[ADRP:%[0-9]+]]:gpr64common = ADRP target-flags(aarch64-page) %const.0
+ ; CHECK-NEXT: [[LDRQui:%[0-9]+]]:fpr128 = LDRQui [[ADRP]], target-flags(aarch64-pageoff, aarch64-nc) %const.0 :: (load (s128) from constant-pool)
+ ; CHECK-NEXT: [[TBLv16i8One:%[0-9]+]]:fpr128 = TBLv16i8One [[COPY]], [[LDRQui]]
+ ; CHECK-NEXT: $q0 = COPY [[TBLv16i8One]]
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
%0:fpr(<2 x s64>) = COPY $q0
%1:fpr(<2 x s64>) = COPY $q1
%2:fpr(<2 x s64>) = G_SHUFFLE_VECTOR %0(<2 x s64>), %1, shufflemask(1, 0)
diff --git a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
index ea55c198a70f1..4f21845bf68f4 100644
--- a/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
+++ b/llvm/test/CodeGen/AArch64/aarch64-matrix-umull-smull.ll
@@ -208,7 +208,7 @@ define void @matrix_mul_double_shuffle(i32 %N, ptr nocapture %C, ptr nocapture r
; CHECK-GI-NEXT: mov w9, w0
; CHECK-GI-NEXT: add w0, w0, #8
; CHECK-GI-NEXT: lsl x9, x9, #2
-; CHECK-GI-NEXT: tbl v2.16b, { v2.16b, v3.16b }, v1.16b
+; CHECK-GI-NEXT: tbl v2.16b, { v2.16b }, v1.16b
; CHECK-GI-NEXT: mul v2.4s, v0.4s, v2.4s
; CHECK-GI-NEXT: str q2, [x1, x9]
; CHECK-GI-NEXT: b.ne .LBB2_1
diff --git a/llvm/test/CodeGen/AArch64/arm64-dup.ll b/llvm/test/CodeGen/AArch64/arm64-dup.ll
index 49fb6c98e223f..7ad8f837d8131 100644
--- a/llvm/test/CodeGen/AArch64/arm64-dup.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-dup.ll
@@ -511,14 +511,13 @@ define void @disguised_dup(<4 x float> %x, ptr %p1, ptr %p2) {
; CHECK-GI-LABEL: disguised_dup:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: adrp x8, .LCPI38_1
-; CHECK-GI-NEXT: // kill: def $q0 killed $q0 def $q0_q1
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI38_1]
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI38_1]
; CHECK-GI-NEXT: adrp x8, .LCPI38_0
-; CHECK-GI-NEXT: tbl.16b v0, { v0, v1 }, v2
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI38_0]
-; CHECK-GI-NEXT: tbl.16b v2, { v0, v1 }, v2
+; CHECK-GI-NEXT: tbl.16b v0, { v0 }, v1
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI38_0]
+; CHECK-GI-NEXT: tbl.16b v1, { v0 }, v1
; CHECK-GI-NEXT: str q0, [x0]
-; CHECK-GI-NEXT: str q2, [x1]
+; CHECK-GI-NEXT: str q1, [x1]
; CHECK-GI-NEXT: ret
%shuf = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> <i32 1, i32 2, i32 0, i32 0>
%dup = shufflevector <4 x float> %shuf, <4 x float> undef, <4 x i32> <i32 3, i32 2, i32 2, i32 3>
diff --git a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
index 9ffda5b9b0af9..e6f2d4248084f 100644
--- a/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-neon-aba-abd.ll
@@ -488,11 +488,11 @@ define <4 x i32> @test_sabd_knownbits_vec4i32(<4 x i32> %lhs, <4 x i32> %rhs) {
; CHECK-GI-NEXT: adrp x8, .LCPI43_0
; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: and v1.16b, v1.16b, v3.16b
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI43_0]
-; CHECK-GI-NEXT: movi v3.2d, #0x0000ff000000ff
+; CHECK-GI-NEXT: movi v2.2d, #0x0000ff000000ff
; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
-; CHECK-GI-NEXT: and v0.16b, v0.16b, v3.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI43_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
+; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: ret
%and1 = and <4 x i32> %lhs, <i32 255, i32 -1, i32 -1, i32 255>
%and2 = and <4 x i32> %rhs, <i32 255, i32 255, i32 -1, i32 -1>
@@ -520,9 +520,9 @@ define <4 x i32> @knownbits_sabd_and_mask(<4 x i32> %a0, <4 x i32> %a1) {
; CHECK-GI-NEXT: adrp x8, .LCPI44_0
; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI44_0]
; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI44_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
%2 = and <4 x i32> %a1, <i32 -1, i32 -1, i32 255, i32 4085>
@@ -545,11 +545,11 @@ define <4 x i32> @knownbits_sabd_and_or_mask(<4 x i32> %a0, <4 x i32> %a1) {
; CHECK-GI-NEXT: adrp x8, .LCPI45_0
; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI45_0]
; CHECK-GI-NEXT: orr v0.16b, v0.16b, v3.16b
; CHECK-GI-NEXT: orr v1.16b, v1.16b, v3.16b
; CHECK-GI-NEXT: uabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI45_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
%2 = or <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>
@@ -582,11 +582,11 @@ define <4 x i32> @knownbits_sabd_and_xor_mask(<4 x i32> %a0, <4 x i32> %a1) {
; CHECK-GI-NEXT: adrp x8, .LCPI46_0
; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI46_0]
; CHECK-GI-NEXT: eor v0.16b, v0.16b, v3.16b
; CHECK-GI-NEXT: eor v1.16b, v1.16b, v3.16b
; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI46_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%1 = and <4 x i32> %a0, <i32 -1, i32 -1, i32 255, i32 4085>
%2 = xor <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>
@@ -610,11 +610,11 @@ define <4 x i32> @knownbits_sabd_and_shl_mask(<4 x i32> %a0, <4 x i32> %a1) {
; CHECK-GI-NEXT: adrp x8, .LCPI47_0
; CHECK-GI-NEXT: and v0.16b, v0.16b, v2.16b
; CHECK-GI-NEXT: and v1.16b, v1.16b, v2.16b
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI47_0]
; CHECK-GI-NEXT: shl v0.4s, v0.4s, #17
; CHECK-GI-NEXT: shl v1.4s, v1.4s, #17
; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI47_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>
%2 = shl <4 x i32> %1, <i32 17, i32 17, i32 17, i32 17>
@@ -648,9 +648,9 @@ define <4 x i32> @knownbits_sabd_and_mul_mask(<4 x i32> %a0, <4 x i32> %a1) {
; CHECK-GI-NEXT: and v2.16b, v1.16b, v2.16b
; CHECK-GI-NEXT: mul v0.4s, v0.4s, v3.4s
; CHECK-GI-NEXT: mul v1.4s, v1.4s, v2.4s
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI48_0]
; CHECK-GI-NEXT: sabd v0.4s, v0.4s, v1.4s
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI48_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%1 = and <4 x i32> %a0, <i32 -65536, i32 -7, i32 -7, i32 -65536>
%2 = mul <4 x i32> %a0, %1
diff --git a/llvm/test/CodeGen/AArch64/extend_inreg_of_concat_subvectors.ll b/llvm/test/CodeGen/AArch64/extend_inreg_of_concat_subvectors.ll
index 6df8d2be6deab..4136185f84cbc 100644
--- a/llvm/test/CodeGen/AArch64/extend_inreg_of_concat_subvectors.ll
+++ b/llvm/test/CodeGen/AArch64/extend_inreg_of_concat_subvectors.ll
@@ -32,14 +32,13 @@ define void @zext_of_concat(ptr %a, ptr %b, ptr %c, ptr %d) nounwind {
; CHECK-LE-GI: ; %bb.0:
; CHECK-LE-GI-NEXT: ldr d0, [x0]
; CHECK-LE-GI-NEXT: ldr d1, [x1]
-; CHECK-LE-GI-NEXT: movi.2d v3, #0000000000000000
; CHECK-LE-GI-NEXT: Lloh0:
; CHECK-LE-GI-NEXT: adrp x8, lCPI0_0 at PAGE
-; CHECK-LE-GI-NEXT: add.2s v2, v0, v1
+; CHECK-LE-GI-NEXT: add.2s v0, v0, v1
; CHECK-LE-GI-NEXT: Lloh1:
-; CHECK-LE-GI-NEXT: ldr q0, [x8, lCPI0_0 at PAGEOFF]
+; CHECK-LE-GI-NEXT: ldr q1, [x8, lCPI0_0 at PAGEOFF]
+; CHECK-LE-GI-NEXT: tbl.16b v0, { v0 }, v1
; CHECK-LE-GI-NEXT: ldr q1, [x2]
-; CHECK-LE-GI-NEXT: tbl.16b v0, { v2, v3 }, v0
; CHECK-LE-GI-NEXT: add.4s v0, v0, v1
; CHECK-LE-GI-NEXT: str q0, [x2]
; CHECK-LE-GI-NEXT: ret
@@ -89,17 +88,16 @@ define void @zext_of_concat_extrause(ptr %a, ptr %b, ptr %c, ptr %d, ptr %e) nou
; CHECK-LE-GI: ; %bb.0:
; CHECK-LE-GI-NEXT: ldr d0, [x0]
; CHECK-LE-GI-NEXT: ldr d1, [x1]
-; CHECK-LE-GI-NEXT: movi.2d v3, #0000000000000000
; CHECK-LE-GI-NEXT: Lloh2:
; CHECK-LE-GI-NEXT: adrp x8, lCPI1_0 at PAGE
-; CHECK-LE-GI-NEXT: add.2s v2, v0, v1
+; CHECK-LE-GI-NEXT: add.2s v0, v0, v1
; CHECK-LE-GI-NEXT: Lloh3:
-; CHECK-LE-GI-NEXT: ldr q0, [x8, lCPI1_0 at PAGEOFF]
-; CHECK-LE-GI-NEXT: mov.d v2[1], v2[0]
-; CHECK-LE-GI-NEXT: tbl.16b v0, { v2, v3 }, v0
-; CHECK-LE-GI-NEXT: str q2, [x4]
-; CHECK-LE-GI-NEXT: ldr q1, [x2]
-; CHECK-LE-GI-NEXT: add.4s v0, v0, v1
+; CHECK-LE-GI-NEXT: ldr q1, [x8, lCPI1_0 at PAGEOFF]
+; CHECK-LE-GI-NEXT: mov.d v0[1], v0[0]
+; CHECK-LE-GI-NEXT: tbl.16b v1, { v0 }, v1
+; CHECK-LE-GI-NEXT: str q0, [x4]
+; CHECK-LE-GI-NEXT: ldr q0, [x2]
+; CHECK-LE-GI-NEXT: add.4s v0, v1, v0
; CHECK-LE-GI-NEXT: str q0, [x2]
; CHECK-LE-GI-NEXT: ret
; CHECK-LE-GI-NEXT: .loh AdrpLdr Lloh2, Lloh3
diff --git a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
index 9f25ed09ffcec..1f761139a7fe2 100644
--- a/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
+++ b/llvm/test/CodeGen/AArch64/neon-bitwise-instructions.ll
@@ -1304,9 +1304,9 @@ define <8 x i8> @vselect_equivalent_shuffle_v8i8_zeroswap(<8 x i8> %a) {
; CHECK-GI-NEXT: movi v1.2d, #0000000000000000
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
; CHECK-GI-NEXT: adrp x8, .LCPI91_0
-; CHECK-GI-NEXT: mov v1.d[1], v0.d[0]
-; CHECK-GI-NEXT: ldr d0, [x8, :lo12:.LCPI91_0]
-; CHECK-GI-NEXT: tbl v0.16b, { v1.16b }, v0.16b
+; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]
+; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI91_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
; CHECK-GI-NEXT: ret
%c = shufflevector <8 x i8> zeroinitializer, <8 x i8> %a, <8 x i32> <i32 8, i32 0, i32 10, i32 1, i32 12, i32 13, i32 14, i32 15>
@@ -1371,11 +1371,9 @@ define <8 x i16> @vselect_equivalent_shuffle_v8i16_zero(<8 x i16> %a) {
;
; CHECK-GI-LABEL: vselect_equivalent_shuffle_v8i16_zero:
; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: // kill: def $q0 killed $q0 def $q0_q1
; CHECK-GI-NEXT: adrp x8, .LCPI93_0
-; CHECK-GI-NEXT: movi v1.2d, #0000000000000000
-; CHECK-GI-NEXT: ldr q2, [x8, :lo12:.LCPI93_0]
-; CHECK-GI-NEXT: tbl v0.16b, { v0.16b, v1.16b }, v2.16b
+; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI93_0]
+; CHECK-GI-NEXT: tbl v0.16b, { v0.16b }, v1.16b
; CHECK-GI-NEXT: ret
%c = shufflevector <8 x i16> %a, <8 x i16> zeroinitializer, <8 x i32> <i32 0, i32 8, i32 2, i32 9, i32 4, i32 5, i32 6, i32 7>
ret <8 x i16> %c
@@ -1398,21 +1396,12 @@ define <8 x i16> @vselect_equivalent_shuffle_v8i16_zero(<8 x i16> %a) {
; CHECK-SD: .byte 14
; CHECK-SD: .byte 15
define <8 x i16> @vselect_equivalent_shuffle_v8i16_zeroswap(<8 x i16> %a) {
-; CHECK-SD-LABEL: vselect_equivalent_shuffle_v8i16_zeroswap:
-; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: adrp x8, .LCPI94_0
-; CHECK-SD-NEXT: ldr q1, [x8, :lo12:.LCPI94_0]
-; CHECK-SD-NEXT: tbl v0.16b, { v0.16b }, v1.16b
-; CHECK-SD-NEXT: ret
-;
-; CHECK-GI-LABEL: vselect_equivalent_shuffle_v8i16_zeroswap:
-; CHECK-GI: // %bb.0:
-; CHECK-GI-NEXT: // kill: def $q0 killed $q0 def $q31_q0
-; CHECK-GI-NEXT: adrp x8, .LCPI94_0
-; CHECK-GI-NEXT: movi v31.2d, #0000000000000000
-; CHECK-GI-NEXT: ldr q1, [x8, :lo12:.LCPI94_0]
-; CHECK-GI-NEXT: tbl v0.16b, { v31.16b, v0.16b }, v1.16b
-; CHECK-GI-NEXT: ret
+; CHECK-LABEL: vselect_equivalent_shuffle_v8i16_zeroswap:
+; CHECK: // %bb.0:
+; CHECK-NEXT: adrp x8, .LCPI94_0
+; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI94_0]
+; CHECK-NEXT: tbl v0.16b, { v0.16b }, v1.16b
+; CHECK-NEXT: ret
%c = shufflevector <8 x i16> zeroinitializer, <8 x i16> %a, <8 x i32> <i32 8, i32 0, i32 10, i32 1, i32 12, i32 13, i32 14, i32 15>
ret <8 x i16> %c
}
More information about the llvm-commits
mailing list