diff options
author | Dan Gohman <gohman@apple.com> | 2009-05-08 23:11:16 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-05-08 23:11:16 +0000 |
commit | 35dc9b65edab933134a9998aa04042e6aa42c9cc (patch) | |
tree | cbcf0b94e349d7f8ae61ba81b95df509ddd7ce68 /llvm | |
parent | 884a8996c53d173b9f53ec150cb8117c36364e1d (diff) | |
download | bcm5719-llvm-35dc9b65edab933134a9998aa04042e6aa42c9cc.tar.gz bcm5719-llvm-35dc9b65edab933134a9998aa04042e6aa42c9cc.zip |
Fix bogus overflow checks by replacing them with actual
overflow checks.
llvm-svn: 71284
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 25 | ||||
-rw-r--r-- | llvm/test/Analysis/ScalarEvolution/div-overflow.ll | 10 |
2 files changed, 28 insertions, 7 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 3ad542cd97c..c53d1f5aaea 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1381,29 +1381,39 @@ SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this))) if (!Step->getValue()->getValue() .urem(RHSC->getValue()->getValue()) && - getTruncateExpr(getZeroExtendExpr(AR, ExtTy), Ty) == AR) { + getZeroExtendExpr(AR, ExtTy) == + getAddRecExpr(getZeroExtendExpr(AR->getStart(), ExtTy), + getZeroExtendExpr(Step, ExtTy), + AR->getLoop())) { std::vector<SCEVHandle> Operands; for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i) Operands.push_back(getUDivExpr(AR->getOperand(i), RHS)); return getAddRecExpr(Operands, AR->getLoop()); } // (A*B)/C --> A*(B/C) if safe and B/C can be folded. - if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) - if (getTruncateExpr(getZeroExtendExpr(M, ExtTy), Ty) == M) + if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) { + std::vector<SCEVHandle> Operands; + for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) + Operands.push_back(getZeroExtendExpr(M->getOperand(i), ExtTy)); + if (getZeroExtendExpr(M, ExtTy) == getMulExpr(Operands)) // Find an operand that's safely divisible. for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) { SCEVHandle Op = M->getOperand(i); SCEVHandle Div = getUDivExpr(Op, RHSC); if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) { - std::vector<SCEVHandle> Operands = M->getOperands(); + Operands = M->getOperands(); Operands[i] = Div; return getMulExpr(Operands); } } + } // (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded. - if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(LHS)) - if (getTruncateExpr(getZeroExtendExpr(A, ExtTy), Ty) == A) { - std::vector<SCEVHandle> Operands; + if (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(LHS)) { + std::vector<SCEVHandle> Operands; + for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) + Operands.push_back(getZeroExtendExpr(A->getOperand(i), ExtTy)); + if (getZeroExtendExpr(A, ExtTy) == getAddExpr(Operands)) { + Operands.clear(); for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) { SCEVHandle Op = getUDivExpr(A->getOperand(i), RHS); if (isa<SCEVUDivExpr>(Op) || getMulExpr(Op, RHS) != A->getOperand(i)) @@ -1413,6 +1423,7 @@ SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS, if (Operands.size() == A->getNumOperands()) return getAddExpr(Operands); } + } // Fold if both operands are constant. if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) { diff --git a/llvm/test/Analysis/ScalarEvolution/div-overflow.ll b/llvm/test/Analysis/ScalarEvolution/div-overflow.ll new file mode 100644 index 00000000000..cb64b856a77 --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/div-overflow.ll @@ -0,0 +1,10 @@ +; RUN: llvm-as < %s | opt -scalar-evolution -analyze -disable-output \ +; RUN: | grep {\\--> ((-128 \\* %a) /u -128)} + +; Don't let ScalarEvolution fold this div away. + +define i8 @foo(i8 %a) { + %t0 = shl i8 %a, 7 + %t1 = lshr i8 %t0, 7 + ret i8 %t1 +} |