Implement Transforms/InstCombine/cast-load-gep.ll, which allows us to devirtualize
[oota-llvm.git] / lib / Transforms / Scalar / SCCP.cpp
index f5ca6f2fc4caf37e00c53f1298aa756aefd51dea..c769b549916162707e7f0bb86768f89cbc36e793 100644 (file)
@@ -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.
@@ -734,12 +771,12 @@ static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) {
       ConstantStruct *CS = dyn_cast<ConstantStruct>(C);
       if (CS == 0) return 0;
       if (CU->getValue() >= CS->getNumOperands()) return 0;
-      C = CS->getOperand(CU->getValue());
+      C = CS->getOperand((unsigned)CU->getValue());
     } else if (ConstantSInt *CS = dyn_cast<ConstantSInt>(CE->getOperand(i))) {
       ConstantArray *CA = dyn_cast<ConstantArray>(C);
       if (CA == 0) return 0;
       if ((uint64_t)CS->getValue() >= CA->getNumOperands()) return 0;
-      C = CA->getOperand(CS->getValue());
+      C = CA->getOperand((unsigned)CS->getValue());
     } else
       return 0;
   return C;