[Polly] Fix codegen assertions to account for DefinedBehaviorContext (#209188)

DeLICM may produce new read access relations whose domain is restricted
to the DefinedBehaviorContext (e.g., only valid when a parameter ensures
no UB). The validation in setNewAccessRelation already accounts for
this, but the debug assertions in createNewAccesses and
generateScalarLoads did not, causing false assertion failures during
code generation.

Intersect the checked domains with getBestKnownDefinedBehaviorContext()
to match the contract that DeLICM relies on.

Fixes #205732

(cherry picked from commit ea61254564)
This commit is contained in:
Karthika Devi C 2026-07-15 23:36:45 +05:30 committed by Douglas Yung
parent a2520c9f13
commit 23780df286
No known key found for this signature in database
GPG key ID: 316C56D064CACBA5
3 changed files with 55 additions and 2 deletions

View file

@ -555,6 +555,11 @@ void BlockGenerator::generateScalarLoads(
#ifndef NDEBUG
auto StmtDom =
Stmt.getDomain().intersect_params(Stmt.getParent()->getContext());
// Restrict to defined behavior context to match DeLICM's contract:
// new read accesses are only required to cover the defined-behavior
// subset of the domain.
StmtDom = StmtDom.intersect_params(
Stmt.getParent()->getBestKnownDefinedBehaviorContext());
auto AccDom = MA->getAccessRelation().domain();
assert(!StmtDom.is_subset(AccDom).is_false() &&
"Scalar must be loaded in all statement instances");

View file

@ -846,9 +846,17 @@ IslNodeBuilder::createNewAccesses(ScopStmt *Stmt,
Stmt->getParent()->getContext().release());
SchedDom = isl_set_intersect_params(
SchedDom, Stmt->getParent()->getContext().release());
assert(isl_set_is_subset(SchedDom, AccDom) &&
// Restrict to defined behavior context to match DeLICM's contract:
// new read accesses are only required to cover the defined-behavior
// subset of the domain.
auto *DefinedBehavior =
Stmt->getParent()->getBestKnownDefinedBehaviorContext().release();
SchedDom =
isl_set_intersect_params(SchedDom, isl_set_copy(DefinedBehavior));
Dom = isl_set_intersect_params(Dom, DefinedBehavior);
assert(isl_set_is_subset(SchedDom, AccDom) != isl_bool_false &&
"Access relation not defined on full schedule domain");
assert(isl_set_is_subset(Dom, AccDom) &&
assert(isl_set_is_subset(Dom, AccDom) != isl_bool_false &&
"Access relation not defined on full domain");
isl_set_free(AccDom);
isl_set_free(SchedDom);

View file

@ -0,0 +1,40 @@
; RUN: opt %loadNPMPolly -passes=polly -S %s | FileCheck %s
;
; https://github.com/llvm/llvm-project/issues/205732
; When DeLICM maps a scalar to an array element, the new access relation
; may only be valid within the DefinedBehaviorContext (i.e., for parameter
; values where the original program has no undefined behavior). Code
; generation must not assert failure for such partial-domain read accesses.
;
; CHECK: polly.start:
define void @foo(i32 %w, ptr %dst, i64 %n) {
entry:
br label %for.outer
for.outer:
%i = phi i64 [ %i.next, %for.mid.exit ], [ 0, %entry ]
br label %for.mid
for.mid:
br label %for.inner
for.inner:
%0 = phi i32 [ 0, %for.mid ], [ 1, %for.inner ]
%1 = load i16, ptr null, align 2
%cond1 = icmp eq i32 0, %w
br i1 %cond1, label %for.inner.exit, label %for.inner
for.inner.exit:
br i1 true, label %for.mid.exit, label %for.mid
for.mid.exit:
%ptr = getelementptr [4 x i8], ptr %dst, i64 %i
store i32 %0, ptr %ptr, align 4
%i.next = add i64 %i, 1
%cond2 = icmp eq i64 %i, %n
br i1 %cond2, label %for.outer.exit, label %for.outer
for.outer.exit:
ret void
}