[llvm] 2343ad7 - [AArch64] Add index check before lowerInterleavedStore() uses ShuffleVectorInst's mask

David Green via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 10 04:52:40 PDT 2022


Author: Peter Rong
Date: 2022-10-10T12:52:31+01:00
New Revision: 2343ad755d602fe67e3418d4edf0a5d0780045d6

URL: https://github.com/llvm/llvm-project/commit/2343ad755d602fe67e3418d4edf0a5d0780045d6
DIFF: https://github.com/llvm/llvm-project/commit/2343ad755d602fe67e3418d4edf0a5d0780045d6.diff

LOG: [AArch64] Add index check before lowerInterleavedStore() uses ShuffleVectorInst's mask

This commit fixes https://github.com/llvm/llvm-project/issues/57326.

Currently we would take a Mask out and directly use it by doing
auto Mask = SVI->getShuffleMask();
However, if the mask is undef, this Mask is not initialized. It might be
a vector of -1 or random integers.
This would cause an Out-of-bound read later when trying to find a
StartMask.

This change checks if all indices in the Mask is in the allowed range,
and fixes the out-of-bound accesses.

Differential Revision: https://reviews.llvm.org/D132634

Added: 
    llvm/test/CodeGen/AArch64/aarch64-interleaved-access-w-undef.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 6ef484463348..b3db12ee3238 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -13990,6 +13990,13 @@ bool AArch64TargetLowering::lowerInterleavedStore(StoreInst *SI,
 
   auto Mask = SVI->getShuffleMask();
 
+  // Sanity check if all the indices are NOT in range.
+  // If mask is `undef` or `poison`, `Mask` may be a vector of -1s.
+  // If all of them are `undef`, OOB read will happen later.
+  if (llvm::all_of(Mask, [](int Idx) { return Idx == UndefMaskElem; })) {
+    return false;
+  }
+
   Type *PtrTy =
       UseScalable
           ? STVTy->getElementType()->getPointerTo(SI->getPointerAddressSpace())
@@ -14041,9 +14048,9 @@ bool AArch64TargetLowering::lowerInterleavedStore(StoreInst *SI,
       } else {
         unsigned StartMask = 0;
         for (unsigned j = 1; j < LaneLen; j++) {
-          unsigned IdxJ = StoreCount * LaneLen * Factor + j;
-          if (Mask[IdxJ * Factor + IdxI] >= 0) {
-            StartMask = Mask[IdxJ * Factor + IdxI] - IdxJ;
+          unsigned IdxJ = StoreCount * LaneLen * Factor + j * Factor + i;
+          if (Mask[IdxJ] >= 0) {
+            StartMask = Mask[IdxJ] - j;
             break;
           }
         }

diff  --git a/llvm/test/CodeGen/AArch64/aarch64-interleaved-access-w-undef.ll b/llvm/test/CodeGen/AArch64/aarch64-interleaved-access-w-undef.ll
new file mode 100644
index 000000000000..d277274cff23
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/aarch64-interleaved-access-w-undef.ll
@@ -0,0 +1,103 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=aarch64-linux-gnu -opaque-pointers < %s | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-unknown-linux-gnu"
+
+define void @f_undef(<8 x i64> %a, ptr %dst) {
+; CHECK-LABEL: f_undef:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> undef
+  store <16 x i64> %S, ptr %dst, align 64
+  ret void
+}
+
+define void @f_poison(<8 x i64> %a, ptr %dst) {
+; CHECK-LABEL: f_poison:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> poison
+  store <16 x i64> %S, ptr %dst, align 64
+  ret void
+}
+
+define void @f_undef_15(<8 x i64> %a, ptr %dst) {
+; CHECK-LABEL: f_undef_15:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    mov x9, x0
+; CHECK-NEXT:    // kill: def $q0 killed $q0 def $q0_q1
+; CHECK-NEXT:    add x8, x0, #64
+; CHECK-NEXT:    mov v1.16b, v0.16b
+; CHECK-NEXT:    st2 { v0.2d, v1.2d }, [x9], #32
+; CHECK-NEXT:    st2 { v0.2d, v1.2d }, [x8]
+; CHECK-NEXT:    add x8, x0, #96
+; CHECK-NEXT:    st2 { v0.2d, v1.2d }, [x9]
+; CHECK-NEXT:    st2 { v0.2d, v1.2d }, [x8]
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> <i32 0, i32 undef, i32 undef, i32 undef,i32 undef, i32 undef, i32 undef, i32 undef,i32 undef, i32 undef, i32 undef, i32 undef,i32 undef, i32 undef, i32 undef, i32 undef>
+  store <16 x i64> %S, ptr %dst, align 64
+  ret void
+}
+
+define void @f_undef_1(<8 x i64> %a, ptr %dst) {
+; CHECK-LABEL: f_undef_1:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    mov x9, x0
+; CHECK-NEXT:    add x8, x0, #64
+; CHECK-NEXT:    mov v16.16b, v0.16b
+; CHECK-NEXT:    // kill: def $q3 killed $q3 def $q3_q4
+; CHECK-NEXT:    mov v17.16b, v16.16b
+; CHECK-NEXT:    mov v5.16b, v2.16b
+; CHECK-NEXT:    // kill: def $q1 killed $q1 def $q1_q2
+; CHECK-NEXT:    st2 { v16.2d, v17.2d }, [x9], #32
+; CHECK-NEXT:    mov v6.16b, v5.16b
+; CHECK-NEXT:    mov v2.16b, v1.16b
+; CHECK-NEXT:    mov v4.16b, v3.16b
+; CHECK-NEXT:    st2 { v5.2d, v6.2d }, [x8]
+; CHECK-NEXT:    add x8, x0, #96
+; CHECK-NEXT:    st2 { v1.2d, v2.2d }, [x9]
+; CHECK-NEXT:    st2 { v3.2d, v4.2d }, [x8]
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i64> %a, <8 x i64> %a, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 undef, i32 14, i32 7, i32 15>
+  store <16 x i64> %S, ptr %dst, align 64
+  ret void
+}
+
+; noundefs and undefs should have the same results.
+define void @noundefs(<8 x i32> %a, <8 x i32> %b, ptr %dst) {
+; CHECK-LABEL: noundefs:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    mov v5.16b, v2.16b
+; CHECK-NEXT:    // kill: def $q3 killed $q3 def $q2_q3
+; CHECK-NEXT:    mov v4.16b, v0.16b
+; CHECK-NEXT:    st2 { v4.4s, v5.4s }, [x0], #32
+; CHECK-NEXT:    mov v2.16b, v1.16b
+; CHECK-NEXT:    st2 { v2.4s, v3.4s }, [x0]
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i32> %a, <8 x i32> %b, <16 x i32> <i32 0, i32 8, i32 1, i32 9, i32 2, i32 10, i32 3, i32 11, i32 4, i32 12, i32 5, i32 13, i32 undef, i32 14, i32 7, i32 15>
+  store <16 x i32> %S, ptr %dst, align 64
+  ret void
+}
+
+define void @undefs(<8 x i32> %a, <8 x i32> %b, ptr %dst) {
+; CHECK-LABEL: undefs:
+; CHECK:       // %bb.0: // %BB
+; CHECK-NEXT:    mov v5.16b, v2.16b
+; CHECK-NEXT:    // kill: def $q3 killed $q3 def $q2_q3
+; CHECK-NEXT:    mov v4.16b, v0.16b
+; CHECK-NEXT:    st2 { v4.4s, v5.4s }, [x0], #32
+; CHECK-NEXT:    mov v2.16b, v1.16b
+; CHECK-NEXT:    st2 { v2.4s, v3.4s }, [x0]
+; CHECK-NEXT:    ret
+BB:
+  %S = shufflevector <8 x i32> %a, <8 x i32> %b, <16 x i32> <i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 3, i32 11, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 7, i32 15>
+  store <16 x i32> %S, ptr %dst, align 64
+  ret void
+}
+


        


More information about the llvm-commits mailing list