[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