aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-05-18 16:29:04 +0000
committerDan Gohman <gohman@apple.com>2009-05-18 16:29:04 +0000
commit10978bd5918689334d44cd30e5cfe06588b6014d (patch)
tree9f773126427c2836ce187eabe01178eca72cddcb /lib/Analysis/ScalarEvolution.cpp
parent0bac95e2e2044b574f3aea14a3fdb31c1b95240f (diff)
Teach ScalarEvolution to recognize x^-1 in the case where non-demanded
bits have been stripped out by instcombine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72010 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp13
1 files changed, 13 insertions, 0 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 3480a317c0..3ecb30232c 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -2203,6 +2203,19 @@ SCEVHandle ScalarEvolution::createSCEV(Value *V) {
// If the RHS of xor is -1, then this is a not operation.
if (CI->isAllOnesValue())
return getNotSCEV(getSCEV(U->getOperand(0)));
+
+ // Model xor(and(x, C), C) as and(~x, C), if C is a low-bits mask.
+ // This is a variant of the check for xor with -1, and it handles
+ // the case where instcombine has trimmed non-demanded bits out
+ // of an xor with -1.
+ if (BinaryOperator *BO = dyn_cast<BinaryOperator>(U->getOperand(0)))
+ if (ConstantInt *LCI = dyn_cast<ConstantInt>(BO->getOperand(1)))
+ if (BO->getOpcode() == Instruction::And &&
+ LCI->getValue() == CI->getValue())
+ if (const SCEVZeroExtendExpr *Z =
+ dyn_cast<SCEVZeroExtendExpr>(getSCEV(U->getOperand(0))))
+ return getZeroExtendExpr(getNotSCEV(Z->getOperand()),
+ U->getType());
}
break;