+ // Ok, we have two differing integer indices. Sign extend them to be the same
+ // type. Long is always big enough, so we use it.
+ C1 = ConstantExpr::getSignExtend(C1, Type::LongTy);
+ C2 = ConstantExpr::getSignExtend(C2, Type::LongTy);
+ if (C1 == C2) return 0; // Are they just differing types?
+
+ // 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())
+ return -1;
+ else
+ return 1;
+}
+
+/// evaluateRelation - This function determines if there is anything we can
+/// decide about the two constants provided. This doesn't need to handle simple
+/// things like integer comparisons, but should instead handle ConstantExprs
+/// and GlobalValuess. If we can determine that the two constants have a
+/// particular relation to each other, we should return the corresponding SetCC
+/// code, otherwise return Instruction::BinaryOpsEnd.
+///
+/// To simplify this code we canonicalize the relation so that the first
+/// operand is always the most "complex" of the two. We consider simple
+/// constants (like ConstantInt) to be the simplest, followed by
+/// GlobalValues, followed by ConstantExpr's (the most complex).
+///
+static Instruction::BinaryOps evaluateRelation(const Constant *V1,
+ const Constant *V2) {
+ assert(V1->getType() == V2->getType() &&
+ "Cannot compare different types of values!");
+ if (V1 == V2) return Instruction::SetEQ;
+
+ if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1)) {
+ // If the first operand is simple, swap operands.
+ assert((isa<GlobalValue>(V2) || isa<ConstantExpr>(V2)) &&
+ "Simple cases should have been handled by caller!");
+ Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1);
+ if (SwappedRelation != Instruction::BinaryOpsEnd)
+ return SetCondInst::getSwappedCondition(SwappedRelation);
+
+ } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(V1)){
+ if (isa<ConstantExpr>(V2)) { // Swap as necessary.
+ Instruction::BinaryOps SwappedRelation = evaluateRelation(V2, V1);
+ if (SwappedRelation != Instruction::BinaryOpsEnd)
+ return SetCondInst::getSwappedCondition(SwappedRelation);
+ else
+ return Instruction::BinaryOpsEnd;
+ }
+
+ // Now we know that the RHS is a GlobalValue or simple constant,
+ // which (since the types must match) means that it's a ConstantPointerNull.
+ if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+ assert(CPR1 != CPR2 &&
+ "GVs for the same value exist at different addresses??");
+ // FIXME: If both globals are external weak, they might both be null!
+ return Instruction::SetNE;
+ } else {
+ assert(isa<ConstantPointerNull>(V2) && "Canonicalization guarantee!");
+ // Global can never be null. FIXME: if we implement external weak
+ // linkage, this is not necessarily true!
+ return Instruction::SetNE;
+ }
+
+ } else {
+ // Ok, the LHS is known to be a constantexpr. The RHS can be any of a
+ // constantexpr, a CPR, or a simple constant.
+ const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+ Constant *CE1Op0 = CE1->getOperand(0);
+
+ switch (CE1->getOpcode()) {
+ case Instruction::Cast:
+ // If the cast is not actually changing bits, and the second operand is a
+ // null pointer, do the comparison with the pre-casted value.
+ if (V2->isNullValue() &&
+ CE1->getType()->isLosslesslyConvertibleTo(CE1Op0->getType()))
+ return evaluateRelation(CE1Op0,
+ Constant::getNullValue(CE1Op0->getType()));
+ break;
+
+ case Instruction::GetElementPtr:
+ // Ok, since this is a getelementptr, we know that the constant has a
+ // pointer type. Check the various cases.
+ if (isa<ConstantPointerNull>(V2)) {
+ // If we are comparing a GEP to a null pointer, check to see if the base
+ // of the GEP equals the null pointer.
+ if (isa<GlobalValue>(CE1Op0)) {
+ // FIXME: this is not true when we have external weak references!
+ // No offset can go from a global to a null pointer.
+ return Instruction::SetGT;
+ } else if (isa<ConstantPointerNull>(CE1Op0)) {
+ // If we are indexing from a null pointer, check to see if we have any
+ // non-zero indices.
+ for (unsigned i = 1, e = CE1->getNumOperands(); i != e; ++i)
+ if (!CE1->getOperand(i)->isNullValue())
+ // Offsetting from null, must not be equal.
+ return Instruction::SetGT;
+ // Only zero indexes from null, must still be zero.
+ return Instruction::SetEQ;
+ }
+ // Otherwise, we can't really say if the first operand is null or not.
+ } else if (const GlobalValue *CPR2 = dyn_cast<GlobalValue>(V2)) {
+ if (isa<ConstantPointerNull>(CE1Op0)) {
+ // FIXME: This is not true with external weak references.
+ return Instruction::SetLT;
+ } else if (const GlobalValue *CPR1 = dyn_cast<GlobalValue>(CE1Op0)) {
+ if (CPR1 == CPR2) {
+ // If this is a getelementptr of the same global, then it must be
+ // different. Because the types must match, the getelementptr could
+ // only have at most one index, and because we fold getelementptr's
+ // with a single zero index, it must be nonzero.
+ assert(CE1->getNumOperands() == 2 &&
+ !CE1->getOperand(1)->isNullValue() &&
+ "Suprising getelementptr!");
+ return Instruction::SetGT;
+ } else {
+ // If they are different globals, we don't know what the value is,
+ // but they can't be equal.
+ return Instruction::SetNE;
+ }
+ }
+ } else {
+ const ConstantExpr *CE2 = cast<ConstantExpr>(V2);
+ const Constant *CE2Op0 = CE2->getOperand(0);
+
+ // There are MANY other foldings that we could perform here. They will
+ // probably be added on demand, as they seem needed.
+ switch (CE2->getOpcode()) {
+ default: break;
+ case Instruction::GetElementPtr:
+ // By far the most common case to handle is when the base pointers are
+ // obviously to the same or different globals.
+ if (isa<GlobalValue>(CE1Op0) && isa<GlobalValue>(CE2Op0)) {
+ if (CE1Op0 != CE2Op0) // Don't know relative ordering, but not equal
+ return Instruction::SetNE;
+ // Ok, we know that both getelementptr instructions are based on the
+ // same global. From this, we can precisely determine the relative
+ // ordering of the resultant pointers.
+ 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))) {
+ case -1: return Instruction::SetLT;
+ case 1: return Instruction::SetGT;
+ case -2: return Instruction::BinaryOpsEnd;
+ }
+
+ // Ok, we ran out of things they have in common. If any leftovers
+ // 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;
+ for (; i < CE2->getNumOperands(); ++i)
+ if (!CE2->getOperand(i)->isNullValue())
+ return Instruction::SetLT;
+ return Instruction::SetEQ;
+ }
+ }
+ }
+
+ default:
+ break;
+ }