[polly] r268023 - [FIX] Prevent division/modulo by zero in parameters

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 29 03:36:59 PDT 2016


Author: jdoerfert
Date: Fri Apr 29 05:36:58 2016
New Revision: 268023

URL: http://llvm.org/viewvc/llvm-project?rev=268023&view=rev
Log:
[FIX] Prevent division/modulo by zero in parameters

  When we materialize parameter SCEVs we did so without considering the
  side effects they might have, e.g., both division and modulo are
  undefined if the right hand side is zero. This is a problem because we
  potentially extended the domain under which we evaluate parameters,
  thus we might have introduced such undefined behaviour. To prevent
  that from happening we will now guard divisions and modulo operations
  in the parameters with a compare and select.


Modified:
    polly/trunk/lib/Support/ScopHelper.cpp

Modified: polly/trunk/lib/Support/ScopHelper.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/ScopHelper.cpp?rev=268023&r1=268022&r2=268023&view=diff
==============================================================================
--- polly/trunk/lib/Support/ScopHelper.cpp (original)
+++ polly/trunk/lib/Support/ScopHelper.cpp Fri Apr 29 05:36:58 2016
@@ -246,6 +246,15 @@ private:
   const Region &R;
   ValueMapT *VMap;
 
+  /// @brief Return the Value for @p E if it is not zero or else the value 1.
+  Value *selectOneIfZero(const SCEV *E, Instruction *IP) {
+    auto *Ty = E->getType();
+    auto *RHS = Expander.expandCodeFor(E, Ty, IP);
+    auto *Zero = ConstantInt::get(Ty, 0);
+    auto *Cond = new ICmpInst(IP, ICmpInst::ICMP_NE, RHS, Zero);
+    return SelectInst::Create(Cond, RHS, ConstantInt::get(Ty, 1), "", IP);
+  }
+
   const SCEV *visitUnknown(const SCEVUnknown *E) {
 
     // If a value mapping was given try if the underlying value is remapped.
@@ -273,7 +282,11 @@ private:
     const SCEV *RHSScev = visit(SE.getSCEV(Inst->getOperand(1)));
 
     Value *LHS = Expander.expandCodeFor(LHSScev, E->getType(), StartIP);
-    Value *RHS = Expander.expandCodeFor(RHSScev, E->getType(), StartIP);
+    Value *RHS = nullptr;
+    if (SE.isKnownNonZero(RHSScev))
+      RHS = Expander.expandCodeFor(RHSScev, E->getType(), StartIP);
+    else
+      RHS = selectOneIfZero(RHSScev, StartIP);
 
     Inst = BinaryOperator::Create((Instruction::BinaryOps)Inst->getOpcode(),
                                   LHS, RHS, Inst->getName() + Name, StartIP);
@@ -295,7 +308,12 @@ private:
     return SE.getSignExtendExpr(visit(E->getOperand()), E->getType());
   }
   const SCEV *visitUDivExpr(const SCEVUDivExpr *E) {
-    return SE.getUDivExpr(visit(E->getLHS()), visit(E->getRHS()));
+    if (SE.isKnownNonZero(E->getRHS()))
+      return SE.getUDivExpr(visit(E->getLHS()), visit(E->getRHS()));
+    auto *RHSScev = visit(E->getRHS());
+    auto *IP = R.getEnteringBlock()->getTerminator();
+    auto *RHS = selectOneIfZero(RHSScev, IP);
+    return SE.getUDivExpr(visit(E->getLHS()), SE.getSCEV(RHS));
   }
   const SCEV *visitAddExpr(const SCEVAddExpr *E) {
     SmallVector<const SCEV *, 4> NewOps;




More information about the llvm-commits mailing list