From b913bbaa415299b732d72239566e203fe57761d6 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sun, 24 Dec 2006 18:52:08 +0000 Subject: [PATCH] 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 --- lib/VMCore/ConstantFold.cpp | 353 +++++++++++++++++++++-------------- lib/VMCore/ConstantFold.h | 3 +- lib/VMCore/ConstantFolding.h | 3 +- 3 files changed, 214 insertions(+), 145 deletions(-) diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 8fb02976fc4..1f751871aec 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(V1) && !isa(V1)) { - if (!isa(V2) && !isa(V2)) { - // We distilled this down to a simple case, use the standard constant - // folder. - ConstantBool *R = dyn_cast( - ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, V1, V2)); + if (!isa(V1)) { + if (!isa(V2)) { + // We distilled thisUse the standard constant folder for a few cases + ConstantBool *R = 0; + Constant *C1 = const_cast(V1); + Constant *C2 = const_cast(V2); + R = dyn_cast( + ConstantExpr::getFCmp(FCmpInst::FCMP_OEQ, C1, C2)); if (R && R->getValue()) return FCmpInst::FCMP_OEQ; R = dyn_cast( - 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( - 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(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(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(V2) && !isa(V2)) { // We distilled this down to a simple case, use the standard constant // folder. + ConstantBool *R = 0; + Constant *C1 = const_cast(V1); + Constant *C2 = const_cast(V2); ICmpInst::Predicate pred = ICmpInst::ICMP_EQ; - ConstantBool *R = - dyn_cast(ConstantExpr::getICmp(pred, V1, V2)); + R = dyn_cast(ConstantExpr::getICmp(pred, C1, C2)); if (R && R->getValue()) return pred; pred = isSigned ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; - R = dyn_cast(ConstantExpr::getICmp(pred, V1, V2)); + R = dyn_cast(ConstantExpr::getICmp(pred, C1, C2)); if (R && R->getValue()) return pred; pred = isSigned ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; - R = dyn_cast(ConstantExpr::getICmp(pred, V1, V2)); + R = dyn_cast(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(V1); - Constant *CE1Op0 = CE1->getOperand(0); + const ConstantExpr *CE1 = cast(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(V2)) + if (const ConstantExpr *CE2 = dyn_cast(V2)) if (CE2->isCast() && isa(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(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(CE1Op0)) { + if (const GlobalValue *GV = dyn_cast(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(C1) || isa(C2)) @@ -1026,24 +1041,24 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate, if (C1->isNullValue()) { if (const GlobalValue *GV = dyn_cast(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(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(C1) && isa(C2)) { bool C1Val = cast(C1)->getValue(); bool C2Val = cast(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(C1) && isa(C2)) { - if (ICmpInst::isSignedPredicate(ICmpInst::Predicate(predicate))) { + if (ICmpInst::isSignedPredicate(ICmpInst::Predicate(pred))) { int64_t V1 = cast(C1)->getSExtValue(); int64_t V2 = cast(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(C1)->getZExtValue(); uint64_t V2 = cast(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(C1) && isa(C2)) { double C1Val = cast(C1)->getValue(); double C2Val = cast(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(C1)) { - if (ConstantPacked *CP2 = dyn_cast(C2)) { - if (predicate == FCmpInst::FCMP_OEQ || predicate == FCmpInst::FCMP_UEQ) { + } else if (const ConstantPacked *CP1 = dyn_cast(C1)) { + if (const ConstantPacked *CP2 = dyn_cast(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(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(CP1->getOperand(i)), @@ -1128,97 +1143,149 @@ Constant *llvm::ConstantFoldCompareInstruction(unsigned short predicate, } } - // Evaluate the relation between the two constants, per the predicate. - switch (evaluateICmpRelation(const_cast(C1), - const_cast(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(C1) && isa(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); - - 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. - predicate = ICmpInst::getSwappedPredicate((ICmpInst::Predicate)predicate); - return ConstantFoldCompareInstruction(predicate, C2, C1); - - default: // These predicates cannot be flopped around. + 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: + // 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; + + 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(C1) && isa(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; diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index a9e3e5809aa..6d7327c01e7 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -46,7 +46,8 @@ namespace llvm { Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldCompareInstruction(unsigned short predicate, - Constant *C1, Constant *C2); + const Constant *C1, + const Constant *C2); Constant *ConstantFoldGetElementPtr(const Constant *C, const std::vector &IdxList); } // End llvm namespace diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h index a9e3e5809aa..6d7327c01e7 100644 --- a/lib/VMCore/ConstantFolding.h +++ b/lib/VMCore/ConstantFolding.h @@ -46,7 +46,8 @@ namespace llvm { Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldCompareInstruction(unsigned short predicate, - Constant *C1, Constant *C2); + const Constant *C1, + const Constant *C2); Constant *ConstantFoldGetElementPtr(const Constant *C, const std::vector &IdxList); } // End llvm namespace