[llvm] [AArch64] Fix tryToConvertShuffleOfTbl2ToTbl4 with non-buildvectror input outoperands. (PR #135961)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 16 06:29:29 PDT 2025
https://github.com/davemgreen updated https://github.com/llvm/llvm-project/pull/135961
>From 7bd988807e02f884204efa4885b54d1aee6b84ea Mon Sep 17 00:00:00 2001
From: David Green <david.green at arm.com>
Date: Wed, 16 Apr 2025 14:29:20 +0100
Subject: [PATCH] [AArch64] Fix tryToConvertShuffleOfTbl2ToTbl4 with
non-buildvectror input outoperands.
It looks like this code is only considering buildvector inputs, expecting the
inputs to have at least 16 operands. This adds a check to make sure that is
true.
Fixes #135950
---
.../Target/AArch64/AArch64ISelLowering.cpp | 24 ++++++++-------
llvm/test/CodeGen/AArch64/arm64-tbl.ll | 30 +++++++++++++++++++
2 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index a95d8d343adf2..2cd28dd21f7d1 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -13871,25 +13871,27 @@ static SDValue tryToConvertShuffleOfTbl2ToTbl4(SDValue Op,
DAG.getTargetConstant(Intrinsic::aarch64_neon_tbl2, dl, MVT::i64);
EVT VT = Op.getValueType();
- if (Tbl1->getOpcode() != ISD::INTRINSIC_WO_CHAIN ||
- Tbl1->getOperand(0) != Tbl2ID ||
- Tbl2->getOpcode() != ISD::INTRINSIC_WO_CHAIN ||
- Tbl2->getOperand(0) != Tbl2ID)
+ if (Tbl1.getOpcode() != ISD::INTRINSIC_WO_CHAIN ||
+ Tbl1.getOperand(0) != Tbl2ID ||
+ Tbl2.getOpcode() != ISD::INTRINSIC_WO_CHAIN ||
+ Tbl2.getOperand(0) != Tbl2ID)
return SDValue();
- if (Tbl1->getValueType(0) != MVT::v16i8 ||
- Tbl2->getValueType(0) != MVT::v16i8)
+ if (Tbl1.getValueType() != MVT::v16i8 || Tbl2.getValueType() != MVT::v16i8)
+ return SDValue();
+
+ SDValue Mask1 = Tbl1.getOperand(3);
+ SDValue Mask2 = Tbl2.getOperand(3);
+ if (Mask1.getOpcode() != ISD::BUILD_VECTOR ||
+ Mask2.getOpcode() != ISD::BUILD_VECTOR)
return SDValue();
- SDValue Mask1 = Tbl1->getOperand(3);
- SDValue Mask2 = Tbl2->getOperand(3);
SmallVector<SDValue, 16> TBLMaskParts(16, SDValue());
for (unsigned I = 0; I < 16; I++) {
if (ShuffleMask[I] < 16)
- TBLMaskParts[I] = Mask1->getOperand(ShuffleMask[I]);
+ TBLMaskParts[I] = Mask1.getOperand(ShuffleMask[I]);
else {
- auto *C =
- dyn_cast<ConstantSDNode>(Mask2->getOperand(ShuffleMask[I] - 16));
+ auto *C = dyn_cast<ConstantSDNode>(Mask2.getOperand(ShuffleMask[I] - 16));
if (!C)
return SDValue();
TBLMaskParts[I] = DAG.getConstant(C->getSExtValue() + 32, dl, MVT::i32);
diff --git a/llvm/test/CodeGen/AArch64/arm64-tbl.ll b/llvm/test/CodeGen/AArch64/arm64-tbl.ll
index a854cb7fec991..fe5a6f12a49c3 100644
--- a/llvm/test/CodeGen/AArch64/arm64-tbl.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-tbl.ll
@@ -1254,6 +1254,36 @@ define <16 x i8> @tbx4_16b(<16 x i8> %A, <16 x i8> %B, <16 x i8> %C, <16 x i8> %
ret <16 x i8> %tmp3
}
+define <16 x i8> @pr135950(<16 x i8> %A, <16 x i8> %B, <16 x i8> %M) {
+; CHECK-SD-LABEL: pr135950:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: mov.16b v3, v1
+; CHECK-SD-NEXT: movi.2d v1, #0000000000000000
+; CHECK-SD-NEXT: mov.16b v4, v0
+; CHECK-SD-NEXT: mov.16b v5, v3
+; CHECK-SD-NEXT: tbl.16b v1, { v3, v4 }, v1
+; CHECK-SD-NEXT: tbl.16b v0, { v4, v5 }, v2
+; CHECK-SD-NEXT: zip1.16b v0, v0, v1
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: pr135950:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: // kill: def $q0 killed $q0 killed $q0_q1_q2 def $q0_q1_q2
+; CHECK-GI-NEXT: mov.16b v3, v2
+; CHECK-GI-NEXT: movi.2d v4, #0000000000000000
+; CHECK-GI-NEXT: // kill: def $q1 killed $q1 killed $q0_q1_q2 def $q0_q1_q2
+; CHECK-GI-NEXT: tbl.16b v3, { v0, v1 }, v3
+; CHECK-GI-NEXT: mov.16b v2, v0
+; CHECK-GI-NEXT: tbl.16b v0, { v1, v2 }, v4
+; CHECK-GI-NEXT: zip1.16b v0, v3, v0
+; CHECK-GI-NEXT: ret
+ %t1 = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> %A, <16 x i8> %B, <16 x i8> %M)
+ %t2 = call <16 x i8> @llvm.aarch64.neon.tbl2.v16i8(<16 x i8> %B, <16 x i8> %A, <16 x i8> zeroinitializer)
+ %s = shufflevector <16 x i8> %t1, <16 x i8> %t2, <16 x i32> <i32 0, i32 16, i32 1, i32 17, i32 2, i32 18, i32 3, i32 19, i32 4, i32 20, i32 5, i32 21, i32 6, i32 22, i32 7, i32 23>
+ ret <16 x i8> %s
+}
+
+
declare <8 x i8> @llvm.aarch64.neon.tbx1.v8i8(<8 x i8>, <16 x i8>, <8 x i8>) nounwind readnone
declare <16 x i8> @llvm.aarch64.neon.tbx1.v16i8(<16 x i8>, <16 x i8>, <16 x i8>) nounwind readnone
declare <8 x i8> @llvm.aarch64.neon.tbx2.v8i8(<8 x i8>, <16 x i8>, <16 x i8>, <8 x i8>) nounwind readnone
More information about the llvm-commits
mailing list