summaryrefslogtreecommitdiffstats
path: root/polly/lib/Support/ScopHelper.cpp
diff options
context:
space:
mode:
authorJohannes Doerfert <doerfert@cs.uni-saarland.de>2016-04-29 10:36:58 +0000
committerJohannes Doerfert <doerfert@cs.uni-saarland.de>2016-04-29 10:36:58 +0000
commitbfaa63a82eb84ed59573a8cb77ccd3e0d2b01bb0 (patch)
tree5502e024333cdb892e49d274c6fa6eef7e55dbe6 /polly/lib/Support/ScopHelper.cpp
parent4f3c985edd224303a607af0facec35829ab1e5a2 (diff)
downloadbcm5719-llvm-bfaa63a82eb84ed59573a8cb77ccd3e0d2b01bb0.tar.gz
bcm5719-llvm-bfaa63a82eb84ed59573a8cb77ccd3e0d2b01bb0.zip
[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. llvm-svn: 268023
Diffstat (limited to 'polly/lib/Support/ScopHelper.cpp')
-rw-r--r--polly/lib/Support/ScopHelper.cpp22
1 files changed, 20 insertions, 2 deletions
diff --git a/polly/lib/Support/ScopHelper.cpp b/polly/lib/Support/ScopHelper.cpp
index e73946f5042..a5c292be579 100644
--- a/polly/lib/Support/ScopHelper.cpp
+++ b/polly/lib/Support/ScopHelper.cpp
@@ -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;
OpenPOWER on IntegriCloud