[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
Mon Jul 13 00:08:06 PDT 2026


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

>From 7552216e88d41a115e2d58d80c79c5e115a6e80a 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..1ad6f746794e2
--- /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 fastcc i32 @func(i64 %indvars.iv3166) {
+; CHECK-LABEL: define fastcc i32 @func(
+; CHECK-SAME: i64 [[INDVARS_IV3166:%.*]]) {
+; CHECK-NEXT:  [[FOR_BODY_861_PREHEADER3486:.*:]]
+; CHECK-NEXT:    [[REDUC_2_64:%.*]] = alloca [2 x i32], align 4
+; CHECK-NEXT:    br label %[[FOR_BODY_861:.*]]
+; CHECK:       [[FOR_BODY_861]]:
+; CHECK-NEXT:    br label %[[FOR_BODY_861]]
+; CHECK:       [[FOR_COND_873_LOOPEXIT:.*]]:
+; CHECK-NEXT:    store i32 poison, ptr [[REDUC_2_64]], align 4
+; CHECK-NEXT:    br label %[[FOR_COND_873_LOOPEXIT]]
+; CHECK:       [[VECTOR_BODY3410:.*]]:
+; CHECK-NEXT:    br label %[[VECTOR_BODY3410]]
+; CHECK:       [[FOR_BODY_895_US:.*]]:
+; CHECK-NEXT:    [[ARRAYIDX1473_US:%.*]] = getelementptr [4 x i8], ptr [[REDUC_2_64]], i64 [[INDVARS_IV3166]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1473_US]], align 4
+; CHECK-NEXT:    br i1 false, label %[[FOR_BODY_895_US]], label %[[VECTOR_BODY3410]]
+;
+for_body_861.preheader3486:
+  %reduc_2_64 = alloca [2 x i32], align 4
+  br label %for_body_861
+
+for_body_861:
+  br label %for_body_861
+
+for_cond_873.loopexit:
+  store i32 %0, ptr %reduc_2_64, align 4
+  %0 = load i32, ptr %reduc_2_64, align 4
+  br label %for_cond_873.loopexit
+
+vector.body3410:
+  br label %vector.body3410
+
+for_body_895.us:
+  %arrayidx1473.us = getelementptr [4 x i8], ptr %reduc_2_64, i64 %indvars.iv3166
+  %1 = load i32, ptr %arrayidx1473.us, align 4
+  br i1 false, label %for_body_895.us, label %vector.body3410
+}
+



More information about the llvm-commits mailing list