[polly] [Polly] Assumptions used to derive domain must not be pruning by domain (PR #190436)
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 3 17:22:15 PDT 2026
https://github.com/Meinersbur created https://github.com/llvm/llvm-project/pull/190436
Another circular reasoning bug
Fixies #190128
>From f9f9c08069b48938bf90c29b5a32f8317829a1e3 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Sat, 4 Apr 2026 01:16:22 +0200
Subject: [PATCH 1/5] WIP
---
polly/include/polly/ScopBuilder.h | 13 +-
polly/include/polly/ScopInfo.h | 2 +-
polly/include/polly/Support/SCEVAffinator.h | 7 +-
polly/lib/Analysis/ScopBuilder.cpp | 144 ++++++++++++--------
polly/lib/Analysis/ScopInfo.cpp | 10 +-
polly/lib/Support/SCEVAffinator.cpp | 10 +-
polly/lib/Support/ScopHelper.cpp | 32 ++++-
7 files changed, 140 insertions(+), 78 deletions(-)
diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h
index e589a7f0b05d6..5bc0a85f6d21a 100644
--- a/polly/include/polly/ScopBuilder.h
+++ b/polly/include/polly/ScopBuilder.h
@@ -113,7 +113,7 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, Instruction *TI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets,bool IsInsideDomain = true);
/// Build the conditions sets for the branch condition @p Condition in
/// the @p Domain.
@@ -126,7 +126,7 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, Value *Condition, Instruction *TI,
Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain = true);
/// Build the conditions sets for the switch @p SI in the @p Domain.
///
@@ -136,7 +136,7 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, SwitchInst *SI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain = true);
/// Build condition sets for unsigned ICmpInst(s).
/// Special handling is required for unsigned operands to ensure that if
@@ -150,7 +150,7 @@ class ScopBuilder final {
BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain,
const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- bool IsStrictUpperBound);
+ bool IsStrictUpperBound,bool IsInsideDomain = true);
/// Propagate the domain constraints through the region @p R.
///
@@ -235,13 +235,14 @@ class ScopBuilder final {
/// @param InvalidDomainMap A map of BB to their invalid domains.
/// @param E The SCEV that should be translated.
/// @param NonNegative Flag to indicate the @p E has to be
- /// non-negative.
+ /// non-negative.
+ /// @param IsInsideDomain
///
/// Note that this function will also adjust the invalid context
/// accordingly.
__isl_give isl_pw_aff *
getPwAff(BasicBlock *BB, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- const SCEV *E, bool NonNegative = false);
+ const SCEV *E, bool NonNegative = false, bool IsInsideDomain = true);
/// Create equivalence classes for required invariant accesses.
///
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 4cfbffc134a3a..271b1f1941bd6 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -2490,7 +2490,7 @@ class Scop final {
/// for complex cases without "error handling code" needed on the users side.
PWACtx getPwAff(const SCEV *E, BasicBlock *BB = nullptr,
bool NonNegative = false,
- RecordedAssumptionsTy *RecordedAssumptions = nullptr);
+ RecordedAssumptionsTy *RecordedAssumptions = nullptr, bool IsInsideDomain = true);
/// Compute the isl representation for the SCEV @p E
///
diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h
index 5fa78cc2431e7..01457864f6375 100644
--- a/polly/include/polly/Support/SCEVAffinator.h
+++ b/polly/include/polly/Support/SCEVAffinator.h
@@ -38,7 +38,7 @@ class SCEVAffinator final : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
///
/// @returns The isl representation of the SCEV @p E in @p Domain.
PWACtx getPwAff(const llvm::SCEV *E, llvm::BasicBlock *BB = nullptr,
- RecordedAssumptionsTy *RecordedAssumptions = nullptr);
+ RecordedAssumptionsTy *RecordedAssumptions = nullptr, bool IsInsideDomain = true);
/// Take the assumption that @p PWAC is non-negative.
void takeNonNegativeAssumption(
@@ -65,7 +65,12 @@ class SCEVAffinator final : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
unsigned NumIterators;
llvm::ScalarEvolution &SE;
llvm::LoopInfo &LI;
+
+
llvm::BasicBlock *BB;
+ bool IsInsideDomain;
+
+
RecordedAssumptionsTy *RecordedAssumptions = nullptr;
/// Target data for element size computing.
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index ce96211d08a41..7ed434139e413 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -346,8 +346,8 @@ isl::set ScopBuilder::adjustDomainDimensions(isl::set Dom, Loop *OldL,
__isl_give isl_pw_aff *
ScopBuilder::getPwAff(BasicBlock *BB,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- const SCEV *E, bool NonNegative) {
- PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions);
+ const SCEV *E, bool NonNegative, bool IsInsideDomain) {
+ PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions, IsInsideDomain);
InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second);
return PWAC.first.release();
}
@@ -364,13 +364,12 @@ __isl_give isl_set *ScopBuilder::buildUnsignedConditionSets(
BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain,
const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- bool IsStrictUpperBound) {
+ bool IsStrictUpperBound, bool IsInsideDomain) {
// Do not take NonNeg assumption on TestVal
// as it might have MSB (Sign bit) set.
- isl_pw_aff *TestVal = getPwAff(BB, InvalidDomainMap, SCEV_TestVal, false);
+ isl_pw_aff *TestVal = getPwAff(BB, InvalidDomainMap, SCEV_TestVal, /*NonNegative=*/ false, IsInsideDomain);
// Take NonNeg assumption on UpperBound.
- isl_pw_aff *UpperBound =
- getPwAff(BB, InvalidDomainMap, SCEV_UpperBound, true);
+ isl_pw_aff *UpperBound = getPwAff(BB, InvalidDomainMap, SCEV_UpperBound, /*NonNegative=*/true, IsInsideDomain);
// 0 <= TestVal
isl_set *First =
@@ -393,11 +392,11 @@ __isl_give isl_set *ScopBuilder::buildUnsignedConditionSets(
bool ScopBuilder::buildConditionSets(
BasicBlock *BB, SwitchInst *SI, Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain) {
Value *Condition = SI->getCondition();
isl_pw_aff *LHS, *RHS;
- LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L));
+ LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L), IsInsideDomain);
unsigned NumSuccessors = SI->getNumSuccessors();
ConditionSets.resize(NumSuccessors);
@@ -405,13 +404,12 @@ bool ScopBuilder::buildConditionSets(
unsigned Idx = Case.getSuccessorIndex();
ConstantInt *CaseValue = Case.getCaseValue();
- RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue));
+ RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue), IsInsideDomain );
isl_set *CaseConditionSet =
buildConditionSet(ICmpInst::ICMP_EQ, isl::manage_copy(LHS),
isl::manage(RHS))
.release();
- ConditionSets[Idx] = isl_set_coalesce(
- isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
+ ConditionSets[Idx] = isl_set_coalesce( isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
}
assert(ConditionSets[0] == nullptr && "Default condition set was set");
@@ -430,7 +428,7 @@ bool ScopBuilder::buildConditionSets(
BasicBlock *BB, Value *Condition, Instruction *TI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain) {
isl_set *ConsequenceCondSet = nullptr;
if (auto Load = dyn_cast<LoadInst>(Condition)) {
@@ -462,10 +460,8 @@ bool ScopBuilder::buildConditionSets(
auto Opcode = BinOp->getOpcode();
assert(Opcode == Instruction::And || Opcode == Instruction::Or);
- bool Valid = buildConditionSets(BB, BinOp->getOperand(0), TI, L, Domain,
- InvalidDomainMap, ConditionSets) &&
- buildConditionSets(BB, BinOp->getOperand(1), TI, L, Domain,
- InvalidDomainMap, ConditionSets);
+ bool Valid = buildConditionSets(BB, BinOp->getOperand(0), TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain) &&
+ buildConditionSets(BB, BinOp->getOperand(1), TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
if (!Valid) {
while (!ConditionSets.empty())
isl_set_free(ConditionSets.pop_back_val());
@@ -503,29 +499,27 @@ bool ScopBuilder::buildConditionSets(
case ICmpInst::ICMP_ULT:
ConsequenceCondSet =
buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand,
- RightOperand, InvalidDomainMap, true);
+ RightOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ true , IsInsideDomain );
break;
case ICmpInst::ICMP_ULE:
ConsequenceCondSet =
buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand,
- RightOperand, InvalidDomainMap, false);
+ RightOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ false , IsInsideDomain );
break;
case ICmpInst::ICMP_UGT:
ConsequenceCondSet =
buildUnsignedConditionSets(BB, Condition, Domain, RightOperand,
- LeftOperand, InvalidDomainMap, true);
+ LeftOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ true , IsInsideDomain );
break;
case ICmpInst::ICMP_UGE:
ConsequenceCondSet =
buildUnsignedConditionSets(BB, Condition, Domain, RightOperand,
- LeftOperand, InvalidDomainMap, false);
+ LeftOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ false , IsInsideDomain );
break;
default:
- LHS = getPwAff(BB, InvalidDomainMap, LeftOperand, NonNeg);
- RHS = getPwAff(BB, InvalidDomainMap, RightOperand, NonNeg);
- ConsequenceCondSet = buildConditionSet(ICond->getPredicate(),
- isl::manage(LHS), isl::manage(RHS))
- .release();
+ LHS = getPwAff(BB, InvalidDomainMap, LeftOperand, NonNeg, IsInsideDomain);
+ RHS = getPwAff(BB, InvalidDomainMap, RightOperand, NonNeg, IsInsideDomain);
+ ConsequenceCondSet = buildConditionSet(ICond->getPredicate(), isl::manage(LHS), isl::manage(RHS)) .release();
break;
}
}
@@ -566,10 +560,9 @@ bool ScopBuilder::buildConditionSets(
bool ScopBuilder::buildConditionSets(
BasicBlock *BB, Instruction *TI, Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets) {
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets ,bool IsInsideDomain ) {
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
- return buildConditionSets(BB, SI, L, Domain, InvalidDomainMap,
- ConditionSets);
+ return buildConditionSets(BB, SI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
if (isa<UncondBrInst>(TI)) {
ConditionSets.push_back(isl_set_copy(Domain));
@@ -577,12 +570,10 @@ bool ScopBuilder::buildConditionSets(
}
Value *Condition = cast<CondBrInst>(TI)->getCondition();
- return buildConditionSets(BB, Condition, TI, L, Domain, InvalidDomainMap,
- ConditionSets);
+ return buildConditionSets(BB, Condition, TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
}
-bool ScopBuilder::propagateDomainConstraints(
- Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
+bool ScopBuilder::propagateDomainConstraints( Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
// Iterate over the region R and propagate the domain constrains from the
// predecessors to the current node. In contrast to the
// buildDomainsWithBranchConstraints function, this one will pull the domain
@@ -929,8 +920,7 @@ bool ScopBuilder::buildDomainsWithBranchConstraints(
SmallVector<isl_set *, 8> ConditionSets;
if (RN->isSubRegion())
ConditionSets.push_back(Domain.copy());
- else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap,
- ConditionSets))
+ else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap, ConditionSets, /*IsInsideDomain=*/true))
return false;
// Now iterate over the successors and set their initial domain based on
@@ -1324,35 +1314,75 @@ void ScopBuilder::buildEscapingDependences(Instruction *Inst) {
void ScopBuilder::addRecordedAssumptions() {
for (auto &AS : llvm::reverse(RecordedAssumptions)) {
+ isl::set S = AS.Set;
+ AssumptionSign Sign = AS.Sign;
+
+ if (AS.BB && !AS.Set.is_params()) {
+ // If the domain was deleted the assumptions are void.
+ // FIXME (correctness): Cannot just delete assumptions with RequiresRTC
+ isl::set Dom = scop->getDomainConditions(AS.BB);
+ if (Dom.is_null())
+ continue;
+
+ // If a basic block was given use its domain to simplify the assumption.
+ // In case of restrictions we know they only have to hold on the domain,
+ // thus we can intersect them with the domain of the block. However, for
+ // assumptions the domain has to imply them, thus:
+ // _ _____
+ // Dom => S <==> A v B <==> A - B
+ //
+ // To avoid the complement we will register A - B as a restriction not an
+ // assumption.
+ if (AS.Sign == AS_RESTRICTION) {
+ S = std::move(S).intersect(std::move(Dom)) ;
+ } else {
+ S = std::move( Dom).subtract (std::move(S));
+ Sign = AS_RESTRICTION;
+ }
+ }
+
+
+ // FIXME (correctness): .params() is an overapproximation; if an AS_ASSUMPTION says
+ // [p] -> { [i] : p == 1 and i == 1 }
+ // the params space will be
+ // [p] -> { [] : }
+ // because there is am element with p == 1 in the set; if RequiresRTC is true, we will not include a check for p at all.
+ S = std::move(S).params();
+
+ #if 0
+ auto PSet = Set.params(); // overapproximation
+ auto Overapproximation = Set.get_space().universe_set().intersect_params(PSet);
+ if (Sign == AS_ASSUMPTION ) {
+ if (RTC) {
+ if (!Overapproximation.is_subset (Set) ) {
+ assert(!"Cannot RTC-check domain values");
+ }
+ } else {
+ // OK -- ???
+ }
+ } else if (Sign == AS_RESTRICTION) {
+ if (RTC) {
+ // OK -- rejecting more than necessary
+ } else {
+ if (!Overapproximation.is_subset (Set) ) {
+ assert(!"Allowing more executions than are valid");
+ }
+ }
+ }
+ Set = PSet;
+ #endif
+
+ #if 0
if (!AS.BB) {
- scop->addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign,
- nullptr /* BasicBlock */, AS.RequiresRTC);
+ scop->addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign, nullptr /* BasicBlock */, AS.RequiresRTC);
continue;
}
+ #endif
- // If the domain was deleted the assumptions are void.
- isl_set *Dom = scop->getDomainConditions(AS.BB).release();
- if (!Dom)
- continue;
- // If a basic block was given use its domain to simplify the assumption.
- // In case of restrictions we know they only have to hold on the domain,
- // thus we can intersect them with the domain of the block. However, for
- // assumptions the domain has to imply them, thus:
- // _ _____
- // Dom => S <==> A v B <==> A - B
- //
- // To avoid the complement we will register A - B as a restriction not an
- // assumption.
- isl_set *S = AS.Set.copy();
- if (AS.Sign == AS_RESTRICTION)
- S = isl_set_params(isl_set_intersect(S, Dom));
- else /* (AS.Sign == AS_ASSUMPTION) */
- S = isl_set_params(isl_set_subtract(Dom, S));
-
- scop->addAssumption(AS.Kind, isl::manage(S), AS.Loc, AS_RESTRICTION, AS.BB,
- AS.RequiresRTC);
+
+ scop->addAssumption(AS.Kind, std::move(S), AS.Loc, Sign, AS.BB, AS.RequiresRTC);
}
}
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index d3aaa7840ae80..d17097a04a049 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -2036,11 +2036,9 @@ void Scop::intersectDefinedBehavior(isl::set Set, AssumptionSign Sign) {
// Limit the complexity of the context. If complexity is exceeded, simplify
// the set and check again.
- if (DefinedBehaviorContext.n_basic_set().release() >
- MaxDisjunktsInDefinedBehaviourContext) {
+ if (DefinedBehaviorContext.n_basic_set().release() > MaxDisjunktsInDefinedBehaviourContext) {
simplify(DefinedBehaviorContext);
- if (DefinedBehaviorContext.n_basic_set().release() >
- MaxDisjunktsInDefinedBehaviourContext)
+ if (DefinedBehaviorContext.n_basic_set().release() > MaxDisjunktsInDefinedBehaviourContext)
DefinedBehaviorContext = {};
}
}
@@ -2169,13 +2167,13 @@ isl::ctx Scop::getIslCtx() const { return IslCtx.get(); }
__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
bool NonNegative,
- RecordedAssumptionsTy *RecordedAssumptions) {
+ RecordedAssumptionsTy *RecordedAssumptions, bool IsInsideDomain) {
// First try to use the SCEVAffinator to generate a piecewise defined
// affine function from @p E in the context of @p BB. If that tasks becomes to
// complex the affinator might return a nullptr. In such a case we invalidate
// the SCoP and return a dummy value. This way we do not need to add error
// handling code to all users of this function.
- auto PWAC = Affinator.getPwAff(E, BB, RecordedAssumptions);
+ auto PWAC = Affinator.getPwAff(E, BB, RecordedAssumptions, IsInsideDomain);
if (!PWAC.first.is_null()) {
// TODO: We could use a heuristic and either use:
// SCEVAffinator::takeNonNegativeAssumption
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp
index c9a728d3d04ec..9d1079882d37f 100644
--- a/polly/lib/Support/SCEVAffinator.cpp
+++ b/polly/lib/Support/SCEVAffinator.cpp
@@ -106,8 +106,7 @@ void SCEVAffinator::takeNonNegativeAssumption(
isl::manage(isl_set_union(PWAC.second.release(), isl_set_copy(NegDom)));
auto *Restriction = BB ? NegDom : isl_set_params(NegDom);
auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
- recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(Restriction), DL,
- AS_RESTRICTION, BB);
+ recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(Restriction), DL, AS_RESTRICTION, BB);
}
PWACtx SCEVAffinator::getPWACtxFromPWA(isl::pw_aff PWA) {
@@ -115,8 +114,9 @@ PWACtx SCEVAffinator::getPWACtxFromPWA(isl::pw_aff PWA) {
}
PWACtx SCEVAffinator::getPwAff(const SCEV *Expr, BasicBlock *BB,
- RecordedAssumptionsTy *RecordedAssumptions) {
+ RecordedAssumptionsTy *RecordedAssumptions, bool IsInsideDomain) {
this->BB = BB;
+ this->IsInsideDomain = IsInsideDomain;
this->RecordedAssumptions = RecordedAssumptions;
if (BB) {
@@ -308,8 +308,8 @@ PWACtx SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
OutOfBoundsDom = isl_set_params(OutOfBoundsDom);
}
- recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(OutOfBoundsDom),
- DebugLoc(), AS_RESTRICTION, BB);
+
+ recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(OutOfBoundsDom), DebugLoc(), AS_RESTRICTION, IsInsideDomain ? BB : nullptr);
return OpPWAC;
}
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp
index a9333e23d2839..47575db7e2979 100644
--- a/polly/lib/Support/ScopHelper.cpp
+++ b/polly/lib/Support/ScopHelper.cpp
@@ -210,8 +210,36 @@ void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
polly::AssumptionKind Kind, isl::set Set,
DebugLoc Loc, polly::AssumptionSign Sign,
BasicBlock *BB, bool RTC) {
- assert((Set.is_params() || BB) &&
- "Assumptions without a basic block must be parameter sets");
+ #if 0
+ if (!BB) {
+ auto PSet = Set.params(); // overapproximation
+ auto Overapproximation = Set.get_space().universe_set().intersect_params(PSet);
+ if (Sign == AS_ASSUMPTION ) {
+ if (RTC) {
+ if (!Overapproximation.is_subset (Set) ) {
+ assert(!"Cannot RTC-check domain values");
+ }
+ } else {
+ // OK -- ???
+ }
+ } else if (Sign == AS_RESTRICTION) {
+ if (RTC) {
+ // OK -- rejecting more than necessary
+ } else {
+ if (!Overapproximation.is_subset (Set) ) {
+ assert(!"Allowing more executions than are valid");
+ }
+ }
+ }
+ Set = PSet;
+ }
+ #endif
+
+ // assert((!RTC || !BB) && "Can only introduce RTC checks for parameters");
+
+
+
+ assert((Set.is_params() || BB) && "Assumptions without a basic block must be parameter sets");
if (RecordedAssumptions)
RecordedAssumptions->push_back({Kind, Sign, Set, Loc, BB, RTC});
}
>From 9270347e46245e70549662473dbe7f8d95c9a1c9 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Sat, 4 Apr 2026 01:31:16 +0200
Subject: [PATCH 2/5] switch-7 fix
---
polly/lib/Analysis/ScopBuilder.cpp | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 7ed434139e413..0af338d81666d 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -347,7 +347,7 @@ __isl_give isl_pw_aff *
ScopBuilder::getPwAff(BasicBlock *BB,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
const SCEV *E, bool NonNegative, bool IsInsideDomain) {
- PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions, IsInsideDomain);
+ PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions, IsInsideDomain);
InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second);
return PWAC.first.release();
}
@@ -396,7 +396,7 @@ bool ScopBuilder::buildConditionSets(
Value *Condition = SI->getCondition();
isl_pw_aff *LHS, *RHS;
- LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L), IsInsideDomain);
+ LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L), /*NonNegative=*/false, IsInsideDomain);
unsigned NumSuccessors = SI->getNumSuccessors();
ConditionSets.resize(NumSuccessors);
@@ -404,7 +404,7 @@ bool ScopBuilder::buildConditionSets(
unsigned Idx = Case.getSuccessorIndex();
ConstantInt *CaseValue = Case.getCaseValue();
- RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue), IsInsideDomain );
+ RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue),/*NonNegative=*/false, IsInsideDomain );
isl_set *CaseConditionSet =
buildConditionSet(ICmpInst::ICMP_EQ, isl::manage_copy(LHS),
isl::manage(RHS))
@@ -435,8 +435,8 @@ bool ScopBuilder::buildConditionSets(
const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L);
const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType());
bool NonNeg = false;
- isl_pw_aff *LHS = getPwAff(BB, InvalidDomainMap, LHSSCEV, NonNeg);
- isl_pw_aff *RHS = getPwAff(BB, InvalidDomainMap, RHSSCEV, NonNeg);
+ isl_pw_aff *LHS = getPwAff(BB, InvalidDomainMap, LHSSCEV, NonNeg, IsInsideDomain);
+ isl_pw_aff *RHS = getPwAff(BB, InvalidDomainMap, RHSSCEV, NonNeg, IsInsideDomain);
ConsequenceCondSet = buildConditionSet(ICmpInst::ICMP_SLE, isl::manage(LHS),
isl::manage(RHS))
.release();
@@ -3262,8 +3262,7 @@ void ScopBuilder::buildAccessRelations(ScopStmt &Stmt) {
for (const SCEV *Subscript : Access->subscripts()) {
if (!Access->isAffine() || !Subscript)
continue;
- scop->getPwAff(Subscript, Stmt.getEntryBlock(), false,
- &RecordedAssumptions);
+ scop->getPwAff(Subscript, Stmt.getEntryBlock(), false, &RecordedAssumptions);
}
Access->buildAccessRelation(SAI);
scop->addAccessData(Access);
>From b83bf319c4c8c74159a6d3451ad29765d07b526f Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Sat, 4 Apr 2026 01:47:02 +0200
Subject: [PATCH 3/5] base fix
---
polly/lib/Analysis/ScopBuilder.cpp | 2 +-
polly/lib/Support/ScopHelper.cpp | 2 +-
polly/test/ScopInfo/zero_ext_of_truncate.ll | 8 ++++++--
polly/test/ScopInfo/zero_ext_of_truncate_2.ll | 10 +++++++---
4 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 0af338d81666d..91f0f32861cf6 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -920,7 +920,7 @@ bool ScopBuilder::buildDomainsWithBranchConstraints(
SmallVector<isl_set *, 8> ConditionSets;
if (RN->isSubRegion())
ConditionSets.push_back(Domain.copy());
- else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap, ConditionSets, /*IsInsideDomain=*/true))
+ else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap, ConditionSets, /*IsInsideDomain=*/false))
return false;
// Now iterate over the successors and set their initial domain based on
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp
index 47575db7e2979..ab7defe05a25e 100644
--- a/polly/lib/Support/ScopHelper.cpp
+++ b/polly/lib/Support/ScopHelper.cpp
@@ -239,7 +239,7 @@ void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
- assert((Set.is_params() || BB) && "Assumptions without a basic block must be parameter sets");
+// assert((Set.is_params() || BB) && "Assumptions without a basic block must be parameter sets");
if (RecordedAssumptions)
RecordedAssumptions->push_back({Kind, Sign, Set, Loc, BB, RTC});
}
diff --git a/polly/test/ScopInfo/zero_ext_of_truncate.ll b/polly/test/ScopInfo/zero_ext_of_truncate.ll
index b509951bbf0d5..e152f141d5617 100644
--- a/polly/test/ScopInfo/zero_ext_of_truncate.ll
+++ b/polly/test/ScopInfo/zero_ext_of_truncate.ll
@@ -9,10 +9,14 @@
; }
;
; FIXME: The truncated value should be a parameter.
+; CHECK: {{^ *}}Context:
+; CHECK-NEXT: [N, tmp, M] -> { : -2147483648 <= N <= 2147483647 and -2147483648 <= tmp <= 2147483647 and -2147483648 <= M <= 2147483647 }
; CHECK: Assumed Context:
; CHECK-NEXT: [N, tmp, M] -> { : }
-; CHECK-NEXT: Invalid Context:
-; CHECK-NEXT: [N, tmp, M] -> { : N < 0 or (N > 0 and tmp >= 128) or (N > 0 and tmp < 0) or (N > 0 and M < 0) }
+; CHECK: Invalid Context:
+; CHECK-NEXT: [N, tmp, M] -> { : tmp <= -129 or tmp >= 128 or N < 0 or (N > 0 and tmp < 0) or (N > 0 and M < 0) }
+; CHECK: Defined Behavior Context:
+; CHECK-NEXT: [N, tmp, M] -> { : -128 <= tmp <= 127 and -2147483648 <= M <= 2147483647 and ((0 < N <= 2147483647 and tmp >= 0 and M >= 0) or N = 0) }
;
; CHECK: Domain :=
; CHECK-NEXT: [N, tmp, M] -> { Stmt_if_then[i0] : tmp >= 0 and M > tmp and 0 <= i0 < N };
diff --git a/polly/test/ScopInfo/zero_ext_of_truncate_2.ll b/polly/test/ScopInfo/zero_ext_of_truncate_2.ll
index ea3356e01cc9f..ee68054b06096 100644
--- a/polly/test/ScopInfo/zero_ext_of_truncate_2.ll
+++ b/polly/test/ScopInfo/zero_ext_of_truncate_2.ll
@@ -8,10 +8,14 @@
; }
; }
;
+; CHECK: {{^ *}}Context:
+; CHECK-NEXT: [N, tmp] -> { : -2147483648 <= N <= 2147483647 and -9223372036854775808 <= tmp <= 9223372036854775807 }
; CHECK: Assumed Context:
-; CHECK-NEXT: [N, tmp] -> { : }
-; CHECK-NEXT: Invalid Context:
-; CHECK-NEXT: [N, tmp] -> { : N > 0 and (tmp < 0 or tmp >= 2147483648) }
+; CHECK-NEXT: [N, tmp] -> { : }
+; CHECK: Invalid Context:
+; CHECK-NEXT: [N, tmp] -> { : tmp <= -2147483649 or tmp >= 2147483648 or (N > 0 and tmp < 0) }
+; CHECK: Defined Behavior Context:
+; CHECK-NEXT: [N, tmp] -> { : -2147483648 <= tmp <= 2147483647 and ((0 < N <= 2147483647 and tmp >= 0) or N = 0) }
;
; CHECK: Domain :=
; CHECK-NEXT: [N, tmp] -> { Stmt_if_then[i0] : tmp >= 0 and tmp < i0 < N };
>From b21a4eb652702ec3af83f83e9d2bacad47447ba4 Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Sat, 4 Apr 2026 02:18:49 +0200
Subject: [PATCH 4/5] Add dedicated test
---
polly/test/ScopInfo/issue190128.ll | 71 ++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
create mode 100644 polly/test/ScopInfo/issue190128.ll
diff --git a/polly/test/ScopInfo/issue190128.ll b/polly/test/ScopInfo/issue190128.ll
new file mode 100644
index 0000000000000..a56fcfc926256
--- /dev/null
+++ b/polly/test/ScopInfo/issue190128.ll
@@ -0,0 +1,71 @@
+; RUN: opt %loadNPMPolly '-passes=polly-custom<scops>' -polly-print-scops -disable-output < %s 2>&1 | FileCheck %s
+;
+; https://github.com/llvm/llvm-project/issues/190128
+;
+; void func(int arg, unsigned char arr_4[11]) {
+; int shl1 = 2147483592LL << arg; // 2147483592
+; int trunc1 = (short)(shl1); // -56
+; int start = trunc1 + 56; // = 0
+; for (short i_0 = start; i_0 < 1; i_0 += 1) {
+; arr_4[i_0] = i_0;
+; for (int i_2 = 1; i_2 < 3; i_2 += 1)
+; ; // somehow this matters -- different CFG
+; }
+; }
+;
+; The constraint -58 <= shl < 32768 (ignorable trunc range) must be checked in an RTC (here: InvalidConstant).
+; Alternatively, %conv6 could be used as a parameter, instead of %shl.
+
+; CHECK: Context:
+; CHECK-NEXT: [shl] -> { : -9223372036854775808 <= shl <= 9223372036854775800 }
+; CHECK: Assumed Context:
+; CHECK-NEXT: [shl] -> { : }
+; CHECK: Invalid Context:
+; CHECK-NEXT: [shl] -> { : shl <= -57 or shl >= 32768 }
+; CHECK: Defined Behavior Context:
+; CHECK-NEXT: [shl] -> { : -56 <= shl <= 32710 }
+
+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"
+
+; Function Attrs: nofree noinline norecurse nosync nounwind memory(argmem: write) uwtable
+define dso_local void @func(i32 noundef %arg, ptr noundef writeonly captures(none) %arr_4) local_unnamed_addr #0 {
+entry:
+ %sh_prom = zext nneg i32 %arg to i64
+ %shl = shl i64 2147483592, %sh_prom
+ %conv1 = trunc i64 %shl to i16
+ %add = add i16 %conv1, 56
+ %cmp22 = icmp slt i16 %add, 1
+ br i1 %cmp22, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.body, %entry
+ ret void
+
+for.body: ; preds = %for.body, %entry
+ %i_0.023 = phi i16 [ %add15, %for.body ], [ %add, %entry ]
+ %conv6 = trunc i16 %i_0.023 to i8
+ %idxprom = sext i16 %i_0.023 to i64
+ %arrayidx = getelementptr inbounds i8, ptr %arr_4, i64 %idxprom
+ store i8 %conv6, ptr %arrayidx, align 1, !tbaa !8
+ %add15 = add nsw i16 %i_0.023, 1
+ %cmp = icmp ugt i16 %i_0.023, 32766
+ br i1 %cmp, label %for.body, label %for.cond.cleanup, !llvm.loop !9
+}
+
+attributes #0 = { nofree noinline norecurse nosync nounwind memory(argmem: write) uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
+
+!llvm.module.flags = !{!0, !1, !2}
+!llvm.ident = !{!3}
+!llvm.errno.tbaa = !{!4}
+
+!0 = !{i32 8, !"PIC Level", i32 2}
+!1 = !{i32 7, !"PIE Level", i32 2}
+!2 = !{i32 7, !"uwtable", i32 2}
+!3 = !{!"clang version 23.0.0git (/home/meinersbur/src/llvm/polly/_src/clang a2d3783b451c0c19a5eb09b1ab9a1c66d81ab6ca)"}
+!4 = !{!5, !5, i64 0}
+!5 = !{!"int", !6, i64 0}
+!6 = !{!"omnipotent char", !7, i64 0}
+!7 = !{!"Simple C/C++ TBAA"}
+!8 = !{!6, !6, i64 0}
+!9 = distinct !{!9, !10, !11}
+!10 = !{!"llvm.loop.mustprogress"}
+!11 = !{!"llvm.loop.unroll.disable"}
>From a486ca94833629f135363072a6b7683440fec74d Mon Sep 17 00:00:00 2001
From: Michael Kruse <llvm-project at meinersbur.de>
Date: Sat, 4 Apr 2026 02:19:49 +0200
Subject: [PATCH 5/5] polly-update-format
---
polly/include/polly/ScopBuilder.h | 11 +-
polly/include/polly/ScopInfo.h | 3 +-
polly/include/polly/Support/SCEVAffinator.h | 5 +-
polly/lib/Analysis/ScopBuilder.cpp | 125 +++++++++++---------
polly/lib/Analysis/ScopInfo.cpp | 9 +-
polly/lib/Support/SCEVAffinator.cpp | 10 +-
polly/lib/Support/ScopHelper.cpp | 11 +-
7 files changed, 100 insertions(+), 74 deletions(-)
diff --git a/polly/include/polly/ScopBuilder.h b/polly/include/polly/ScopBuilder.h
index 5bc0a85f6d21a..f7c7b69fcc2c0 100644
--- a/polly/include/polly/ScopBuilder.h
+++ b/polly/include/polly/ScopBuilder.h
@@ -113,7 +113,8 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, Instruction *TI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets,bool IsInsideDomain = true);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
+ bool IsInsideDomain = true);
/// Build the conditions sets for the branch condition @p Condition in
/// the @p Domain.
@@ -126,7 +127,8 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, Value *Condition, Instruction *TI,
Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain = true);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
+ bool IsInsideDomain = true);
/// Build the conditions sets for the switch @p SI in the @p Domain.
///
@@ -136,7 +138,8 @@ class ScopBuilder final {
bool buildConditionSets(BasicBlock *BB, SwitchInst *SI, Loop *L,
__isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain = true);
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets,
+ bool IsInsideDomain = true);
/// Build condition sets for unsigned ICmpInst(s).
/// Special handling is required for unsigned operands to ensure that if
@@ -150,7 +153,7 @@ class ScopBuilder final {
BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain,
const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- bool IsStrictUpperBound,bool IsInsideDomain = true);
+ bool IsStrictUpperBound, bool IsInsideDomain = true);
/// Propagate the domain constraints through the region @p R.
///
diff --git a/polly/include/polly/ScopInfo.h b/polly/include/polly/ScopInfo.h
index 271b1f1941bd6..844850eb587bf 100644
--- a/polly/include/polly/ScopInfo.h
+++ b/polly/include/polly/ScopInfo.h
@@ -2490,7 +2490,8 @@ class Scop final {
/// for complex cases without "error handling code" needed on the users side.
PWACtx getPwAff(const SCEV *E, BasicBlock *BB = nullptr,
bool NonNegative = false,
- RecordedAssumptionsTy *RecordedAssumptions = nullptr, bool IsInsideDomain = true);
+ RecordedAssumptionsTy *RecordedAssumptions = nullptr,
+ bool IsInsideDomain = true);
/// Compute the isl representation for the SCEV @p E
///
diff --git a/polly/include/polly/Support/SCEVAffinator.h b/polly/include/polly/Support/SCEVAffinator.h
index 01457864f6375..f6bcf061abf6b 100644
--- a/polly/include/polly/Support/SCEVAffinator.h
+++ b/polly/include/polly/Support/SCEVAffinator.h
@@ -38,7 +38,8 @@ class SCEVAffinator final : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
///
/// @returns The isl representation of the SCEV @p E in @p Domain.
PWACtx getPwAff(const llvm::SCEV *E, llvm::BasicBlock *BB = nullptr,
- RecordedAssumptionsTy *RecordedAssumptions = nullptr, bool IsInsideDomain = true);
+ RecordedAssumptionsTy *RecordedAssumptions = nullptr,
+ bool IsInsideDomain = true);
/// Take the assumption that @p PWAC is non-negative.
void takeNonNegativeAssumption(
@@ -66,11 +67,9 @@ class SCEVAffinator final : public llvm::SCEVVisitor<SCEVAffinator, PWACtx> {
llvm::ScalarEvolution &SE;
llvm::LoopInfo &LI;
-
llvm::BasicBlock *BB;
bool IsInsideDomain;
-
RecordedAssumptionsTy *RecordedAssumptions = nullptr;
/// Target data for element size computing.
diff --git a/polly/lib/Analysis/ScopBuilder.cpp b/polly/lib/Analysis/ScopBuilder.cpp
index 91f0f32861cf6..cddb1daeabc30 100644
--- a/polly/lib/Analysis/ScopBuilder.cpp
+++ b/polly/lib/Analysis/ScopBuilder.cpp
@@ -347,7 +347,8 @@ __isl_give isl_pw_aff *
ScopBuilder::getPwAff(BasicBlock *BB,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
const SCEV *E, bool NonNegative, bool IsInsideDomain) {
- PWACtx PWAC = scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions, IsInsideDomain);
+ PWACtx PWAC =
+ scop->getPwAff(E, BB, NonNegative, &RecordedAssumptions, IsInsideDomain);
InvalidDomainMap[BB] = InvalidDomainMap[BB].unite(PWAC.second);
return PWAC.first.release();
}
@@ -363,13 +364,15 @@ ScopBuilder::getPwAff(BasicBlock *BB,
__isl_give isl_set *ScopBuilder::buildUnsignedConditionSets(
BasicBlock *BB, Value *Condition, __isl_keep isl_set *Domain,
const SCEV *SCEV_TestVal, const SCEV *SCEV_UpperBound,
- DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- bool IsStrictUpperBound, bool IsInsideDomain) {
+ DenseMap<BasicBlock *, isl::set> &InvalidDomainMap, bool IsStrictUpperBound,
+ bool IsInsideDomain) {
// Do not take NonNeg assumption on TestVal
// as it might have MSB (Sign bit) set.
- isl_pw_aff *TestVal = getPwAff(BB, InvalidDomainMap, SCEV_TestVal, /*NonNegative=*/ false, IsInsideDomain);
+ isl_pw_aff *TestVal = getPwAff(BB, InvalidDomainMap, SCEV_TestVal,
+ /*NonNegative=*/false, IsInsideDomain);
// Take NonNeg assumption on UpperBound.
- isl_pw_aff *UpperBound = getPwAff(BB, InvalidDomainMap, SCEV_UpperBound, /*NonNegative=*/true, IsInsideDomain);
+ isl_pw_aff *UpperBound = getPwAff(BB, InvalidDomainMap, SCEV_UpperBound,
+ /*NonNegative=*/true, IsInsideDomain);
// 0 <= TestVal
isl_set *First =
@@ -396,7 +399,8 @@ bool ScopBuilder::buildConditionSets(
Value *Condition = SI->getCondition();
isl_pw_aff *LHS, *RHS;
- LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L), /*NonNegative=*/false, IsInsideDomain);
+ LHS = getPwAff(BB, InvalidDomainMap, SE.getSCEVAtScope(Condition, L),
+ /*NonNegative=*/false, IsInsideDomain);
unsigned NumSuccessors = SI->getNumSuccessors();
ConditionSets.resize(NumSuccessors);
@@ -404,12 +408,14 @@ bool ScopBuilder::buildConditionSets(
unsigned Idx = Case.getSuccessorIndex();
ConstantInt *CaseValue = Case.getCaseValue();
- RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue),/*NonNegative=*/false, IsInsideDomain );
+ RHS = getPwAff(BB, InvalidDomainMap, SE.getSCEV(CaseValue),
+ /*NonNegative=*/false, IsInsideDomain);
isl_set *CaseConditionSet =
buildConditionSet(ICmpInst::ICMP_EQ, isl::manage_copy(LHS),
isl::manage(RHS))
.release();
- ConditionSets[Idx] = isl_set_coalesce( isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
+ ConditionSets[Idx] = isl_set_coalesce(
+ isl_set_intersect(CaseConditionSet, isl_set_copy(Domain)));
}
assert(ConditionSets[0] == nullptr && "Default condition set was set");
@@ -435,8 +441,10 @@ bool ScopBuilder::buildConditionSets(
const SCEV *LHSSCEV = SE.getSCEVAtScope(Load, L);
const SCEV *RHSSCEV = SE.getZero(LHSSCEV->getType());
bool NonNeg = false;
- isl_pw_aff *LHS = getPwAff(BB, InvalidDomainMap, LHSSCEV, NonNeg, IsInsideDomain);
- isl_pw_aff *RHS = getPwAff(BB, InvalidDomainMap, RHSSCEV, NonNeg, IsInsideDomain);
+ isl_pw_aff *LHS =
+ getPwAff(BB, InvalidDomainMap, LHSSCEV, NonNeg, IsInsideDomain);
+ isl_pw_aff *RHS =
+ getPwAff(BB, InvalidDomainMap, RHSSCEV, NonNeg, IsInsideDomain);
ConsequenceCondSet = buildConditionSet(ICmpInst::ICMP_SLE, isl::manage(LHS),
isl::manage(RHS))
.release();
@@ -460,8 +468,11 @@ bool ScopBuilder::buildConditionSets(
auto Opcode = BinOp->getOpcode();
assert(Opcode == Instruction::And || Opcode == Instruction::Or);
- bool Valid = buildConditionSets(BB, BinOp->getOperand(0), TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain) &&
- buildConditionSets(BB, BinOp->getOperand(1), TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
+ bool Valid =
+ buildConditionSets(BB, BinOp->getOperand(0), TI, L, Domain,
+ InvalidDomainMap, ConditionSets, IsInsideDomain) &&
+ buildConditionSets(BB, BinOp->getOperand(1), TI, L, Domain,
+ InvalidDomainMap, ConditionSets, IsInsideDomain);
if (!Valid) {
while (!ConditionSets.empty())
isl_set_free(ConditionSets.pop_back_val());
@@ -497,29 +508,32 @@ bool ScopBuilder::buildConditionSets(
switch (ICond->getPredicate()) {
case ICmpInst::ICMP_ULT:
- ConsequenceCondSet =
- buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand,
- RightOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ true , IsInsideDomain );
+ ConsequenceCondSet = buildUnsignedConditionSets(
+ BB, Condition, Domain, LeftOperand, RightOperand, InvalidDomainMap,
+ /*IsStrictUpperBound=*/true, IsInsideDomain);
break;
case ICmpInst::ICMP_ULE:
- ConsequenceCondSet =
- buildUnsignedConditionSets(BB, Condition, Domain, LeftOperand,
- RightOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ false , IsInsideDomain );
+ ConsequenceCondSet = buildUnsignedConditionSets(
+ BB, Condition, Domain, LeftOperand, RightOperand, InvalidDomainMap,
+ /*IsStrictUpperBound=*/false, IsInsideDomain);
break;
case ICmpInst::ICMP_UGT:
- ConsequenceCondSet =
- buildUnsignedConditionSets(BB, Condition, Domain, RightOperand,
- LeftOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ true , IsInsideDomain );
+ ConsequenceCondSet = buildUnsignedConditionSets(
+ BB, Condition, Domain, RightOperand, LeftOperand, InvalidDomainMap,
+ /*IsStrictUpperBound=*/true, IsInsideDomain);
break;
case ICmpInst::ICMP_UGE:
- ConsequenceCondSet =
- buildUnsignedConditionSets(BB, Condition, Domain, RightOperand,
- LeftOperand, InvalidDomainMap, /*IsStrictUpperBound=*/ false , IsInsideDomain );
+ ConsequenceCondSet = buildUnsignedConditionSets(
+ BB, Condition, Domain, RightOperand, LeftOperand, InvalidDomainMap,
+ /*IsStrictUpperBound=*/false, IsInsideDomain);
break;
default:
LHS = getPwAff(BB, InvalidDomainMap, LeftOperand, NonNeg, IsInsideDomain);
- RHS = getPwAff(BB, InvalidDomainMap, RightOperand, NonNeg, IsInsideDomain);
- ConsequenceCondSet = buildConditionSet(ICond->getPredicate(), isl::manage(LHS), isl::manage(RHS)) .release();
+ RHS =
+ getPwAff(BB, InvalidDomainMap, RightOperand, NonNeg, IsInsideDomain);
+ ConsequenceCondSet = buildConditionSet(ICond->getPredicate(),
+ isl::manage(LHS), isl::manage(RHS))
+ .release();
break;
}
}
@@ -560,9 +574,10 @@ bool ScopBuilder::buildConditionSets(
bool ScopBuilder::buildConditionSets(
BasicBlock *BB, Instruction *TI, Loop *L, __isl_keep isl_set *Domain,
DenseMap<BasicBlock *, isl::set> &InvalidDomainMap,
- SmallVectorImpl<__isl_give isl_set *> &ConditionSets ,bool IsInsideDomain ) {
+ SmallVectorImpl<__isl_give isl_set *> &ConditionSets, bool IsInsideDomain) {
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI))
- return buildConditionSets(BB, SI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
+ return buildConditionSets(BB, SI, L, Domain, InvalidDomainMap,
+ ConditionSets, IsInsideDomain);
if (isa<UncondBrInst>(TI)) {
ConditionSets.push_back(isl_set_copy(Domain));
@@ -570,10 +585,12 @@ bool ScopBuilder::buildConditionSets(
}
Value *Condition = cast<CondBrInst>(TI)->getCondition();
- return buildConditionSets(BB, Condition, TI, L, Domain, InvalidDomainMap, ConditionSets, IsInsideDomain);
+ return buildConditionSets(BB, Condition, TI, L, Domain, InvalidDomainMap,
+ ConditionSets, IsInsideDomain);
}
-bool ScopBuilder::propagateDomainConstraints( Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
+bool ScopBuilder::propagateDomainConstraints(
+ Region *R, DenseMap<BasicBlock *, isl::set> &InvalidDomainMap) {
// Iterate over the region R and propagate the domain constrains from the
// predecessors to the current node. In contrast to the
// buildDomainsWithBranchConstraints function, this one will pull the domain
@@ -920,7 +937,8 @@ bool ScopBuilder::buildDomainsWithBranchConstraints(
SmallVector<isl_set *, 8> ConditionSets;
if (RN->isSubRegion())
ConditionSets.push_back(Domain.copy());
- else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap, ConditionSets, /*IsInsideDomain=*/false))
+ else if (!buildConditionSets(BB, TI, BBLoop, Domain.get(), InvalidDomainMap,
+ ConditionSets, /*IsInsideDomain=*/false))
return false;
// Now iterate over the successors and set their initial domain based on
@@ -1315,14 +1333,14 @@ void ScopBuilder::buildEscapingDependences(Instruction *Inst) {
void ScopBuilder::addRecordedAssumptions() {
for (auto &AS : llvm::reverse(RecordedAssumptions)) {
isl::set S = AS.Set;
- AssumptionSign Sign = AS.Sign;
+ AssumptionSign Sign = AS.Sign;
if (AS.BB && !AS.Set.is_params()) {
- // If the domain was deleted the assumptions are void.
+ // If the domain was deleted the assumptions are void.
// FIXME (correctness): Cannot just delete assumptions with RequiresRTC
- isl::set Dom = scop->getDomainConditions(AS.BB);
- if (Dom.is_null())
- continue;
+ isl::set Dom = scop->getDomainConditions(AS.BB);
+ if (Dom.is_null())
+ continue;
// If a basic block was given use its domain to simplify the assumption.
// In case of restrictions we know they only have to hold on the domain,
@@ -1334,22 +1352,23 @@ void ScopBuilder::addRecordedAssumptions() {
// To avoid the complement we will register A - B as a restriction not an
// assumption.
if (AS.Sign == AS_RESTRICTION) {
- S = std::move(S).intersect(std::move(Dom)) ;
- } else {
- S = std::move( Dom).subtract (std::move(S));
- Sign = AS_RESTRICTION;
- }
+ S = std::move(S).intersect(std::move(Dom));
+ } else {
+ S = std::move(Dom).subtract(std::move(S));
+ Sign = AS_RESTRICTION;
}
+ }
-
- // FIXME (correctness): .params() is an overapproximation; if an AS_ASSUMPTION says
+ // FIXME (correctness): .params() is an overapproximation; if an
+ // AS_ASSUMPTION says
// [p] -> { [i] : p == 1 and i == 1 }
- // the params space will be
+ // the params space will be
// [p] -> { [] : }
- // because there is am element with p == 1 in the set; if RequiresRTC is true, we will not include a check for p at all.
+ // because there is am element with p == 1 in the set; if RequiresRTC is
+ // true, we will not include a check for p at all.
S = std::move(S).params();
- #if 0
+#if 0
auto PSet = Set.params(); // overapproximation
auto Overapproximation = Set.get_space().universe_set().intersect_params(PSet);
if (Sign == AS_ASSUMPTION ) {
@@ -1370,19 +1389,18 @@ void ScopBuilder::addRecordedAssumptions() {
}
}
Set = PSet;
- #endif
+#endif
- #if 0
+#if 0
if (!AS.BB) {
scop->addAssumption(AS.Kind, AS.Set, AS.Loc, AS.Sign, nullptr /* BasicBlock */, AS.RequiresRTC);
continue;
}
- #endif
-
-
+#endif
- scop->addAssumption(AS.Kind, std::move(S), AS.Loc, Sign, AS.BB, AS.RequiresRTC);
+ scop->addAssumption(AS.Kind, std::move(S), AS.Loc, Sign, AS.BB,
+ AS.RequiresRTC);
}
}
@@ -3262,7 +3280,8 @@ void ScopBuilder::buildAccessRelations(ScopStmt &Stmt) {
for (const SCEV *Subscript : Access->subscripts()) {
if (!Access->isAffine() || !Subscript)
continue;
- scop->getPwAff(Subscript, Stmt.getEntryBlock(), false, &RecordedAssumptions);
+ scop->getPwAff(Subscript, Stmt.getEntryBlock(), false,
+ &RecordedAssumptions);
}
Access->buildAccessRelation(SAI);
scop->addAccessData(Access);
diff --git a/polly/lib/Analysis/ScopInfo.cpp b/polly/lib/Analysis/ScopInfo.cpp
index d17097a04a049..e0457d809fdd2 100644
--- a/polly/lib/Analysis/ScopInfo.cpp
+++ b/polly/lib/Analysis/ScopInfo.cpp
@@ -2036,9 +2036,11 @@ void Scop::intersectDefinedBehavior(isl::set Set, AssumptionSign Sign) {
// Limit the complexity of the context. If complexity is exceeded, simplify
// the set and check again.
- if (DefinedBehaviorContext.n_basic_set().release() > MaxDisjunktsInDefinedBehaviourContext) {
+ if (DefinedBehaviorContext.n_basic_set().release() >
+ MaxDisjunktsInDefinedBehaviourContext) {
simplify(DefinedBehaviorContext);
- if (DefinedBehaviorContext.n_basic_set().release() > MaxDisjunktsInDefinedBehaviourContext)
+ if (DefinedBehaviorContext.n_basic_set().release() >
+ MaxDisjunktsInDefinedBehaviourContext)
DefinedBehaviorContext = {};
}
}
@@ -2167,7 +2169,8 @@ isl::ctx Scop::getIslCtx() const { return IslCtx.get(); }
__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
bool NonNegative,
- RecordedAssumptionsTy *RecordedAssumptions, bool IsInsideDomain) {
+ RecordedAssumptionsTy *RecordedAssumptions,
+ bool IsInsideDomain) {
// First try to use the SCEVAffinator to generate a piecewise defined
// affine function from @p E in the context of @p BB. If that tasks becomes to
// complex the affinator might return a nullptr. In such a case we invalidate
diff --git a/polly/lib/Support/SCEVAffinator.cpp b/polly/lib/Support/SCEVAffinator.cpp
index 9d1079882d37f..8509804d67904 100644
--- a/polly/lib/Support/SCEVAffinator.cpp
+++ b/polly/lib/Support/SCEVAffinator.cpp
@@ -106,7 +106,8 @@ void SCEVAffinator::takeNonNegativeAssumption(
isl::manage(isl_set_union(PWAC.second.release(), isl_set_copy(NegDom)));
auto *Restriction = BB ? NegDom : isl_set_params(NegDom);
auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
- recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(Restriction), DL, AS_RESTRICTION, BB);
+ recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(Restriction), DL,
+ AS_RESTRICTION, BB);
}
PWACtx SCEVAffinator::getPWACtxFromPWA(isl::pw_aff PWA) {
@@ -114,7 +115,8 @@ PWACtx SCEVAffinator::getPWACtxFromPWA(isl::pw_aff PWA) {
}
PWACtx SCEVAffinator::getPwAff(const SCEV *Expr, BasicBlock *BB,
- RecordedAssumptionsTy *RecordedAssumptions, bool IsInsideDomain) {
+ RecordedAssumptionsTy *RecordedAssumptions,
+ bool IsInsideDomain) {
this->BB = BB;
this->IsInsideDomain = IsInsideDomain;
this->RecordedAssumptions = RecordedAssumptions;
@@ -308,8 +310,8 @@ PWACtx SCEVAffinator::visitTruncateExpr(const SCEVTruncateExpr *Expr) {
OutOfBoundsDom = isl_set_params(OutOfBoundsDom);
}
-
- recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(OutOfBoundsDom), DebugLoc(), AS_RESTRICTION, IsInsideDomain ? BB : nullptr);
+ recordAssumption(RecordedAssumptions, UNSIGNED, isl::manage(OutOfBoundsDom),
+ DebugLoc(), AS_RESTRICTION, IsInsideDomain ? BB : nullptr);
return OpPWAC;
}
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp
index ab7defe05a25e..23acc1b2176ff 100644
--- a/polly/lib/Support/ScopHelper.cpp
+++ b/polly/lib/Support/ScopHelper.cpp
@@ -210,7 +210,7 @@ void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
polly::AssumptionKind Kind, isl::set Set,
DebugLoc Loc, polly::AssumptionSign Sign,
BasicBlock *BB, bool RTC) {
- #if 0
+#if 0
if (!BB) {
auto PSet = Set.params(); // overapproximation
auto Overapproximation = Set.get_space().universe_set().intersect_params(PSet);
@@ -233,13 +233,12 @@ void polly::recordAssumption(polly::RecordedAssumptionsTy *RecordedAssumptions,
}
Set = PSet;
}
- #endif
+#endif
- // assert((!RTC || !BB) && "Can only introduce RTC checks for parameters");
+ // assert((!RTC || !BB) && "Can only introduce RTC checks for parameters");
-
-
-// assert((Set.is_params() || BB) && "Assumptions without a basic block must be parameter sets");
+ // assert((Set.is_params() || BB) && "Assumptions without a basic block must
+ // be parameter sets");
if (RecordedAssumptions)
RecordedAssumptions->push_back({Kind, Sign, Set, Loc, BB, RTC});
}
More information about the llvm-commits
mailing list