[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