[llvm] [SROA] Fix assertion failure when promoting self-referential load/store (PR #208826)
Krisitan Erik Olsen via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 18:02:45 PDT 2026
https://github.com/Kristianerik updated https://github.com/llvm/llvm-project/pull/208826
>From 30d47f7d93dc2a38429e48f96971ff81351c331c Mon Sep 17 00:00:00 2001
From: Kristianerik <kristian.erik at outlook.com>
Date: Mon, 13 Jul 2026 00:07:14 -0700
Subject: [PATCH] [SROA] Fix assertion failure when promoting self-referential
load/store
---
llvm/lib/Transforms/Utils/SSAUpdater.cpp | 3 ++
.../SROA/sroa-self-referential-load.ll | 45 +++++++++++++++++++
2 files changed, 48 insertions(+)
create mode 100644 llvm/test/Transforms/SROA/sroa-self-referential-load.ll
diff --git a/llvm/lib/Transforms/Utils/SSAUpdater.cpp b/llvm/lib/Transforms/Utils/SSAUpdater.cpp
index b6c5c28161fd8..44afd43ec3896 100644
--- a/llvm/lib/Transforms/Utils/SSAUpdater.cpp
+++ b/llvm/lib/Transforms/Utils/SSAUpdater.cpp
@@ -447,6 +447,9 @@ void LoadAndStorePromoter::run(const SmallVectorImpl<Instruction *> &Insts) {
// use the stored value.
if (StoredValue) {
replaceLoadWithValue(L, StoredValue);
+ // Avoid assertions in unreachable code.
+ if (StoredValue == L)
+ StoredValue = PoisonValue::get(L->getType());
L->replaceAllUsesWith(StoredValue);
ReplacedLoads[L] = StoredValue;
} else {
diff --git a/llvm/test/Transforms/SROA/sroa-self-referential-load.ll b/llvm/test/Transforms/SROA/sroa-self-referential-load.ll
new file mode 100644
index 0000000000000..39c2cf01455a3
--- /dev/null
+++ b/llvm/test/Transforms/SROA/sroa-self-referential-load.ll
@@ -0,0 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt --passes=sroa -S < %s | FileCheck %s
+
+; Ensure no crash when a store's value operand is the load being promoted,
+; creating a self-referential cycle in unreachable code.
+
+define i32 @func(i64 %iv) {
+; CHECK-LABEL: define i32 @func(
+; CHECK-SAME: i64 [[IV:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[A:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: br label %[[LOOP]]
+; CHECK: [[EXIT:.*]]:
+; CHECK-NEXT: store i32 poison, ptr [[A]], align 4
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[DEAD:.*]]:
+; CHECK-NEXT: br label %[[DEAD]]
+; CHECK: [[USE:.*]]:
+; CHECK-NEXT: [[GEP:%.*]] = getelementptr [4 x i8], ptr [[A]], i64 [[IV]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[GEP]], align 4
+; CHECK-NEXT: br i1 false, label %[[USE]], label %[[DEAD]]
+;
+entry:
+ %a = alloca [2 x i32], align 4
+ br label %loop
+
+loop:
+ br label %loop
+
+exit:
+ store i32 %0, ptr %a, align 4
+ %0 = load i32, ptr %a, align 4
+ br label %exit
+
+dead:
+ br label %dead
+
+use:
+ %gep = getelementptr [4 x i8], ptr %a, i64 %iv
+ %1 = load i32, ptr %gep, align 4
+ br i1 false, label %use, label %dead
+}
+
More information about the llvm-commits
mailing list