Teach getExactSDiv to evaluate x/1 to x up front, as it's a common

enough special case, and it theoretically allows more folding because
it works even when x is unanalyzable.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@106763 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2010-06-24 16:51:25 +00:00
parent 789fef987f
commit d42819a07b

View File

@ -414,20 +414,28 @@ static const SCEV *getExactSDiv(const SCEV *LHS, const SCEV *RHS,
if (LHS == RHS)
return SE.getConstant(LHS->getType(), 1);
// Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do some
// folding.
if (RHS->isAllOnesValue())
return SE.getMulExpr(LHS, RHS);
// Handle a few RHS special cases.
const SCEVConstant *RC = dyn_cast<SCEVConstant>(RHS);
if (RC) {
const APInt &RA = RC->getValue()->getValue();
// Handle x /s -1 as x * -1, to give ScalarEvolution a chance to do
// some folding.
if (RA.isAllOnesValue())
return SE.getMulExpr(LHS, RC);
// Handle x /s 1 as x.
if (RA == 1)
return LHS;
}
// Check for a division of a constant by a constant.
if (const SCEVConstant *C = dyn_cast<SCEVConstant>(LHS)) {
const SCEVConstant *RC = dyn_cast<SCEVConstant>(RHS);
if (!RC)
return 0;
if (C->getValue()->getValue().srem(RC->getValue()->getValue()) != 0)
const APInt &LA = C->getValue()->getValue();
const APInt &RA = RC->getValue()->getValue();
if (LA.srem(RA) != 0)
return 0;
return SE.getConstant(C->getValue()->getValue()
.sdiv(RC->getValue()->getValue()));
return SE.getConstant(LA.sdiv(RA));
}
// Distribute the sdiv over addrec operands, if the addrec doesn't overflow.