aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorNick Lewycky <nicholas@mxc.ca>2007-11-20 08:24:44 +0000
committerNick Lewycky <nicholas@mxc.ca>2007-11-20 08:24:44 +0000
commitef94749b4c1d8b754b63ab20f3c82c7593ba8243 (patch)
tree7e715ba0cd375ad406ed636e7eddaa92849d36c3 /lib
parentf77e37cc074c8c39eec664de42b67a7278d0f8b6 (diff)
downloadexternal_llvm-ef94749b4c1d8b754b63ab20f3c82c7593ba8243.zip
external_llvm-ef94749b4c1d8b754b63ab20f3c82c7593ba8243.tar.gz
external_llvm-ef94749b4c1d8b754b63ab20f3c82c7593ba8243.tar.bz2
Be more careful when transforming | to +. Patch from Wojciech Matyjewicz.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44248 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp14
1 files changed, 8 insertions, 6 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 6e50617..e7bb9ab 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -1484,25 +1484,27 @@ SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) {
case Instruction::SDiv:
return SE.getSDivExpr(getSCEV(I->getOperand(0)),
getSCEV(I->getOperand(1)));
- break;
-
case Instruction::Sub:
return SE.getMinusSCEV(getSCEV(I->getOperand(0)),
getSCEV(I->getOperand(1)));
case Instruction::Or:
// If the RHS of the Or is a constant, we may have something like:
- // X*4+1 which got turned into X*4|1. Handle this as an add so loop
+ // X*4+1 which got turned into X*4|1. Handle this as an Add so loop
// optimizations will transparently handle this case.
+ //
+ // In order for this transformation to be safe, the LHS must be of the
+ // form X*(2^n) and the Or constant must be less than 2^n.
+
if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
SCEVHandle LHS = getSCEV(I->getOperand(0));
APInt CommonFact(GetConstantFactor(LHS));
assert(!CommonFact.isMinValue() &&
"Common factor should at least be 1!");
- if (CommonFact.ugt(CI->getValue())) {
- // If the LHS is a multiple that is larger than the RHS, use +.
+ const APInt &CIVal = CI->getValue();
+ if (CommonFact.countTrailingZeros() >=
+ (CIVal.getBitWidth() - CIVal.countLeadingZeros()))
return SE.getAddExpr(LHS,
getSCEV(I->getOperand(1)));
- }
}
break;
case Instruction::Xor: