[llvm] [SROA] Fix assertion failure when promoting self-referential load/store (PR #208826)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 10 12:58:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-transforms

Author: Krisitan Erik Olsen (Kristianerik)

<details>
<summary>Changes</summary>

When LoadAndStorePromoter::run processes a block where a store's value operand is defined by the load being promoted (a self-referential cycle in unreachable code), it sets StoredValue to the load instruction. When it then calls replaceAllUsesWith, the doRAUW assertion fires because the replacement value contains the value being replaced.
The single-block promotion paths in promoteSingleBlockAlloca already guard against this with a check for ReplVal == LI, replacing with poison instead. This patch adds the same guard to the in-block load path in LoadAndStorePromoter::run, which was missing it.
The regression was introduced in #<!-- -->135609, which added the propagateStoredValuesToLoads path in SROA that routes through LoadAndStorePromoter::run.

Fixes #<!-- -->204799

---
Full diff: https://github.com/llvm/llvm-project/pull/208826.diff


2 Files Affected:

- (modified) llvm/lib/Transforms/Utils/SSAUpdater.cpp (+3) 
- (added) llvm/test/Transforms/SROA/pr204799.ll (+22) 


``````````diff
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/pr204799.ll b/llvm/test/Transforms/SROA/pr204799.ll
new file mode 100644
index 0000000000000..6fa3e702b8e35
--- /dev/null
+++ b/llvm/test/Transforms/SROA/pr204799.ll
@@ -0,0 +1,22 @@
+; RUN: opt --passes=sroa %s -S -o - 2>&1 | FileCheck %s
+
+; Ensure no crash when a store's value operand is the load being promoted,
+; creating a self-referential cycle in unreachable code.
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define fastcc i32 @func(i64 %iv) {
+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
+}
+
+; CHECK-LABEL: @func

``````````

</details>


https://github.com/llvm/llvm-project/pull/208826


More information about the llvm-commits mailing list