[llvm] [Loads] Fix crash on mixed-address-space pointers in no-AA store check (PR #195256)

Jiří Filek via llvm-commits llvm-commits at lists.llvm.org
Fri May 1 04:42:41 PDT 2026


https://github.com/fileho updated https://github.com/llvm/llvm-project/pull/195256

>From ab9cfbbee2dc3c07a2998e24c3b156425b8ebffe Mon Sep 17 00:00:00 2001
From: Jiri Filek <jiri.filek at gmail.com>
Date: Fri, 1 May 2026 13:05:04 +0200
Subject: [PATCH 1/3] [Loads] Fix crash on mixed-address-space pointers in
 no-AA store check

areNonOverlapSameBaseLoadAndStore built ConstantRanges from APInts
sized by the load and store pointer index widths. When those widths
differ (AMDGPU's AS=0 vs AS=5), ConstantRange::intersectWith
asserts. Add early return mirroring BasicAA.
---
 llvm/lib/Analysis/Loads.cpp           |  2 ++
 llvm/unittests/Analysis/LoadsTest.cpp | 29 +++++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index 4c157ba835f93..bcaefddffc619 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -580,6 +580,8 @@ static bool areNonOverlapSameBaseLoadAndStore(const Value *LoadPtr,
       DL, StoreOffset, /* AllowNonInbounds */ false);
   if (LoadBase != StoreBase)
     return false;
+  if (LoadOffset.getBitWidth() != StoreOffset.getBitWidth())
+    return false;
   auto LoadAccessSize = LocationSize::precise(DL.getTypeStoreSize(LoadTy));
   auto StoreAccessSize = LocationSize::precise(DL.getTypeStoreSize(StoreTy));
   ConstantRange LoadRange(LoadOffset,
diff --git a/llvm/unittests/Analysis/LoadsTest.cpp b/llvm/unittests/Analysis/LoadsTest.cpp
index 4dbe644ac8262..af3ca12b9bc20 100644
--- a/llvm/unittests/Analysis/LoadsTest.cpp
+++ b/llvm/unittests/Analysis/LoadsTest.cpp
@@ -67,6 +67,35 @@ define i32 @f() {
   ASSERT_TRUE(CI->equalsInt(42));
 }
 
+// Test the load and store pointers reach the same base value through different address spaces
+// with different index widths (here AS=0 has 64-bit pointers and AS=5 has
+// 32-bit pointers)
+TEST(LoadsTest, FindAvailableLoadedValueMixedAddrSpaceNullAA) {
+  LLVMContext C;
+  std::unique_ptr<Module> M = parseIR(C, R"IR(
+target datalayout = "e-p:64:64-p5:32:32-i64:64-n32:64-S32-A5"
+
+define ptr @f() {
+entry:
+  %a = alloca [16 x i8], align 8, addrspace(5)
+  %ac = addrspacecast ptr addrspace(5) %a to ptr
+  store ptr null, ptr %ac, align 8
+  %q = getelementptr inbounds i8, ptr addrspace(5) %a, i32 8
+  store i64 42, ptr addrspace(5) %q, align 8
+  %v = load ptr, ptr %ac, align 8
+  ret ptr %v
+}
+)IR");
+  auto *F = cast<Function>(M->getNamedValue("f"));
+  ASSERT_TRUE(F);
+  auto *LI = cast<LoadInst>(&*++F->front().rbegin());
+  ASSERT_TRUE(LI);
+  BasicBlock::iterator BBI(LI);
+  Value *Loaded =
+      FindAvailableLoadedValue(LI, LI->getParent(), BBI, 0, nullptr, nullptr);
+  EXPECT_EQ(Loaded, nullptr);
+}
+
 TEST(LoadsTest, CanReplacePointersIfEqual) {
   LLVMContext C;
   std::unique_ptr<Module> M = parseIR(C,

>From f3c35cfd48a918d656cc28cf0402d4e5b913a8bf Mon Sep 17 00:00:00 2001
From: Jiri Filek <jiri.filek at gmail.com>
Date: Fri, 1 May 2026 13:32:44 +0200
Subject: [PATCH 2/3] Run clang-format

---
 llvm/unittests/Analysis/LoadsTest.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/llvm/unittests/Analysis/LoadsTest.cpp b/llvm/unittests/Analysis/LoadsTest.cpp
index af3ca12b9bc20..e3ee4c8852c84 100644
--- a/llvm/unittests/Analysis/LoadsTest.cpp
+++ b/llvm/unittests/Analysis/LoadsTest.cpp
@@ -67,9 +67,9 @@ define i32 @f() {
   ASSERT_TRUE(CI->equalsInt(42));
 }
 
-// Test the load and store pointers reach the same base value through different address spaces
-// with different index widths (here AS=0 has 64-bit pointers and AS=5 has
-// 32-bit pointers)
+// Test the load and store pointers reach the same base value through different
+// address spaces with different index widths (here AS=0 has 64-bit pointers and
+// AS=5 has 32-bit pointers)
 TEST(LoadsTest, FindAvailableLoadedValueMixedAddrSpaceNullAA) {
   LLVMContext C;
   std::unique_ptr<Module> M = parseIR(C, R"IR(

>From 3f39f6b861d2bee667f844809fcd4f067acc6c3c Mon Sep 17 00:00:00 2001
From: Jiri Filek <jiri.filek at gmail.com>
Date: Fri, 1 May 2026 13:42:15 +0200
Subject: [PATCH 3/3] [Loads] Move mixed bit width check before
 stripAndAccumulateConstantOffsets

---
 llvm/lib/Analysis/Loads.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Analysis/Loads.cpp b/llvm/lib/Analysis/Loads.cpp
index bcaefddffc619..ac4d37aca7673 100644
--- a/llvm/lib/Analysis/Loads.cpp
+++ b/llvm/lib/Analysis/Loads.cpp
@@ -574,14 +574,14 @@ static bool areNonOverlapSameBaseLoadAndStore(const Value *LoadPtr,
                                               const DataLayout &DL) {
   APInt LoadOffset(DL.getIndexTypeSizeInBits(LoadPtr->getType()), 0);
   APInt StoreOffset(DL.getIndexTypeSizeInBits(StorePtr->getType()), 0);
+  if (LoadOffset.getBitWidth() != StoreOffset.getBitWidth())
+    return false;
   const Value *LoadBase = LoadPtr->stripAndAccumulateConstantOffsets(
       DL, LoadOffset, /* AllowNonInbounds */ false);
   const Value *StoreBase = StorePtr->stripAndAccumulateConstantOffsets(
       DL, StoreOffset, /* AllowNonInbounds */ false);
   if (LoadBase != StoreBase)
     return false;
-  if (LoadOffset.getBitWidth() != StoreOffset.getBitWidth())
-    return false;
   auto LoadAccessSize = LocationSize::precise(DL.getTypeStoreSize(LoadTy));
   auto StoreAccessSize = LocationSize::precise(DL.getTypeStoreSize(StoreTy));
   ConstantRange LoadRange(LoadOffset,



More information about the llvm-commits mailing list