diff options
author | Nick Lewycky <nicholas@mxc.ca> | 2007-11-20 08:24:44 +0000 |
---|---|---|
committer | Nick Lewycky <nicholas@mxc.ca> | 2007-11-20 08:24:44 +0000 |
commit | ef94749b4c1d8b754b63ab20f3c82c7593ba8243 (patch) | |
tree | 7e715ba0cd375ad406ed636e7eddaa92849d36c3 /lib | |
parent | f77e37cc074c8c39eec664de42b67a7278d0f8b6 (diff) | |
download | external_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.cpp | 14 |
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: |