[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