[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