Add value range analyzing of Add and Sub.
authorNick Lewycky <nicholas@mxc.ca>
Fri, 24 Oct 2008 04:00:26 +0000 (04:00 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Fri, 24 Oct 2008 04:00:26 +0000 (04:00 +0000)
Understand that mul %x, 1 = %x.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@58069 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/PredicateSimplifier.cpp

index 665a46bfd73fb82847287e21478dc1f5c80f4776..5baaec12581e0da03595eef8c34b185b7989410b 100644 (file)
@@ -1938,6 +1938,7 @@ namespace {
         assert(!Ty->isFPOrFPVector() && "Float in work queue!");
 
         Constant *Zero = Constant::getNullValue(Ty);
+        Constant *One = ConstantInt::get(Ty, 1);
         ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
 
         switch (Opcode) {
@@ -1945,19 +1946,73 @@ namespace {
           case Instruction::LShr:
           case Instruction::AShr:
           case Instruction::Shl:
+            if (Op1 == Zero) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Sub:
             if (Op1 == Zero) {
               add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
+            if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
+              unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
+              ConstantRange CR = VR.range(n_ci0, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(CI0->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
+              unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
+              ConstantRange CR = VR.range(n_ci1, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(CI1->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
             break;
           case Instruction::Or:
             if (Op0 == AllOnes || Op1 == AllOnes) {
               add(BO, AllOnes, ICmpInst::ICMP_EQ, NewContext);
               return;
-            } // fall-through
-          case Instruction::Xor:
+            }
+            if (Op0 == Zero) {
+              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            } else if (Op1 == Zero) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Add:
+            if (ConstantInt *CI0 = dyn_cast<ConstantInt>(Op0)) {
+              unsigned n_ci0 = VN.getOrInsertVN(Op1, Top);
+              ConstantRange CR = VR.range(n_ci0, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(-CI0->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            if (ConstantInt *CI1 = dyn_cast<ConstantInt>(Op1)) {
+              unsigned n_ci1 = VN.getOrInsertVN(Op0, Top);
+              ConstantRange CR = VR.range(n_ci1, Top);
+              if (!CR.isFullSet()) {
+                CR.subtract(-CI1->getValue());
+                unsigned n_bo = VN.getOrInsertVN(BO, Top);
+                VR.applyRange(n_bo, CR, Top, this);
+                return;
+              }
+            }
+            // fall-through
+          case Instruction::Xor:
             if (Op0 == Zero) {
               add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
               return;
@@ -1974,19 +2029,30 @@ namespace {
               add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
-            // fall-through
+            if (Op0 == Zero || Op1 == Zero) {
+              add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
+            break;
           case Instruction::Mul:
             if (Op0 == Zero || Op1 == Zero) {
               add(BO, Zero, ICmpInst::ICMP_EQ, NewContext);
               return;
             }
+            if (Op0 == One) {
+              add(BO, Op1, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            } else if (Op1 == One) {
+              add(BO, Op0, ICmpInst::ICMP_EQ, NewContext);
+              return;
+            }
             break;
         }
 
         // "%x = add i32 %y, %z" and %x EQ %y then %z EQ 0
         // "%x = add i32 %y, %z" and %x EQ %z then %y EQ 0
         // "%x = shl i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 0
-        // "%x = udiv i32 %y, %z" and %x EQ %y then %z EQ 1
+        // "%x = udiv i32 %y, %z" and %x EQ %y and %y NE 0 then %z EQ 1
 
         Value *Known = Op0, *Unknown = Op1,
               *TheBO = VN.canonicalize(BO, Top);
@@ -2009,10 +2075,8 @@ namespace {
             case Instruction::UDiv:
             case Instruction::SDiv:
               if (Unknown == Op1) break;
-              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE)) {
-                Constant *One = ConstantInt::get(Ty, 1);
+              if (isRelatedBy(Known, Zero, ICmpInst::ICMP_NE))
                 add(Unknown, One, ICmpInst::ICMP_EQ, NewContext);
-              }
               break;
           }
         }
@@ -2488,7 +2552,7 @@ namespace {
 
   void PredicateSimplifier::Forwards::visitLoadInst(LoadInst &LI) {
     Value *Ptr = LI.getPointerOperand();
-    // avoid "load uint* null" -> null NE null.
+    // avoid "load i8* null" -> null NE null.
     if (isa<Constant>(Ptr)) return;
 
     VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &LI);
@@ -2624,8 +2688,8 @@ namespace {
           if (!Op1->getValue().isAllOnesValue())
             NextVal = ConstantInt::get(Op1->getValue()+1);
          break;
-
       }
+
       if (NextVal) {
         VRPSolver VRP(VN, IG, UB, VR, PS->DTDFS, PS->modified, &IC);
         if (VRP.isRelatedBy(IC.getOperand(0), NextVal,