summaryrefslogtreecommitdiff
path: root/lib/VMCore/ConstantFold.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2006-12-24 18:52:08 +0000
committerReid Spencer <rspencer@reidspencer.com>2006-12-24 18:52:08 +0000
commitb913bbaa415299b732d72239566e203fe57761d6 (patch)
tree92d43efdddc22c07e35b1b612d91bfa22597fe9d /lib/VMCore/ConstantFold.cpp
parent4fa021a1a9e062683e203d775bae897fb8b75fac (diff)
downloadllvm-b913bbaa415299b732d72239566e203fe57761d6.tar.gz
llvm-b913bbaa415299b732d72239566e203fe57761d6.tar.bz2
llvm-b913bbaa415299b732d72239566e203fe57761d6.tar.xz
Cleanup ConstantFoldCompareInstruction:
1. Make the arguments const like the other ConstantFold* functions. 2. Clean up evaluateFCmpRelation so it makes sense for floating point. 3. Implement the use of evaluateFCmpRelation to fold floating point CEs 4. Shorten a variable name so more things fit on one line. 5. Fix various comments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32759 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/ConstantFold.cpp')
-rw-r--r--lib/VMCore/ConstantFold.cpp335
1 files changed, 201 insertions, 134 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 8fb02976fc..1f751871ae 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -742,50 +742,61 @@ static int IdxCompare(Constant *C1, Constant *C2, const Type *ElTy) {
/// things like ConstantFP comparisons, but should instead handle ConstantExprs.
/// If we can determine that the two constants have a particular relation to
/// each other, we should return the corresponding FCmpInst predicate,
-/// otherwise return FCmpInst::BAD_FCMP_PREDICATE.
+/// otherwise return FCmpInst::BAD_FCMP_PREDICATE. This is used below in
+/// ConstantFoldCompareInstruction.
///
/// 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 ConstantFP) to be the simplest, followed by
-/// GlobalValues, followed by ConstantExpr's (the most complex).
-static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) {
+/// operand is always the most "complex" of the two. We consider ConstantFP
+/// to be the simplest, and ConstantExprs to be the most complex.
+static FCmpInst::Predicate evaluateFCmpRelation(const Constant *V1,
+ const Constant *V2) {
assert(V1->getType() == V2->getType() &&
- "Cannot compare different types of values!");
+ "Cannot compare values of different types!");
+ // Handle degenerate case quickly
if (V1 == V2) return FCmpInst::FCMP_OEQ;
- if (!isa<ConstantExpr>(V1) && !isa<GlobalValue>(V1)) {
- if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2)) {
- // We distilled this down to a simple case, use the standard constant
- // folder.
- ConstantBool *R = dyn_cast<ConstantBool>(
- ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, V1, V2));
+ if (!isa<ConstantExpr>(V1)) {
+ if (!isa<ConstantExpr>(V2)) {
+ // We distilled thisUse the standard constant folder for a few cases
+ ConstantBool *R = 0;
+ Constant *C1 = const_cast<Constant*>(V1);
+ Constant *C2 = const_cast<Constant*>(V2);
+ R = dyn_cast<ConstantBool>(
+ ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, C1, C2));
if (R && R->getValue())
return FCmpInst::FCMP_OEQ;
R = dyn_cast<ConstantBool>(
- ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, V1, V2));
+ ConstantExpr::getFCmp(FCmpInst::FCMP_OLT, C1, C2));
if (R && R->getValue())
return FCmpInst::FCMP_OLT;
R = dyn_cast<ConstantBool>(
- ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, V1, V2));
- if (R && R->getValue()) return FCmpInst::FCMP_OGT;
-
- // If we couldn't figure it out, bail.
+ ConstantExpr::getFCmp(FCmpInst::FCMP_OGT, C1, C2));
+ if (R && R->getValue())
+ return FCmpInst::FCMP_OGT;
+
+ // Nothing more we can do
return FCmpInst::BAD_FCMP_PREDICATE;
}
- // If the first operand is simple, swap operands.
- FCmpInst::Predicate SwappedPredicate = evaluateFCmpRelation(V2, V1);
- if (SwappedPredicate != FCmpInst::BAD_FCMP_PREDICATE)
- return FCmpInst::getSwappedPredicate(SwappedPredicate);
-
- return FCmpInst::BAD_FCMP_PREDICATE;
+ // If the first operand is simple and second is ConstantExpr, swap operands.
+ FCmpInst::Predicate SwappedRelation = evaluateFCmpRelation(V2, V1);
+ if (SwappedRelation != FCmpInst::BAD_FCMP_PREDICATE)
+ return FCmpInst::getSwappedPredicate(SwappedRelation);
+ } else {
+ // Ok, the LHS is known to be a constantexpr. The RHS can be any of a
+ // constantexpr or a simple constant.
+ const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+ switch (CE1->getOpcode()) {
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ // We might be able to do something with these but we don't right now.
+ break;
+ default:
+ break;
+ }
}
-
- // Ok, the LHS is known to be a constantexpr. The RHS can be any of a
- // constantexpr, a CPR, or a simple constant.
- // ConstantExpr *CE1 = cast<ConstantExpr>(V1);
- // Constant *CE1Op0 = CE1->getOperand(0);
-
// There are MANY other foldings that we could perform here. They will
// probably be added on demand, as they seem needed.
return FCmpInst::BAD_FCMP_PREDICATE;
@@ -803,7 +814,8 @@ static FCmpInst::Predicate evaluateFCmpRelation(Constant *V1, Constant *V2) {
/// constants (like ConstantInt) to be the simplest, followed by
/// GlobalValues, followed by ConstantExpr's (the most complex).
///
-static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
+static ICmpInst::Predicate evaluateICmpRelation(const Constant *V1,
+ const Constant *V2,
bool isSigned) {
assert(V1->getType() == V2->getType() &&
"Cannot compare different types of values!");
@@ -813,17 +825,19 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
if (!isa<GlobalValue>(V2) && !isa<ConstantExpr>(V2)) {
// We distilled this down to a simple case, use the standard constant
// folder.
+ ConstantBool *R = 0;
+ Constant *C1 = const_cast<Constant*>(V1);
+ Constant *C2 = const_cast<Constant*>(V2);
ICmpInst::Predicate pred = ICmpInst::ICMP_EQ;
- ConstantBool *R =
- dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, V1, V2));
+ R = dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, C1, C2));
if (R && R->getValue())
return pred;
pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT;
- R = dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, V1, V2));
+ R = dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, C1, C2));
if (R && R->getValue())
return pred;
pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
- R = dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, V1, V2));
+ R = dyn_cast<ConstantBool>(ConstantExpr::getICmp(pred, C1, C2));
if (R && R->getValue())
return pred;
@@ -861,8 +875,8 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
} else {
// Ok, the LHS is known to be a constantexpr. The RHS can be any of a
// constantexpr, a CPR, or a simple constant.
- ConstantExpr *CE1 = cast<ConstantExpr>(V1);
- Constant *CE1Op0 = CE1->getOperand(0);
+ const ConstantExpr *CE1 = cast<ConstantExpr>(V1);
+ const Constant *CE1Op0 = CE1->getOperand(0);
switch (CE1->getOpcode()) {
case Instruction::Trunc:
@@ -894,7 +908,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
// from the same type as the src of the LHS, evaluate the inputs. This is
// important for things like "icmp eq (cast 4 to int*), (cast 5 to int*)",
// which happens a lot in compilers with tagged integers.
- if (ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2))
+ if (const ConstantExpr *CE2 = dyn_cast<ConstantExpr>(V2))
if (CE2->isCast() && isa<PointerType>(CE1->getType()) &&
CE1->getOperand(0)->getType() == CE2->getOperand(0)->getType() &&
CE1->getOperand(0)->getType()->isIntegral()) {
@@ -912,7 +926,7 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
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 (GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0)) {
+ if (const GlobalValue *GV = dyn_cast<GlobalValue>(CE1Op0)) {
if (GV->hasExternalWeakLinkage())
// Weak linkage GVals could be zero or not. We're comparing that
// to null pointer so its greater-or-equal
@@ -1015,8 +1029,9 @@ static ICmpInst::Predicate evaluateICmpRelation(Constant *V1, Constant *V2,
return ICmpInst::BAD_ICMP_PREDICATE;
}
-Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
- Constant *C1, Constant *C2) {
+Constant *llvm::ConstantFoldCompareInstruction(unsigned short pred,
+ const Constant *C1,
+ const Constant *C2) {
// Handle some degenerate cases first
if (isa<UndefValue>(C1) || isa<UndefValue>(C2))
@@ -1026,24 +1041,24 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
if (C1->isNullValue()) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C2))
if (!GV->hasExternalWeakLinkage()) // External weak GV can be null
- if (predicate == ICmpInst::ICMP_EQ)
+ if (pred == ICmpInst::ICMP_EQ)
return ConstantBool::getFalse();
- else if (predicate == ICmpInst::ICMP_NE)
+ else if (pred == ICmpInst::ICMP_NE)
return ConstantBool::getTrue();
// icmp eq/ne(GV,null) -> false/true
} else if (C2->isNullValue()) {
if (const GlobalValue *GV = dyn_cast<GlobalValue>(C1))
if (!GV->hasExternalWeakLinkage()) // External weak GV can be null
- if (predicate == ICmpInst::ICMP_EQ)
+ if (pred == ICmpInst::ICMP_EQ)
return ConstantBool::getFalse();
- else if (predicate == ICmpInst::ICMP_NE)
+ else if (pred == ICmpInst::ICMP_NE)
return ConstantBool::getTrue();
}
if (isa<ConstantBool>(C1) && isa<ConstantBool>(C2)) {
bool C1Val = cast<ConstantBool>(C1)->getValue();
bool C2Val = cast<ConstantBool>(C2)->getValue();
- switch (predicate) {
+ switch (pred) {
default: assert(0 && "Invalid ICmp Predicate"); return 0;
case ICmpInst::ICMP_EQ: return ConstantBool::get(C1Val == C2Val);
case ICmpInst::ICMP_NE: return ConstantBool::get(C1Val != C2Val);
@@ -1057,10 +1072,10 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
case ICmpInst::ICMP_SGE:return ConstantBool::get(C1Val >= C2Val);
}
} else if (isa<ConstantInt>(C1) && isa<ConstantInt>(C2)) {
- if (ICmpInst::isSignedPredicate(ICmpInst::Predicate(predicate))) {
+ if (ICmpInst::isSignedPredicate(ICmpInst::Predicate(pred))) {
int64_t V1 = cast<ConstantInt>(C1)->getSExtValue();
int64_t V2 = cast<ConstantInt>(C2)->getSExtValue();
- switch (predicate) {
+ switch (pred) {
default: assert(0 && "Invalid ICmp Predicate"); return 0;
case ICmpInst::ICMP_SLT:return ConstantBool::get(V1 < V2);
case ICmpInst::ICMP_SGT:return ConstantBool::get(V1 > V2);
@@ -1070,7 +1085,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
} else {
uint64_t V1 = cast<ConstantInt>(C1)->getZExtValue();
uint64_t V2 = cast<ConstantInt>(C2)->getZExtValue();
- switch (predicate) {
+ switch (pred) {
default: assert(0 && "Invalid ICmp Predicate"); return 0;
case ICmpInst::ICMP_EQ: return ConstantBool::get(V1 == V2);
case ICmpInst::ICMP_NE: return ConstantBool::get(V1 != V2);
@@ -1083,7 +1098,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
} else if (isa<ConstantFP>(C1) && isa<ConstantFP>(C2)) {
double C1Val = cast<ConstantFP>(C1)->getValue();
double C2Val = cast<ConstantFP>(C2)->getValue();
- switch (predicate) {
+ switch (pred) {
default: assert(0 && "Invalid FCmp Predicate"); return 0;
case FCmpInst::FCMP_FALSE: return ConstantBool::getFalse();
case FCmpInst::FCMP_TRUE: return ConstantBool::getTrue();
@@ -1102,9 +1117,9 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
case FCmpInst::FCMP_UGE:
case FCmpInst::FCMP_OGE: return ConstantBool::get(C1Val >= C2Val);
}
- } else if (ConstantPacked *CP1 = dyn_cast<ConstantPacked>(C1)) {
- if (ConstantPacked *CP2 = dyn_cast<ConstantPacked>(C2)) {
- if (predicate == FCmpInst::FCMP_OEQ || predicate == FCmpInst::FCMP_UEQ) {
+ } else if (const ConstantPacked *CP1 = dyn_cast<ConstantPacked>(C1)) {
+ if (const ConstantPacked *CP2 = dyn_cast<ConstantPacked>(C2)) {
+ if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
Constant *C= ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ,
const_cast<Constant*>(CP1->getOperand(i)),
@@ -1114,7 +1129,7 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
}
// Otherwise, could not decide from any element pairs.
return 0;
- } else if (predicate == ICmpInst::ICMP_EQ) {
+ } else if (pred == ICmpInst::ICMP_EQ) {
for (unsigned i = 0, e = CP1->getNumOperands(); i != e; ++i) {
Constant *C = ConstantExpr::getICmp(ICmpInst::ICMP_EQ,
const_cast<Constant*>(CP1->getOperand(i)),
@@ -1128,98 +1143,150 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate,
}
}
- // Evaluate the relation between the two constants, per the predicate.
- switch (evaluateICmpRelation(const_cast<Constant*>(C1),
- const_cast<Constant*>(C2),
- CmpInst::isSigned(predicate))) {
- default: assert(0 && "Unknown relational!");
- case ICmpInst::BAD_ICMP_PREDICATE:
- break; // Couldn't determine anything about these constants.
- case ICmpInst::ICMP_EQ: // We know the constants are equal!
- // If we know the constants are equal, we can decide the result of this
- // computation precisely.
- return ConstantBool::get(predicate == ICmpInst::ICMP_EQ ||
- predicate == ICmpInst::ICMP_ULE ||
- predicate == ICmpInst::ICMP_SLE ||
- predicate == ICmpInst::ICMP_UGE ||
- predicate == ICmpInst::ICMP_SGE);
- case ICmpInst::ICMP_ULT:
- // If we know that C1 < C2, we can decide the result of this computation
- // precisely.
- return ConstantBool::get(predicate == ICmpInst::ICMP_ULT ||
- predicate == ICmpInst::ICMP_NE ||
- predicate == ICmpInst::ICMP_ULE);
- case ICmpInst::ICMP_SLT:
- // If we know that C1 < C2, we can decide the result of this computation
- // precisely.
- return ConstantBool::get(predicate == ICmpInst::ICMP_SLT ||
- predicate == ICmpInst::ICMP_NE ||
- predicate == ICmpInst::ICMP_SLE);
- case ICmpInst::ICMP_UGT:
- // If we know that C1 > C2, we can decide the result of this computation
- // precisely.
- return ConstantBool::get(predicate == ICmpInst::ICMP_UGT ||
- predicate == ICmpInst::ICMP_NE ||
- predicate == ICmpInst::ICMP_UGE);
- case ICmpInst::ICMP_SGT:
- // If we know that C1 > C2, we can decide the result of this computation
- // precisely.
- return ConstantBool::get(predicate == ICmpInst::ICMP_SGT ||
- predicate == ICmpInst::ICMP_NE ||
- predicate == ICmpInst::ICMP_SGE);
- case ICmpInst::ICMP_ULE:
- // If we know that C1 <= C2, we can only partially decide this relation.
- if (predicate == ICmpInst::ICMP_UGT) return ConstantBool::getFalse();
- if (predicate == ICmpInst::ICMP_ULT) return ConstantBool::getTrue();
- break;
- case ICmpInst::ICMP_SLE:
- // If we know that C1 <= C2, we can only partially decide this relation.
- if (predicate == ICmpInst::ICMP_SGT) return ConstantBool::getFalse();
- if (predicate == ICmpInst::ICMP_SLT) return ConstantBool::getTrue();
- break;
-
- case ICmpInst::ICMP_UGE:
- // If we know that C1 >= C2, we can only partially decide this relation.
- if (predicate == ICmpInst::ICMP_ULT) return ConstantBool::getFalse();
- if (predicate == ICmpInst::ICMP_UGT) return ConstantBool::getTrue();
- break;
- case ICmpInst::ICMP_SGE:
- // If we know that C1 >= C2, we can only partially decide this relation.
- if (predicate == ICmpInst::ICMP_SLT) return ConstantBool::getFalse();
- if (predicate == ICmpInst::ICMP_SGT) return ConstantBool::getTrue();
- break;
-
- case ICmpInst::ICMP_NE:
- // If we know that C1 != C2, we can only partially decide this relation.
- if (predicate == ICmpInst::ICMP_EQ) return ConstantBool::getFalse();
- if (predicate == ICmpInst::ICMP_NE) return ConstantBool::getTrue();
- break;
- }
-
- if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) {
- // If C2 is a constant expr and C1 isn't, flop them around and fold the
- // other way if possible.
- switch (predicate) {
- case ICmpInst::ICMP_EQ:
- case ICmpInst::ICMP_NE:
- // No change of predicate required.
- return ConstantFoldCompareInstruction(predicate, C2, C1);
-
+ if (C1->getType()->isFloatingPoint()) {
+ switch (evaluateFCmpRelation(C1, C2)) {
+ default: assert(0 && "Unknown relation!");
+ case FCmpInst::FCMP_UNO:
+ case FCmpInst::FCMP_ORD:
+ case FCmpInst::FCMP_UEQ:
+ case FCmpInst::FCMP_UNE:
+ case FCmpInst::FCMP_ULT:
+ case FCmpInst::FCMP_UGT:
+ case FCmpInst::FCMP_ULE:
+ case FCmpInst::FCMP_UGE:
+ case FCmpInst::FCMP_TRUE:
+ case FCmpInst::FCMP_FALSE:
+ case FCmpInst::BAD_FCMP_PREDICATE:
+ break; // Couldn't determine anything about these constants.
+ case FCmpInst::FCMP_OEQ: // We know that C1 == C2
+ return ConstantBool::get(
+ pred == FCmpInst::FCMP_UEQ || pred == FCmpInst::FCMP_OEQ ||
+ pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE ||
+ pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ case FCmpInst::FCMP_OLT: // We know that C1 < C2
+ return ConstantBool::get(
+ pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+ pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT ||
+ pred == FCmpInst::FCMP_ULE || pred == FCmpInst::FCMP_OLE);
+ case FCmpInst::FCMP_OGT: // We know that C1 > C2
+ return ConstantBool::get(
+ pred == FCmpInst::FCMP_UNE || pred == FCmpInst::FCMP_ONE ||
+ pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT ||
+ pred == FCmpInst::FCMP_UGE || pred == FCmpInst::FCMP_OGE);
+ case FCmpInst::FCMP_OLE: // We know that C1 <= C2
+ // We can only partially decide this relation.
+ if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT)
+ return ConstantBool::getFalse();
+ if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT)
+ return ConstantBool::getTrue();
+ break;
+ case FCmpInst::FCMP_OGE: // We known that C1 >= C2
+ // We can only partially decide this relation.
+ if (pred == FCmpInst::FCMP_ULT || pred == FCmpInst::FCMP_OLT)
+ return ConstantBool::getFalse();
+ if (pred == FCmpInst::FCMP_UGT || pred == FCmpInst::FCMP_OGT)
+ return ConstantBool::getTrue();
+ break;
+ case ICmpInst::ICMP_NE: // We know that C1 != C2
+ // We can only partially decide this relation.
+ if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ)
+ return ConstantBool::getFalse();
+ if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE)
+ return ConstantBool::getTrue();
+ break;
+ }
+ } else {
+ // Evaluate the relation between the two constants, per the predicate.
+ switch (evaluateICmpRelation(C1, C2, CmpInst::isSigned(pred))) {
+ default: assert(0 && "Unknown relational!");
+ case ICmpInst::BAD_ICMP_PREDICATE:
+ break; // Couldn't determine anything about these constants.
+ case ICmpInst::ICMP_EQ: // We know the constants are equal!
+ // If we know the constants are equal, we can decide the result of this
+ // computation precisely.
+ return ConstantBool::get(pred == ICmpInst::ICMP_EQ ||
+ pred == ICmpInst::ICMP_ULE ||
+ pred == ICmpInst::ICMP_SLE ||
+ pred == ICmpInst::ICMP_UGE ||
+ pred == ICmpInst::ICMP_SGE);
case ICmpInst::ICMP_ULT:
+ // If we know that C1 < C2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(pred == ICmpInst::ICMP_ULT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_ULE);
case ICmpInst::ICMP_SLT:
+ // If we know that C1 < C2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(pred == ICmpInst::ICMP_SLT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_SLE);
case ICmpInst::ICMP_UGT:
+ // If we know that C1 > C2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(pred == ICmpInst::ICMP_UGT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_UGE);
case ICmpInst::ICMP_SGT:
+ // If we know that C1 > C2, we can decide the result of this computation
+ // precisely.
+ return ConstantBool::get(pred == ICmpInst::ICMP_SGT ||
+ pred == ICmpInst::ICMP_NE ||
+ pred == ICmpInst::ICMP_SGE);
case ICmpInst::ICMP_ULE:
+ // If we know that C1 <= C2, we can only partially decide this relation.
+ if (pred == ICmpInst::ICMP_UGT) return ConstantBool::getFalse();
+ if (pred == ICmpInst::ICMP_ULT) return ConstantBool::getTrue();
+ break;
case ICmpInst::ICMP_SLE:
+ // If we know that C1 <= C2, we can only partially decide this relation.
+ if (pred == ICmpInst::ICMP_SGT) return ConstantBool::getFalse();
+ if (pred == ICmpInst::ICMP_SLT) return ConstantBool::getTrue();
+ break;
+
case ICmpInst::ICMP_UGE:
+ // If we know that C1 >= C2, we can only partially decide this relation.
+ if (pred == ICmpInst::ICMP_ULT) return ConstantBool::getFalse();
+ if (pred == ICmpInst::ICMP_UGT) return ConstantBool::getTrue();
+ break;
case ICmpInst::ICMP_SGE:
- // Change the predicate as necessary to swap the operands.
- predicate = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)predicate);
- return ConstantFoldCompareInstruction(predicate, C2, C1);
+ // If we know that C1 >= C2, we can only partially decide this relation.
+ if (pred == ICmpInst::ICMP_SLT) return ConstantBool::getFalse();
+ if (pred == ICmpInst::ICMP_SGT) return ConstantBool::getTrue();
+ break;
- default: // These predicates cannot be flopped around.
+ case ICmpInst::ICMP_NE:
+ // If we know that C1 != C2, we can only partially decide this relation.
+ if (pred == ICmpInst::ICMP_EQ) return ConstantBool::getFalse();
+ if (pred == ICmpInst::ICMP_NE) return ConstantBool::getTrue();
break;
}
+
+ if (!isa<ConstantExpr>(C1) && isa<ConstantExpr>(C2)) {
+ // If C2 is a constant expr and C1 isn't, flop them around and fold the
+ // other way if possible.
+ switch (pred) {
+ case ICmpInst::ICMP_EQ:
+ case ICmpInst::ICMP_NE:
+ // No change of predicate required.
+ return ConstantFoldCompareInstruction(pred, C2, C1);
+
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ // Change the predicate as necessary to swap the operands.
+ pred = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)pred);
+ return ConstantFoldCompareInstruction(pred, C2, C1);
+
+ default: // These predicates cannot be flopped around.
+ break;
+ }
+ }
}
return 0;
}