[polly] r268025 - [FIX] Unsigned comparisons change invalid domain
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 29 03:44:41 PDT 2016
Author: jdoerfert
Date: Fri Apr 29 05:44:41 2016
New Revision: 268025
URL: http://llvm.org/viewvc/llvm-project?rev=268025&view=rev
Log:
[FIX] Unsigned comparisons change invalid domain
It does not suffice to take a global assumptions for unsigned comparisons but
we also need to adjust the invalid domain of the statements guarded by such
an assumption. To this end we allow to specialize the getPwAff call now in
order to indicate unsigned interpretation.
Added:
polly/trunk/test/ScopInfo/non-precise-inv-load-6.ll
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/include/polly/Support/SCEVAffinator.h
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/Support/SCEVAffinator.cpp
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=268025&r1=268024&r2=268025&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Fri Apr 29 05:44:41 2016
@@ -1267,8 +1267,11 @@ public:
/// @brief Compute the isl representation for the SCEV @p E in this stmt.
///
+ /// @param E The SCEV that should be translated.
+ /// @param NonNegative Flag to indicate the @p E has to be non-negative.
+ ///
/// Note that this function will also adjust the invalid context accordingly.
- __isl_give isl_pw_aff *getPwAff(const SCEV *E);
+ __isl_give isl_pw_aff *getPwAff(const SCEV *E, bool NonNegative = false);
/// @brief Get the loop for a dimension.
///
@@ -2125,15 +2128,18 @@ public:
/// @brief Compute the isl representation for the SCEV @p E
///
+ /// @param E The SCEV that should be translated.
/// @param BB An (optional) basic block in which the isl_pw_aff is computed.
/// SCEVs known to not reference any loops in the SCoP can be
/// passed without a @p BB.
+ /// @param NonNegative Flag to indicate the @p E has to be non-negative.
///
/// Note that this function will always return a valid isl_pw_aff. However, if
/// the translation of @p E was deemed to complex the SCoP is invalidated and
/// a dummy value of appropriate dimension is returned. This allows to bail
/// for complex cases without "error handling code" needed on the users side.
- __isl_give PWACtx getPwAff(const SCEV *E, BasicBlock *BB = nullptr);
+ __isl_give PWACtx getPwAff(const SCEV *E, BasicBlock *BB = nullptr,
+ bool NonNegative = false);
/// @brief Compute the isl representation for the SCEV @p E
///
Modified: polly/trunk/include/polly/Support/SCEVAffinator.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/SCEVAffinator.h?rev=268025&r1=268024&r2=268025&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/SCEVAffinator.h (original)
+++ polly/trunk/include/polly/Support/SCEVAffinator.h Fri Apr 29 05:44:41 2016
@@ -64,6 +64,9 @@ public:
__isl_give PWACtx getPwAff(const llvm::SCEV *E,
llvm::BasicBlock *BB = nullptr);
+ /// @brief Take the asumption that @p PWAC is non-negative.
+ void takeNonNegativeAssumption(PWACtx &PWAC);
+
/// @brief Check an <nsw> AddRec for the loop @p L is cached.
bool hasNSWAddRecForLoop(llvm::Loop *L) const;
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=268025&r1=268024&r2=268025&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Fri Apr 29 05:44:41 2016
@@ -1045,8 +1045,8 @@ __isl_give isl_map *ScopStmt::getSchedul
return M;
}
-__isl_give isl_pw_aff *ScopStmt::getPwAff(const SCEV *E) {
- PWACtx PWAC = getParent()->getPwAff(E, getEntryBlock());
+__isl_give isl_pw_aff *ScopStmt::getPwAff(const SCEV *E, bool NonNegative) {
+ PWACtx PWAC = getParent()->getPwAff(E, getEntryBlock(), NonNegative);
InvalidDomain = isl_set_union(InvalidDomain, PWAC.second);
return PWAC.first;
}
@@ -1315,20 +1315,12 @@ buildConditionSets(ScopStmt &Stmt, Value
ScalarEvolution &SE = *S.getSE();
isl_pw_aff *LHS, *RHS;
- LHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(0), L));
- RHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(1), L));
-
- if (ICond->isUnsigned()) {
- // For unsigned comparisons we assumed the signed bit of neither operand
- // to be set. The comparison is equal to a signed comparison under this
- // assumption.
- auto *BB = Stmt.getEntryBlock();
- S.recordAssumption(UNSIGNED, isl_pw_aff_nonneg_set(isl_pw_aff_copy(LHS)),
- TI->getDebugLoc(), AS_ASSUMPTION, BB);
- S.recordAssumption(UNSIGNED, isl_pw_aff_nonneg_set(isl_pw_aff_copy(RHS)),
- TI->getDebugLoc(), AS_ASSUMPTION, BB);
- }
-
+ // For unsigned comparisons we assumed the signed bit of neither operand
+ // to be set. The comparison is equal to a signed comparison under this
+ // assumption.
+ bool NonNeg = ICond->isUnsigned();
+ LHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(0), L), NonNeg);
+ RHS = Stmt.getPwAff(SE.getSCEVAtScope(ICond->getOperand(1), L), NonNeg);
ConsequenceCondSet =
buildConditionSet(ICond->getPredicate(), LHS, RHS, Domain);
}
@@ -3789,15 +3781,19 @@ void Scop::dump() const { print(dbgs());
isl_ctx *Scop::getIslCtx() const { return IslCtx.get(); }
-__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB) {
+__isl_give PWACtx Scop::getPwAff(const SCEV *E, BasicBlock *BB,
+ bool NonNegative) {
// 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 cdoe to all users of this function.
auto PWAC = Affinator.getPwAff(E, BB);
- if (PWAC.first)
+ if (PWAC.first) {
+ if (NonNegative)
+ Affinator.takeNonNegativeAssumption(PWAC);
return PWAC;
+ }
auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
invalidate(COMPLEXITY, DL);
Modified: polly/trunk/lib/Support/SCEVAffinator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVAffinator.cpp?rev=268025&r1=268024&r2=268025&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVAffinator.cpp (original)
+++ polly/trunk/lib/Support/SCEVAffinator.cpp Fri Apr 29 05:44:41 2016
@@ -119,6 +119,15 @@ SCEVAffinator::~SCEVAffinator() {
freePWACtx(CachedPair.second);
}
+void SCEVAffinator::takeNonNegativeAssumption(PWACtx &PWAC) {
+ auto *NegPWA = isl_pw_aff_neg(isl_pw_aff_copy(PWAC.first));
+ auto *NegDom = isl_pw_aff_pos_set(NegPWA);
+ PWAC.second = isl_set_union(PWAC.second, isl_set_copy(NegDom));
+ auto *Restriction = BB ? NegDom : isl_set_params(NegDom);
+ auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
+ S->recordAssumption(UNSIGNED, Restriction, DL, AS_RESTRICTION, BB);
+}
+
__isl_give PWACtx SCEVAffinator::getPWACtxFromPWA(__isl_take isl_pw_aff *PWA) {
return std::make_pair(
PWA, isl_set_empty(isl_space_set_alloc(Ctx, 0, NumIterators)));
@@ -334,14 +343,7 @@ SCEVAffinator::visitZeroExtendExpr(const
// If the width is to big we assume the negative part does not occur.
if (!Precise) {
- auto *NegOpPWA = isl_pw_aff_neg(isl_pw_aff_copy(OpPWAC.first));
- auto *NegDom = isl_pw_aff_pos_set(NegOpPWA);
- auto *ExprDomain = BB ? S->getDomainConditions(BB) : nullptr;
- NegDom = ExprDomain ? isl_set_intersect(NegDom, ExprDomain) : NegDom;
- OpPWAC.second = isl_set_union(OpPWAC.second, isl_set_copy(NegDom));
- NegDom = BB ? NegDom : isl_set_params(NegDom);
- auto DL = BB ? BB->getTerminator()->getDebugLoc() : DebugLoc();
- S->recordAssumption(UNSIGNED, NegDom, DL, AS_RESTRICTION, BB);
+ takeNonNegativeAssumption(OpPWAC);
return OpPWAC;
}
Added: polly/trunk/test/ScopInfo/non-precise-inv-load-6.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/non-precise-inv-load-6.ll?rev=268025&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/non-precise-inv-load-6.ll (added)
+++ polly/trunk/test/ScopInfo/non-precise-inv-load-6.ll Fri Apr 29 05:44:41 2016
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -polly-scops -analyze < %s | FileCheck %s
+;
+l Check that we model the execution context correctly.
+;
+; void f(unsigned *I, unsigned *A, int c) {
+; for (unsigned i = c; i < 10; i++)
+; A[i] += *I;
+; }
+;
+; CHECK: Invariant Accesses: {
+; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT: [c] -> { Stmt_for_body[i0] -> MemRef_I[0] };
+; CHECK-NEXT: Execution Context: [c] -> { : 0 <= c <= 9 }
+; CHECK-NEXT: }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @f(i32* %I, i32* %A, i64 %c) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ %c, %entry ]
+ %exitcond = icmp ult i64 %indvars.iv, 10
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp = load i32, i32* %I, align 4
+ %arrayidx = getelementptr inbounds i32, i32* %A, i64 %indvars.iv
+ %tmp1 = load i32, i32* %arrayidx, align 4
+ %add = add i32 %tmp1, %tmp
+ store i32 %add, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
More information about the llvm-commits
mailing list