[llvm-commits] CVS: llvm/lib/VMCore/ConstantFolding.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Jan 28 11:10:04 PST 2005



Changes in directory llvm/lib/VMCore:

ConstantFolding.cpp updated: 1.70 -> 1.71
---
Log message:

Fix ConstProp/2005-01-28-SetCCGEP.ll: indexing over zero sized elements does
not change the address.


---
Diffs of the changes:  (+36 -5)

 ConstantFolding.cpp |   41 ++++++++++++++++++++++++++++++++++++-----
 1 files changed, 36 insertions(+), 5 deletions(-)


Index: llvm/lib/VMCore/ConstantFolding.cpp
diff -u llvm/lib/VMCore/ConstantFolding.cpp:1.70 llvm/lib/VMCore/ConstantFolding.cpp:1.71
--- llvm/lib/VMCore/ConstantFolding.cpp:1.70	Thu Jan  6 10:26:38 2005
+++ llvm/lib/VMCore/ConstantFolding.cpp	Fri Jan 28 13:09:51 2005
@@ -623,6 +623,22 @@
   return 0;
 }
 
+/// isZeroSizedType - This type is zero sized if its an array or structure of
+/// zero sized types.  The only leaf zero sized type is an empty structure.
+static bool isMaybeZeroSizedType(const Type *Ty) {
+  if (isa<OpaqueType>(Ty)) return true;  // Can't say.
+  if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+
+    // If all of elements have zero size, this does too.
+    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
+      if (!isMaybeZeroSizedType(Ty)) return false;
+    return true;
+
+  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    return isMaybeZeroSizedType(ATy->getElementType());
+  }
+  return false;
+}
 
 /// IdxCompare - Compare the two constants as though they were getelementptr
 /// indices.  This allows coersion of the types to be the same thing.
@@ -631,7 +647,7 @@
 /// first is less than the second, return -1, if the second is less than the
 /// first, return 1.  If the constants are not integral, return -2.
 ///
-static int IdxCompare(Constant *C1, Constant *C2) {
+static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
   if (C1 == C2) return 0;
 
   // Ok, we found a different index.  Are either of the operands
@@ -645,6 +661,11 @@
   C2 = ConstantExpr::getSignExtend(C2, Type::LongTy);
   if (C1 == C2) return 0;  // Are they just differing types?
 
+  // If the type being indexed over is really just a zero sized type, there is
+  // no pointer difference being made here.
+  if (isMaybeZeroSizedType(ElTy))
+    return -2; // dunno.
+
   // If they are really different, now that they are the same type, then we
   // found a difference!
   if (cast<ConstantSInt>(C1)->getValue() < cast<ConstantSInt>(C2)->getValue())
@@ -779,8 +800,11 @@
             unsigned i = 1;
             
             // Compare all of the operands the GEP's have in common.
-            for (;i != CE1->getNumOperands() && i != CE2->getNumOperands(); ++i)
-              switch (IdxCompare(CE1->getOperand(i), CE2->getOperand(i))) {
+            gep_type_iterator GTI = gep_type_begin(CE1);
+            for (;i != CE1->getNumOperands() && i != CE2->getNumOperands();
+                 ++i, ++GTI)
+              switch (IdxCompare(CE1->getOperand(i), CE2->getOperand(i),
+                                 GTI.getIndexedType())) {
               case -1: return Instruction::SetLT;
               case 1:  return Instruction::SetGT;
               case -2: return Instruction::BinaryOpsEnd;
@@ -790,10 +814,17 @@
             // are non-zero then we have a difference, otherwise we are equal.
             for (; i < CE1->getNumOperands(); ++i)
               if (!CE1->getOperand(i)->isNullValue())
-                return Instruction::SetGT;
+                if (isa<ConstantIntegral>(CE1->getOperand(i)))
+                  return Instruction::SetGT;
+                else
+                  return Instruction::BinaryOpsEnd; // Might be equal.
+                    
             for (; i < CE2->getNumOperands(); ++i)
               if (!CE2->getOperand(i)->isNullValue())
-                return Instruction::SetLT;
+                if (isa<ConstantIntegral>(CE2->getOperand(i)))
+                  return Instruction::SetLT;
+                else
+                  return Instruction::BinaryOpsEnd; // Might be equal.
             return Instruction::SetEQ;
           }
         }






More information about the llvm-commits mailing list