mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 19:12:56 +02:00
Fix bogus overflow checks by replacing them with actual
overflow checks. llvm-svn: 71284
This commit is contained in:
parent
8e26879521
commit
141989d3c2
@ -1381,29 +1381,39 @@ SCEVHandle ScalarEvolution::getUDivExpr(const SCEVHandle &LHS,
|
|||||||
dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this)))
|
dyn_cast<SCEVConstant>(AR->getStepRecurrence(*this)))
|
||||||
if (!Step->getValue()->getValue()
|
if (!Step->getValue()->getValue()
|
||||||
.urem(RHSC->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;
|
std::vector<SCEVHandle> Operands;
|
||||||
for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i)
|
for (unsigned i = 0, e = AR->getNumOperands(); i != e; ++i)
|
||||||
Operands.push_back(getUDivExpr(AR->getOperand(i), RHS));
|
Operands.push_back(getUDivExpr(AR->getOperand(i), RHS));
|
||||||
return getAddRecExpr(Operands, AR->getLoop());
|
return getAddRecExpr(Operands, AR->getLoop());
|
||||||
}
|
}
|
||||||
// (A*B)/C --> A*(B/C) if safe and B/C can be folded.
|
// (A*B)/C --> A*(B/C) if safe and B/C can be folded.
|
||||||
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS))
|
if (const SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(LHS)) {
|
||||||
if (getTruncateExpr(getZeroExtendExpr(M, ExtTy), Ty) == M)
|
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.
|
// Find an operand that's safely divisible.
|
||||||
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
|
for (unsigned i = 0, e = M->getNumOperands(); i != e; ++i) {
|
||||||
SCEVHandle Op = M->getOperand(i);
|
SCEVHandle Op = M->getOperand(i);
|
||||||
SCEVHandle Div = getUDivExpr(Op, RHSC);
|
SCEVHandle Div = getUDivExpr(Op, RHSC);
|
||||||
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
|
if (!isa<SCEVUDivExpr>(Div) && getMulExpr(Div, RHSC) == Op) {
|
||||||
std::vector<SCEVHandle> Operands = M->getOperands();
|
Operands = M->getOperands();
|
||||||
Operands[i] = Div;
|
Operands[i] = Div;
|
||||||
return getMulExpr(Operands);
|
return getMulExpr(Operands);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// (A+B)/C --> (A/C + B/C) if safe and A/C and B/C can be folded.
|
// (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 (const SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(LHS)) {
|
||||||
if (getTruncateExpr(getZeroExtendExpr(A, ExtTy), Ty) == A) {
|
std::vector<SCEVHandle> Operands;
|
||||||
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) {
|
for (unsigned i = 0, e = A->getNumOperands(); i != e; ++i) {
|
||||||
SCEVHandle Op = getUDivExpr(A->getOperand(i), RHS);
|
SCEVHandle Op = getUDivExpr(A->getOperand(i), RHS);
|
||||||
if (isa<SCEVUDivExpr>(Op) || getMulExpr(Op, RHS) != A->getOperand(i))
|
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())
|
if (Operands.size() == A->getNumOperands())
|
||||||
return getAddExpr(Operands);
|
return getAddExpr(Operands);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Fold if both operands are constant.
|
// Fold if both operands are constant.
|
||||||
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
|
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
|
||||||
|
10
test/Analysis/ScalarEvolution/div-overflow.ll
Normal file
10
test/Analysis/ScalarEvolution/div-overflow.ll
Normal file
@ -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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user