[llvm-commits] CVS: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp

Nick Lewycky nicholas at mxc.ca
Sat Apr 7 08:48:50 PDT 2007



Changes in directory llvm/lib/Transforms/Scalar:

PredicateSimplifier.cpp updated: 1.65 -> 1.66
---
Log message:

Add support for cast instructions.


---
Diffs of the changes:  (+75 -17)

 PredicateSimplifier.cpp |   92 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 75 insertions(+), 17 deletions(-)


Index: llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp
diff -u llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.65 llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.66
--- llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp:1.65	Fri Apr  6 23:49:12 2007
+++ llvm/lib/Transforms/Scalar/PredicateSimplifier.cpp	Sat Apr  7 10:48:32 2007
@@ -813,6 +813,14 @@
       return Range;
     }
 
+#ifndef NDEBUG
+    bool isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP);
+#endif
+
+  public:
+
+    explicit ValueRanges(TargetData *TD) : TD(TD) {}
+
     // rangeFromValue - converts a Value into a range. If the value is a
     // constant it constructs the single element range, otherwise it performs
     // a lookup. The width W must be retrieved from typeToWidth and may not
@@ -842,14 +850,6 @@
       return 0;
     }
 
-#ifndef NDEBUG
-    bool isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP);
-#endif
-
-  public:
-
-    explicit ValueRanges(TargetData *TD) : TD(TD) {}
-
     bool isRelatedBy(Value *V1, Value *V2, ETNode *Subtree, LatticeVal LV) {
       uint32_t W = typeToWidth(V1->getType());
       if (!W) return false;
@@ -907,6 +907,7 @@
 
     void addToWorklist(Value *V, Constant *C, ICmpInst::Predicate Pred,
                        VRPSolver *VRP);
+    void markBlock(VRPSolver *VRP);
 
     void mergeInto(Value **I, unsigned n, Value *New, ETNode *Subtree,
                    VRPSolver *VRP) {
@@ -946,7 +947,14 @@
         }
       }
 
-      update(V, CR, Subtree);
+      ConstantRange Merged = CR.intersectWith(
+                                rangeFromValue(V, Subtree, CR.getBitWidth()));
+      if (Merged.isEmptySet()) {
+        markBlock(VRP);
+        return;
+      }
+
+      update(V, Merged, Subtree);
     }
 
     void addNotEquals(Value *V1, Value *V2, ETNode *Subtree, VRPSolver *VRP) {
@@ -1608,8 +1616,29 @@
           add(Ptr, Constant::getNullValue(Ptr->getType()), ICmpInst::ICMP_NE,
               NewContext);
         }
+      } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
+        const Type *SrcTy = CI->getSrcTy();
+
+        Value *TheCI = IG.canonicalize(CI, Top);
+        uint32_t W = VR.typeToWidth(SrcTy);
+        if (!W) return;
+        ConstantRange CR = VR.rangeFromValue(TheCI, Top, W);
+
+        if (CR.isFullSet()) return;
+
+        switch (CI->getOpcode()) {
+          default: break;
+          case Instruction::ZExt:
+          case Instruction::SExt:
+            VR.applyRange(IG.canonicalize(CI->getOperand(0), Top),
+                          CR.truncate(W), Top, this);
+            break;
+          case Instruction::BitCast:
+            VR.applyRange(IG.canonicalize(CI->getOperand(0), Top),
+                          CR, Top, this);
+            break;
+        }
       }
-      // TODO: CastInst "%a = cast ... %b" where %a is EQ or NE a constant.
     }
 
     /// opsToDef - A new relationship was discovered involving one of this
@@ -1639,7 +1668,7 @@
         assert(!Ty->isFPOrFPVector() && "Float in work queue!");
 
         Constant *Zero = Constant::getNullValue(Ty);
-        Constant *AllOnes = ConstantInt::getAllOnesValue(Ty);
+        ConstantInt *AllOnes = ConstantInt::getAllOnesValue(Ty);
 
         switch (Opcode) {
           default: break;
@@ -1753,16 +1782,41 @@
           add(SI, SI->getTrueValue(), ICmpInst::ICMP_EQ, NewContext);
         }
       } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
-        const Type *Ty = CI->getDestTy();
-        if (Ty->isFPOrFPVector()) return;
+        const Type *DestTy = CI->getDestTy();
+        if (DestTy->isFPOrFPVector()) return;
 
-        if (Constant *C = dyn_cast<Constant>(
-                IG.canonicalize(CI->getOperand(0), Top))) {
-          add(CI, ConstantExpr::getCast(CI->getOpcode(), C, Ty),
+        Value *Op = IG.canonicalize(CI->getOperand(0), Top);
+        Instruction::CastOps Opcode = CI->getOpcode();
+
+        if (Constant *C = dyn_cast<Constant>(Op)) {
+          add(CI, ConstantExpr::getCast(Opcode, C, DestTy),
               ICmpInst::ICMP_EQ, NewContext);
         }
 
-        // TODO: "%a = cast ... %b" where %b is NE/LT/GT a constant.
+        uint32_t W = VR.typeToWidth(DestTy);
+        Value *TheCI = IG.canonicalize(CI, Top);
+        ConstantRange CR = VR.rangeFromValue(Op, Top, W);
+
+        if (!CR.isFullSet()) {
+          switch (Opcode) {
+            default: break;
+            case Instruction::ZExt:
+              VR.applyRange(TheCI, CR.zeroExtend(W), Top, this);
+              break;
+            case Instruction::SExt:
+              VR.applyRange(TheCI, CR.signExtend(W), Top, this);
+              break;
+            case Instruction::Trunc: {
+              ConstantRange Result = CR.truncate(W);
+              if (!Result.isFullSet())
+                VR.applyRange(TheCI, Result, Top, this);
+            } break;
+            case Instruction::BitCast:
+              VR.applyRange(TheCI, CR, Top, this);
+              break;
+            // TODO: other casts?
+          }
+        }
       } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
         for (GetElementPtrInst::op_iterator OI = GEPI->idx_begin(),
              OE = GEPI->idx_end(); OI != OE; ++OI) {
@@ -1912,6 +1966,10 @@
     VRP->add(V, C, Pred, VRP->TopInst);
   }
 
+  void ValueRanges::markBlock(VRPSolver *VRP) {
+    VRP->UB.mark(VRP->TopBB);
+  }
+
 #ifndef NDEBUG
   bool ValueRanges::isCanonical(Value *V, ETNode *Subtree, VRPSolver *VRP) {
     return V == VRP->IG.canonicalize(V, Subtree);






More information about the llvm-commits mailing list