[llvm] [SCEV] Fix ScalarEvolution::getBackedgeTakenInfo when L not found (PR #201502)
Thurston Dang via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 3 21:22:37 PDT 2026
https://github.com/thurstond created https://github.com/llvm/llvm-project/pull/201502
By the end of ScalarEvolution::getBackEdgeTakenInfo():
```
...
BackedgeTakenInfo Result = computeBackedgeTakenCount(L);
if (Result.hasAnyInfo()) {
// Invalidate any expression using an addrec in this loop.
...
}
return BackedgeTakenCounts.find(L)->second = std::move(Result);
```
BackedgeTakenCounts may no longer contain an entry for L, resulting in a crash (https://github.com/llvm/llvm-project/issues/195176). This patch fixes the issue by inserting the entry if it does not exist (and otherwise keeping the same behavior).
This adds a regression test (crash on opt 19.1.0 onwards e.g., https://godbolt.org/z/Wq3n3rEqT), metarenamed from
https://github.com/dtcxzyw/llvm-autoreduce/issues/106, which in turn was derived from https://github.com/llvm/llvm-project/issues/195176.
>From ca91081f76e879f11bbde602f27d50b6af69464f Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Thu, 4 Jun 2026 04:11:04 +0000
Subject: [PATCH] [SCEV] Fix ScalarEvolution::getBackedgeTakenInfo when L not
found
In ScalarEvolution::getBackEdgeTakenInfo():
...
BackedgeTakenInfo Result = computeBackedgeTakenCount(L);
if (Result.hasAnyInfo()) {
// Invalidate any expression using an addrec in this loop.
...
}
return BackedgeTakenCounts.find(L)->second = std::move(Result);
BackedgeTakenCounts may no longer contain an entry for L, resulting in a
crash (https://github.com/llvm/llvm-project/issues/195176). This patch
fixes the issue by inserting the entry if it does not exist (and
otherwise keeping the same behavior).
This adds a regression test, metarenamed from
https://github.com/dtcxzyw/llvm-autoreduce/issues/106, which in turn was
derived from https://github.com/llvm/llvm-project/issues/195176.
---
llvm/lib/Analysis/ScalarEvolution.cpp | 2 +-
.../Transforms/IndVarSimplify/issue195176.ll | 78 +++++++++++++++++++
2 files changed, 79 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Transforms/IndVarSimplify/issue195176.ll
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index ddf583082b2de..9e0058e4b724a 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -8746,7 +8746,7 @@ ScalarEvolution::getBackedgeTakenInfo(const Loop *L) {
// recusive call to getBackedgeTakenInfo (on a different
// loop), which would invalidate the iterator computed
// earlier.
- return BackedgeTakenCounts.find(L)->second = std::move(Result);
+ return BackedgeTakenCounts[L] = std::move(Result);
}
void ScalarEvolution::forgetAllLoops() {
diff --git a/llvm/test/Transforms/IndVarSimplify/issue195176.ll b/llvm/test/Transforms/IndVarSimplify/issue195176.ll
new file mode 100644
index 0000000000000..fc9ef42a1d7d5
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/issue195176.ll
@@ -0,0 +1,78 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=indvars -S | FileCheck %s
+
+define i32 @ham(ptr %arg) {
+; CHECK-LABEL: define i32 @ham(
+; CHECK-SAME: ptr [[ARG:%.*]]) {
+; CHECK-NEXT: [[BBLOCK:.*:]]
+; CHECK-NEXT: br label %[[BBLOCK2:.*]]
+; CHECK: [[BBLOCK1:.*]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[BBLOCK2_LOOPEXIT:.*]]:
+; CHECK-NEXT: br label %[[BBLOCK2]]
+; CHECK: [[BBLOCK2]]:
+; CHECK-NEXT: br i1 true, label %[[BBLOCK1]], label %[[BBLOCK3_PREHEADER:.*]]
+; CHECK: [[BBLOCK3_PREHEADER]]:
+; CHECK-NEXT: br label %[[BBLOCK3:.*]]
+; CHECK: [[BBLOCK3]]:
+; CHECK-NEXT: [[PHI4:%.*]] = phi i64 [ [[ADD14:%.*]], %[[BBLOCK13:.*]] ], [ 0, %[[BBLOCK3_PREHEADER]] ]
+; CHECK-NEXT: [[PHI5:%.*]] = phi ptr [ null, %[[BBLOCK13]] ], [ [[ARG]], %[[BBLOCK3_PREHEADER]] ]
+; CHECK-NEXT: [[PHI6:%.*]] = phi ptr [ [[GETELEMENTPTR:%.*]], %[[BBLOCK13]] ], [ null, %[[BBLOCK3_PREHEADER]] ]
+; CHECK-NEXT: br label %[[BBLOCK11:.*]]
+; CHECK: [[BBLOCK7:.*]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[BBLOCK8:.*]]:
+; CHECK-NEXT: [[PTRTOINT:%.*]] = ptrtoint ptr [[PHI6]] to i64
+; CHECK-NEXT: [[ICMP9:%.*]] = icmp ugt ptr [[PHI5]], null
+; CHECK-NEXT: [[XOR:%.*]] = xor i64 [[PTRTOINT]], -1
+; CHECK-NEXT: [[ICMP10:%.*]] = icmp ult i64 [[PHI4]], [[XOR]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[ICMP9]], i1 [[ICMP10]], i1 false
+; CHECK-NEXT: br i1 [[SELECT]], label %[[BBLOCK13]], label %[[BBLOCK7]]
+; CHECK: [[BBLOCK11]]:
+; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[PHI4]], 1
+; CHECK-NEXT: [[ICMP12:%.*]] = icmp eq i64 [[ADD]], 1
+; CHECK-NEXT: br i1 [[ICMP12]], label %[[BBLOCK8]], label %[[BBLOCK11]]
+; CHECK: [[BBLOCK13]]:
+; CHECK-NEXT: [[ADD14]] = add nuw nsw i64 [[PHI4]], 1
+; CHECK-NEXT: [[GETELEMENTPTR]] = getelementptr nusw i8, ptr [[PHI6]], i64 [[ADD14]]
+; CHECK-NEXT: br i1 false, label %[[BBLOCK2_LOOPEXIT]], label %[[BBLOCK3]]
+;
+bblock:
+ br label %bblock2
+
+bblock1: ; preds = %bblock2
+ unreachable
+
+bblock2: ; preds = %bblock13, %bblock
+ %phi = phi i64 [ 0, %bblock ], [ 1, %bblock13 ]
+ %icmp = icmp ult i64 %phi, 1
+ br i1 %icmp, label %bblock1, label %bblock3
+
+bblock3: ; preds = %bblock13, %bblock2
+ %phi4 = phi i64 [ %add14, %bblock13 ], [ 0, %bblock2 ]
+ %phi5 = phi ptr [ null, %bblock13 ], [ %arg, %bblock2 ]
+ %phi6 = phi ptr [ %getelementptr, %bblock13 ], [ null, %bblock2 ]
+ br label %bblock11
+
+bblock7: ; preds = %bblock8
+ unreachable
+
+bblock8: ; preds = %bblock11
+ %ptrtoint = ptrtoint ptr %phi6 to i64
+ %icmp9 = icmp ugt ptr %phi5, null
+ %xor = xor i64 %ptrtoint, -1
+ %icmp10 = icmp ult i64 %phi4, %xor
+ %select = select i1 %icmp9, i1 %icmp10, i1 false
+ br i1 %select, label %bblock13, label %bblock7
+
+bblock11: ; preds = %bblock11, %bblock3
+ %add = add i64 %phi4, 1
+ %icmp12 = icmp eq i64 %add, 1
+ br i1 %icmp12, label %bblock8, label %bblock11
+
+bblock13: ; preds = %bblock8
+ %add14 = add i64 %phi4, 1
+ %getelementptr = getelementptr nusw i8, ptr %phi6, i64 %add14
+ %icmp15 = icmp eq i64 %phi4, 1
+ br i1 %icmp15, label %bblock2, label %bblock3
+}
More information about the llvm-commits
mailing list