[polly] [Polly] Fix assertion in addUserAssumptions for unreachable blocks (PR #227311)
Karthika Devi C via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 05:11:32 PDT 2026
https://github.com/kartcq updated https://github.com/llvm/llvm-project/pull/227311
>From db803b743b2ae6bf2c47528b86ab1a25006fe473 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Tue, 29 Sep 2026 06:09:50 -0700
Subject: [PATCH 1/4] [Polly] Fix assertion in addUserAssumptions for
unreachable blocks
ScopBuilder::addUserAssumptions() crashes when an llvm.assume call
resides in a block that has no entry in InvalidDomainMap. This happens
when __builtin_unreachable() is converted to llvm.assume by earlier
passes, but Polly's buildDomainsWithBranchConstraints() skips the
block (e.g. due to an UnreachableInst terminator), leaving its
InvalidDomainMap entry uninitialized.
Skip such assumptions instead of asserting.
Fixes #226718
---
polly/lib/Analysis/ScopBuilder.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 9d48ba2f89248..63d3d56a82c46 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -1472,6 +1472,11 @@ void ScopBuilder::addUserAssumptions(
SmallVector<isl_set *, 2> ConditionSets;
auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr;
BasicBlock *BB = InScop ? CI->getParent() : R.getEntry();
+
+ // Skip assumptions in blocks with no computed domain (e.g. unreachable blocks).
+ if (!InvalidDomainMap.count(BB))
+ continue;
+
auto *Dom = InScop ? isl_set_copy(scop->getDomainConditions(BB).get())
: isl_set_copy(scop->getContext().get());
assert(Dom && "Cannot propagate a nullptr.");
>From e691033baaf12c4b833ebd03d204f393e000d40b Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Tue, 29 Sep 2026 19:20:36 +0530
Subject: [PATCH 2/4] Update Format
---
polly/lib/Analysis/ScopBuilder.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 63d3d56a82c46..6767280dc0790 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -980,7 +980,7 @@ bool ScopBuilder::buildDomainsWithBranchConstraints(
isl::set CondSet = isl::manage(ConditionSets[u]);
BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u);
- // Skip blocks outside the region.
+ blocks outside the region.
if (!scop->contains(SuccBB))
continue;
@@ -1473,7 +1473,8 @@ void ScopBuilder::addUserAssumptions(
auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr;
BasicBlock *BB = InScop ? CI->getParent() : R.getEntry();
- // Skip assumptions in blocks with no computed domain (e.g. unreachable blocks).
+ // Skip assumptions in blocks with no computed domain (e.g. unreachable
+ // blocks).
if (!InvalidDomainMap.count(BB))
continue;
>From 2ef0f4c06fa2b319dad7b1729357d6aa223bf7b3 Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Tue, 29 Sep 2026 19:29:48 +0530
Subject: [PATCH 3/4] Update ScopBuilder.cpp
---
polly/lib/Analysis/ScopBuilder.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 6767280dc0790..de8b4380f8245 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -980,7 +980,7 @@ bool ScopBuilder::buildDomainsWithBranchConstraints(
isl::set CondSet = isl::manage(ConditionSets[u]);
BasicBlock *SuccBB = getRegionNodeSuccessor(RN, TI, u);
- blocks outside the region.
+ // Skip blocks outside the region.
if (!scop->contains(SuccBB))
continue;
>From 65802a14d1255781afdbc7e305365e4a40ec788f Mon Sep 17 00:00:00 2001
From: Karthika Devi C <kartc at qti.qualcomm.com>
Date: Wed, 30 Sep 2026 05:04:41 -0700
Subject: [PATCH 4/4] Address review: clarify comment for non-affine
subregions, add lit test
---
polly/lib/Analysis/ScopBuilder.cpp | 7 ++-
.../assume_in_non_affine_subregion.ll | 56 +++++++++++++++++++
2 files changed, 61 insertions(+), 2 deletions(-)
create mode 100644 polly/test/ScopInfo/assume_in_non_affine_subregion.ll
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index de8b4380f8245..a33a630c7bbdb 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -1473,8 +1473,11 @@ void ScopBuilder::addUserAssumptions(
auto *TI = InScop ? CI->getParent()->getTerminator() : nullptr;
BasicBlock *BB = InScop ? CI->getParent() : R.getEntry();
- // Skip assumptions in blocks with no computed domain (e.g. unreachable
- // blocks).
+ // Skip assumptions in blocks with no computed domain. This includes
+ // interior blocks of non-affine subregions (only the entry block has a
+ // domain) and unreachable blocks. We cannot use getDomainConditions here
+ // as it would return the region's domain for any block in a non-affine
+ // subregion, but the assumption may not actually execute.
if (!InvalidDomainMap.count(BB))
continue;
diff --git a/polly/test/ScopInfo/assume_in_non_affine_subregion.ll b/polly/test/ScopInfo/assume_in_non_affine_subregion.ll
new file mode 100644
index 0000000000000..09429980d0442
--- /dev/null
+++ b/polly/test/ScopInfo/assume_in_non_affine_subregion.ll
@@ -0,0 +1,56 @@
+; RUN: opt %loadNPMPolly '-passes=polly-custom<scops>' -polly-print-scops -disable-output < %s 2>&1 | FileCheck %s
+;
+; Verify that an llvm.assume inside an interior block of a non-affine
+; subregion does not cause an assertion failure in addUserAssumptions.
+; The assume's block has no InvalidDomainMap entry and must be skipped.
+;
+; https://github.com/llvm/llvm-project/issues/226718
+;
+; void test(int *A, int *B, long n, int m) {
+; for (long i = 0; i < n; i++) {
+; A[i] = m;
+; if (B[i]) {
+; if (!(m == 0)) { __builtin_unreachable(); }
+; B[i] = 1;
+; }
+; }
+; }
+;
+; CHECK: Printing analysis
+; CHECK: Region: %for.body---%exit
+; CHECK: Statements {
+; CHECK: }
+
+define void @test(ptr %A, ptr %B, i64 %n, i32 %m) {
+entry:
+ %cmp = icmp sgt i64 %n, 0
+ br i1 %cmp, label %for.body.ph, label %exit
+
+for.body.ph:
+ %cmp2 = icmp eq i32 %m, 0
+ br label %for.body
+
+for.body:
+ %i = phi i64 [ 0, %for.body.ph ], [ %inc, %for.inc ]
+ %arrayidx.A = getelementptr inbounds i32, ptr %A, i64 %i
+ store i32 %m, ptr %arrayidx.A, align 4
+ %arrayidx.B = getelementptr inbounds i32, ptr %B, i64 %i
+ %val = load i32, ptr %arrayidx.B, align 4
+ %tobool = icmp eq i32 %val, 0
+ br i1 %tobool, label %for.inc, label %if.then
+
+if.then:
+ call void @llvm.assume(i1 %cmp2)
+ store i32 1, ptr %arrayidx.B, align 4
+ br label %for.inc
+
+for.inc:
+ %inc = add nuw nsw i64 %i, 1
+ %exitcond = icmp eq i64 %inc, %n
+ br i1 %exitcond, label %exit, label %for.body
+
+exit:
+ ret void
+}
+
+declare void @llvm.assume(i1)
More information about the llvm-commits
mailing list