[llvm-commits] CVS: llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Chris Lattner lattner at cs.uiuc.edu
Sat Jun 19 02:10:01 PDT 2004


Changes in directory llvm/lib/Transforms/Utils:

SimplifyCFG.cpp updated: 1.41 -> 1.42

---
Log message:

Do not sort by the address of LLVM ConstantInt* objects.  This produces 
nondeterministic results that depend on where these objects land in memory.
Instead, sort by the value of the constant, which is stable.

Before this patch, the -simplifycfg pass run from two different compilers
could cause different code to be generated, though it was semantically the
same:

@@ -12258,8 +12258,8 @@
        %s_addr.1 = phi sbyte* [ %s, %entry ], [ %inc.0, %no_exit ]             ; <sbyte*> [#uses=5]
        %tmp.1 = load sbyte* %s_addr.1          ; <sbyte> [#uses=1]
        switch sbyte %tmp.1, label %no_exit [
-                sbyte 0, label %loopexit
                 sbyte 46, label %loopexit
+                sbyte 0, label %loopexit
        ]
 
We need to stomp all of this stuff out.



---
Diffs of the changes:  (+21 -10)

Index: llvm/lib/Transforms/Utils/SimplifyCFG.cpp
diff -u llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.41 llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.42
--- llvm/lib/Transforms/Utils/SimplifyCFG.cpp:1.41	Sun May  2 00:19:36 2004
+++ llvm/lib/Transforms/Utils/SimplifyCFG.cpp	Sat Jun 19 02:02:14 2004
@@ -241,13 +241,13 @@
 // GatherConstantSetEQs - Given a potentially 'or'd together collection of seteq
 // instructions that compare a value against a constant, return the value being
 // compared, and stick the constant into the Values vector.
-static Value *GatherConstantSetEQs(Value *V, std::vector<Constant*> &Values) {
+static Value *GatherConstantSetEQs(Value *V, std::vector<ConstantInt*> &Values){
   if (Instruction *Inst = dyn_cast<Instruction>(V))
     if (Inst->getOpcode() == Instruction::SetEQ) {
-      if (Constant *C = dyn_cast<Constant>(Inst->getOperand(1))) {
+      if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
         Values.push_back(C);
         return Inst->getOperand(0);
-      } else if (Constant *C = dyn_cast<Constant>(Inst->getOperand(0))) {
+      } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
         Values.push_back(C);
         return Inst->getOperand(1);
       }
@@ -263,20 +263,20 @@
 // GatherConstantSetNEs - Given a potentially 'and'd together collection of
 // setne instructions that compare a value against a constant, return the value
 // being compared, and stick the constant into the Values vector.
-static Value *GatherConstantSetNEs(Value *V, std::vector<Constant*> &Values) {
+static Value *GatherConstantSetNEs(Value *V, std::vector<ConstantInt*> &Values){
   if (Instruction *Inst = dyn_cast<Instruction>(V))
     if (Inst->getOpcode() == Instruction::SetNE) {
-      if (Constant *C = dyn_cast<Constant>(Inst->getOperand(1))) {
+      if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(1))) {
         Values.push_back(C);
         return Inst->getOperand(0);
-      } else if (Constant *C = dyn_cast<Constant>(Inst->getOperand(0))) {
+      } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand(0))) {
         Values.push_back(C);
         return Inst->getOperand(1);
       }
     } else if (Inst->getOpcode() == Instruction::Cast) {
       // Cast of X to bool is really a comparison against zero.
       assert(Inst->getType() == Type::BoolTy && "Can only handle bool values!");
-      Values.push_back(Constant::getNullValue(Inst->getOperand(0)->getType()));
+      Values.push_back(ConstantInt::get(Inst->getOperand(0)->getType(), 0));
       return Inst->getOperand(0);
     } else if (Inst->getOpcode() == Instruction::And) {
       if (Value *LHS = GatherConstantSetNEs(Inst->getOperand(0), Values))
@@ -293,7 +293,7 @@
 /// bunch of comparisons of one value against constants, return the value and
 /// the constants being compared.
 static bool GatherValueComparisons(Instruction *Cond, Value *&CompVal,
-                                   std::vector<Constant*> &Values) {
+                                   std::vector<ConstantInt*> &Values) {
   if (Cond->getOpcode() == Instruction::Or) {
     CompVal = GatherConstantSetEQs(Cond, Values);
 
@@ -533,6 +533,17 @@
   return Changed;
 }
 
+namespace {
+  /// ConstantIntOrdering - This class implements a stable ordering of constant
+  /// integers that does not depend on their address.  This is important for
+  /// applications that sort ConstantInt's to ensure uniqueness.
+  struct ConstantIntOrdering {
+    bool operator()(const ConstantInt *LHS, const ConstantInt *RHS) const {
+      return LHS->getRawValue() < RHS->getRawValue();
+    }
+  };
+}
+
 
 // SimplifyCFG - This function is used to do simplification of a CFG.  For
 // example, it adjusts branches to branches to eliminate the extra hop, it
@@ -952,12 +963,12 @@
         // If this is a bunch of seteq's or'd together, or if it's a bunch of
         // 'setne's and'ed together, collect them.
         Value *CompVal = 0;
-        std::vector<Constant*> Values;
+        std::vector<ConstantInt*> Values;
         bool TrueWhenEqual = GatherValueComparisons(Cond, CompVal, Values);
         if (CompVal && CompVal->getType()->isInteger()) {
           // There might be duplicate constants in the list, which the switch
           // instruction can't handle, remove them now.
-          std::sort(Values.begin(), Values.end());
+          std::sort(Values.begin(), Values.end(), ConstantIntOrdering());
           Values.erase(std::unique(Values.begin(), Values.end()), Values.end());
           
           // Figure out which block is which destination.





More information about the llvm-commits mailing list