aboutsummaryrefslogtreecommitdiff
path: root/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
commita177c6747195f2abe5a0fc10e1a65d6c0afb85b5 (patch)
tree2143a5b9674a47f631aa7387bf1b368d08bfdde8 /lib/Transforms
parente0e50dbb9fe975b4f4b3d2eb061b2ac74a5cc7c0 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18807 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/SCCP.cpp37
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp
index f5ca6f2fc4..b51f3ad68c 100644
--- a/lib/Transforms/Scalar/SCCP.cpp
+++ b/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.