summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-12-11 23:15:19 +0000
committerChris Lattner <sabre@nondot.org>2004-12-11 23:15:19 +0000
commitcbc0161d1fd73d79b3ea751f80327ee4cc4162a1 (patch)
tree619feb5d00416c09283cfe0f186a02847366e556 /llvm/lib/Transforms
parent2c14b32e2b8c3658f8f4c7a302a01bae9ed324cf (diff)
downloadbcm5719-llvm-cbc0161d1fd73d79b3ea751f80327ee4cc4162a1.tar.gz
bcm5719-llvm-cbc0161d1fd73d79b3ea751f80327ee4cc4162a1.zip
If one side of and/or is known to be 0/-1, it doesn't matter
if the other side is overdefined. This allows us to fold conditions like: if (X < Y || Y > Z) in some cases. llvm-svn: 18807
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r--llvm/lib/Transforms/Scalar/SCCP.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Scalar/SCCP.cpp b/llvm/lib/Transforms/Scalar/SCCP.cpp
index f5ca6f2fc4c..b51f3ad68cb 100644
--- a/llvm/lib/Transforms/Scalar/SCCP.cpp
+++ b/llvm/lib/Transforms/Scalar/SCCP.cpp
@@ -615,6 +615,43 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
LatticeVal &V2State = getValueState(I.getOperand(1));
if (V1State.isOverdefined() || V2State.isOverdefined()) {
+ // If this is an AND or OR with 0 or -1, it doesn't matter that the other
+ // operand is overdefined.
+ if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Or) {
+ LatticeVal *NonOverdefVal = 0;
+ if (!V1State.isOverdefined()) {
+ NonOverdefVal = &V1State;
+ } else if (!V2State.isOverdefined()) {
+ NonOverdefVal = &V2State;
+ }
+
+ if (NonOverdefVal) {
+ if (NonOverdefVal->isUndefined()) {
+ // Could annihilate value.
+ if (I.getOpcode() == Instruction::And)
+ markConstant(IV, &I, Constant::getNullValue(I.getType()));
+ else
+ markConstant(IV, &I, ConstantInt::getAllOnesValue(I.getType()));
+ return;
+ } else {
+ if (I.getOpcode() == Instruction::And) {
+ if (NonOverdefVal->getConstant()->isNullValue()) {
+ markConstant(IV, &I, NonOverdefVal->getConstant());
+ return; // X or 0 = -1
+ }
+ } else {
+ if (ConstantIntegral *CI =
+ dyn_cast<ConstantIntegral>(NonOverdefVal->getConstant()))
+ if (CI->isAllOnesValue()) {
+ markConstant(IV, &I, NonOverdefVal->getConstant());
+ return; // X or -1 = -1
+ }
+ }
+ }
+ }
+ }
+
+
// If both operands are PHI nodes, it is possible that this instruction has
// a constant value, despite the fact that the PHI node doesn't. Check for
// this condition now.
OpenPOWER on IntegriCloud