[Polly] Apply gist only after converting to pw_aff (#192975)

A single-valued set/map is not necessarily single-valued anymore after
applying after gisting a context. In particular, the set/map might not
be single-valued outside the context.

Convert the result of MemoryAccess::getAddressFunction() directly to
pw_aff. Since it is the result of lexmin(), it is single-valued by
definition. Gist the context only after te conversion.

We should consider using `isl_basic_map_partial_lexmin_pw_multi_aff` in
`getAddressFunction()` directly to avoid the intermediate step.

Fixes #190459
This commit is contained in:
Michael Kruse
2026-04-20 15:06:45 +01:00
committed by GitHub
parent 3b37151c84
commit 6b7d1a494b
3 changed files with 36 additions and 1 deletions

View File

@@ -1061,6 +1061,7 @@ Value *IslNodeBuilder::preloadUnconditionally(isl::set AccessRange,
isl::ast_build Build,
Instruction *AccInst) {
isl::pw_multi_aff PWAccRel = isl::pw_multi_aff::from_set(AccessRange);
PWAccRel = PWAccRel.gist_params(S.getContext());
isl::ast_expr Access = Build.access_from(PWAccRel);
isl::ast_expr Address = Access.address_of();
Value *AddressValue = ExprBuilder.create(Address.release());
@@ -1087,7 +1088,6 @@ Value *IslNodeBuilder::preloadUnconditionally(isl::set AccessRange,
Value *IslNodeBuilder::preloadInvariantLoad(const MemoryAccess &MA,
isl::set Domain) {
isl::set AccessRange = MA.getAddressFunction().range();
AccessRange = AccessRange.gist_params(S.getContext());
if (!materializeParameters(AccessRange.get()))
return nullptr;

View File

@@ -3301,6 +3301,7 @@ public:
static inline isl::pw_multi_aff from_map(isl::map map);
static inline isl::pw_multi_aff from_set(isl::set set);
inline isl::pw_multi_aff gist(isl::set set) const;
inline isl::pw_multi_aff gist_params(isl::set set) const;
inline isl::union_pw_multi_aff gist(const isl::union_set &context) const;
inline isl::pw_multi_aff gist(const isl::basic_set &set) const;
inline isl::pw_multi_aff gist(const isl::point &set) const;
@@ -16391,6 +16392,12 @@ isl::pw_multi_aff pw_multi_aff::gist(isl::set set) const
return manage(res);
}
isl::pw_multi_aff pw_multi_aff::gist_params(isl::set set) const
{
auto res = isl_pw_multi_aff_gist_params(copy(), set.release());
return manage(res);
}
isl::union_pw_multi_aff pw_multi_aff::gist(const isl::union_set &context) const
{
return isl::union_pw_multi_aff(*this).gist(context);

View File

@@ -0,0 +1,28 @@
; RUN: opt %loadNPMPolly '-passes=polly-custom<codegen>' -polly-invariant-load-hoisting -S < %s | FileCheck %s
;
; https://github.com/llvm/llvm-project/issues/190459
; Avoid crash because isl_set_gist_params does not preserve single-valuedness
;
; CHECK: polly.split_new_and_old:
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
define i32 @func() {
bb:
br label %bb1
bb1: ; preds = %bb2, %bb
%i = phi i32 [ %i3, %bb2 ], [ 0, %bb ]
br label %bb4
bb2: ; preds = %bb4
%i3 = add i32 %i, 1
br label %bb1
bb4: ; preds = %bb4, %bb1
%i5 = and i32 %i, 7
%i6 = zext i32 %i5 to i64
%i7 = getelementptr [8 x i8], ptr null, i64 %i6
%i8 = load i8, ptr %i7, align 1
br i1 false, label %bb4, label %bb2
}