[llvm] 9892dc1 - [AArch64] Fix vectorToScalarBitmask BE (#156314)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 7 05:33:17 PDT 2025
Author: Giuseppe Cesarano
Date: 2025-09-07T13:33:13+01:00
New Revision: 9892dc1d3433fd55f163a29421e18ed596550bda
URL: https://github.com/llvm/llvm-project/commit/9892dc1d3433fd55f163a29421e18ed596550bda
DIFF: https://github.com/llvm/llvm-project/commit/9892dc1d3433fd55f163a29421e18ed596550bda.diff
LOG: [AArch64] Fix vectorToScalarBitmask BE (#156314)
Closes #156312
Added:
llvm/test/CodeGen/AArch64/vector-to-scalar-bitmask.ll
Modified:
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index e788bee6be322..cdf5e4e394f97 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -24329,6 +24329,7 @@ static SDValue vectorToScalarBitmask(SDNode *N, SelectionDAG &DAG) {
// Ensure that all elements' bits are either 0s or 1s.
ComparisonResult = DAG.getSExtOrTrunc(ComparisonResult, DL, VecVT);
+ bool IsLE = DAG.getDataLayout().isLittleEndian();
SmallVector<SDValue, 16> MaskConstants;
if (DAG.getSubtarget<AArch64Subtarget>().isNeonAvailable() &&
VecVT == MVT::v16i8) {
@@ -24336,7 +24337,10 @@ static SDValue vectorToScalarBitmask(SDNode *N, SelectionDAG &DAG) {
// per entry. We split it into two halves, apply the mask, zip the halves to
// create 8x 16-bit values, and the perform the vector reduce.
for (unsigned Half = 0; Half < 2; ++Half) {
- for (unsigned MaskBit = 1; MaskBit <= 128; MaskBit *= 2) {
+ for (unsigned I = 0; I < 8; ++I) {
+ // On big-endian targets, the lane order in sub-byte vector elements
+ // gets reversed, so we need to flip the bit index.
+ unsigned MaskBit = IsLE ? (1u << I) : (1u << (7 - I));
MaskConstants.push_back(DAG.getConstant(MaskBit, DL, MVT::i32));
}
}
@@ -24354,8 +24358,9 @@ static SDValue vectorToScalarBitmask(SDNode *N, SelectionDAG &DAG) {
}
// All other vector sizes.
- unsigned MaxBitMask = 1u << (VecVT.getVectorNumElements() - 1);
- for (unsigned MaskBit = 1; MaskBit <= MaxBitMask; MaskBit *= 2) {
+ unsigned NumEl = VecVT.getVectorNumElements();
+ for (unsigned I = 0; I < NumEl; ++I) {
+ unsigned MaskBit = IsLE ? (1u << I) : (1u << (NumEl - 1 - I));
MaskConstants.push_back(DAG.getConstant(MaskBit, DL, MVT::i64));
}
diff --git a/llvm/test/CodeGen/AArch64/vector-to-scalar-bitmask.ll b/llvm/test/CodeGen/AArch64/vector-to-scalar-bitmask.ll
new file mode 100644
index 0000000000000..01c83ca220b65
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/vector-to-scalar-bitmask.ll
@@ -0,0 +1,75 @@
+; RUN: llc -O3 -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK-LE
+; RUN: llc -O3 -mtriple=aarch64_be-linux-gnu %s -o - | FileCheck %s --check-prefix=CHECK-BE
+
+define i16 @convert_to_bitmask16(<16 x i8> %vec) {
+ %cmp_result = icmp ne <16 x i8> %vec, zeroinitializer
+ %bitmask = bitcast <16 x i1> %cmp_result to i16
+ ret i16 %bitmask
+}
+
+define i16 @convert_to_bitmask8(<8 x i16> %vec) {
+ %cmp_result = icmp ne <8 x i16> %vec, zeroinitializer
+ %bitmask = bitcast <8 x i1> %cmp_result to i8
+ %extended_bitmask = zext i8 %bitmask to i16
+ ret i16 %extended_bitmask
+}
+
+; Little endian
+
+; CHECK-LE-LABEL: .LCPI0_0:
+; CHECK-LE-NEXT: .byte 1
+; CHECK-LE-NEXT: .byte 2
+; CHECK-LE-NEXT: .byte 4
+; CHECK-LE-NEXT: .byte 8
+; CHECK-LE-NEXT: .byte 16
+; CHECK-LE-NEXT: .byte 32
+; CHECK-LE-NEXT: .byte 64
+; CHECK-LE-NEXT: .byte 128
+; CHECK-LE-NEXT: .byte 1
+; CHECK-LE-NEXT: .byte 2
+; CHECK-LE-NEXT: .byte 4
+; CHECK-LE-NEXT: .byte 8
+; CHECK-LE-NEXT: .byte 16
+; CHECK-LE-NEXT: .byte 32
+; CHECK-LE-NEXT: .byte 64
+; CHECK-LE-NEXT: .byte 128
+
+; CHECK-LE-LABEL: .LCPI1_0:
+; CHECK-LE-NEXT: .hword 1
+; CHECK-LE-NEXT: .hword 2
+; CHECK-LE-NEXT: .hword 4
+; CHECK-LE-NEXT: .hword 8
+; CHECK-LE-NEXT: .hword 16
+; CHECK-LE-NEXT: .hword 32
+; CHECK-LE-NEXT: .hword 64
+; CHECK-LE-NEXT: .hword 128
+
+; Big endian
+
+; CHECK-BE-LABEL: .LCPI0_0:
+; CHECK-BE-NEXT: .byte 128
+; CHECK-BE-NEXT: .byte 64
+; CHECK-BE-NEXT: .byte 32
+; CHECK-BE-NEXT: .byte 16
+; CHECK-BE-NEXT: .byte 8
+; CHECK-BE-NEXT: .byte 4
+; CHECK-BE-NEXT: .byte 2
+; CHECK-BE-NEXT: .byte 1
+; CHECK-BE-NEXT: .byte 128
+; CHECK-BE-NEXT: .byte 64
+; CHECK-BE-NEXT: .byte 32
+; CHECK-BE-NEXT: .byte 16
+; CHECK-BE-NEXT: .byte 8
+; CHECK-BE-NEXT: .byte 4
+; CHECK-BE-NEXT: .byte 2
+; CHECK-BE-NEXT: .byte 1
+
+; CHECK-BE-LABEL: .LCPI1_0:
+; CHECK-BE-NEXT: .hword 128
+; CHECK-BE-NEXT: .hword 64
+; CHECK-BE-NEXT: .hword 32
+; CHECK-BE-NEXT: .hword 16
+; CHECK-BE-NEXT: .hword 8
+; CHECK-BE-NEXT: .hword 4
+; CHECK-BE-NEXT: .hword 2
+; CHECK-BE-NEXT: .hword 1
More information about the llvm-commits
mailing list