aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/InstructionCombining.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/InstructionCombining.cpp')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp1704
1 files changed, 1023 insertions, 681 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index 8b6f370..205dfef 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -24,8 +24,8 @@
// 1. If a binary operator has a constant operand, it is moved to the RHS
// 2. Bitwise operators with constant operands are always grouped so that
// shifts are performed first, then or's, then and's, then xor's.
-// 3. SetCC instructions are converted from <,>,<=,>= to ==,!= if possible
-// 4. All SetCC instructions on boolean values are replaced with logical ops
+// 3. Compare instructions are converted from <,>,<=,>= to ==,!= if possible
+// 4. All cmp instructions on boolean values are replaced with logical ops
// 5. add X, X is represented as (X*2) => (X << 1)
// 6. Multiplies with a power-of-two constant argument are transformed into
// shifts.
@@ -143,11 +143,12 @@ namespace {
Instruction *visitAnd(BinaryOperator &I);
Instruction *visitOr (BinaryOperator &I);
Instruction *visitXor(BinaryOperator &I);
- Instruction *visitSetCondInst(SetCondInst &I);
- Instruction *visitSetCondInstWithCastAndCast(SetCondInst &SCI);
+ Instruction *visitFCmpInst(FCmpInst &I);
+ Instruction *visitICmpInst(ICmpInst &I);
+ Instruction *visitICmpInstWithCastAndCast(ICmpInst &ICI);
- Instruction *FoldGEPSetCC(User *GEPLHS, Value *RHS,
- Instruction::BinaryOps Cond, Instruction &I);
+ Instruction *FoldGEPICmp(User *GEPLHS, Value *RHS,
+ ICmpInst::Predicate Cond, Instruction &I);
Instruction *visitShiftInst(ShiftInst &I);
Instruction *FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
ShiftInst &I);
@@ -274,10 +275,14 @@ namespace {
Value *V, const Type *DestTy,
Instruction *InsertBefore);
- // SimplifyCommutative - This performs a few simplifications for commutative
- // operators.
+ /// SimplifyCommutative - This performs a few simplifications for
+ /// commutative operators.
bool SimplifyCommutative(BinaryOperator &I);
+ /// SimplifyCompare - This reorders the operands of a CmpInst to get them in
+ /// most-complex to least-complex order.
+ bool SimplifyCompare(CmpInst &I);
+
bool SimplifyDemandedBits(Value *V, uint64_t Mask,
uint64_t &KnownZero, uint64_t &KnownOne,
unsigned Depth = 0);
@@ -303,7 +308,7 @@ namespace {
Value *FoldLogicalPlusAnd(Value *LHS, Value *RHS, ConstantIntegral *Mask,
bool isSub, Instruction &I);
Instruction *InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
- bool Inside, Instruction &IB);
+ bool isSigned, bool Inside, Instruction &IB);
Instruction *PromoteCastOfAllocation(CastInst &CI, AllocationInst &AI);
Instruction *MatchBSwap(BinaryOperator &I);
@@ -381,7 +386,8 @@ isEliminableCastPair(
/// ValueRequiresCast - Return true if the cast from "V to Ty" actually results
/// in any code being generated. It does not require codegen if V is simple
/// enough or if the cast can be folded into other casts.
-static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
+static bool ValueRequiresCast(Instruction::CastOps opcode, const Value *V,
+ const Type *Ty, TargetData *TD) {
if (V->getType() == Ty || isa<Constant>(V)) return false;
// If this is a noop cast, it isn't real codegen.
@@ -390,8 +396,7 @@ static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) {
// If this is another cast that can be eliminated, it isn't codegen either.
if (const CastInst *CI = dyn_cast<CastInst>(V))
- if (isEliminableCastPair(CI, CastInst::getCastOpcode(
- V, V->getType()->isSigned(), Ty, Ty->isSigned()), Ty, TD))
+ if (isEliminableCastPair(CI, opcode, Ty, TD))
return false;
return true;
}
@@ -456,6 +461,17 @@ bool InstCombiner::SimplifyCommutative(BinaryOperator &I) {
return Changed;
}
+/// SimplifyCompare - For a CmpInst this function just orders the operands
+/// so that theyare listed from right (least complex) to left (most complex).
+/// This puts constants before unary operators before binary operators.
+bool InstCombiner::SimplifyCompare(CmpInst &I) {
+ if (getComplexity(I.getOperand(0)) >= getComplexity(I.getOperand(1)))
+ return false;
+ I.swapOperands();
+ // Compare instructions are not associative so there's nothing else we can do.
+ return true;
+}
+
// dyn_castNegVal - Given a 'sub' instruction, return the RHS of the instruction
// if the LHS is a constant zero (which is the 'negate' form).
//
@@ -1451,13 +1467,24 @@ Value *InstCombiner::SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts,
return MadeChange ? I : 0;
}
-// isTrueWhenEqual - Return true if the specified setcondinst instruction is
-// true when both operands are equal...
-//
-static bool isTrueWhenEqual(Instruction &I) {
- return I.getOpcode() == Instruction::SetEQ ||
- I.getOpcode() == Instruction::SetGE ||
- I.getOpcode() == Instruction::SetLE;
+/// @returns true if the specified compare instruction is
+/// true when both operands are equal...
+/// @brief Determine if the ICmpInst returns true if both operands are equal
+static bool isTrueWhenEqual(ICmpInst &ICI) {
+ ICmpInst::Predicate pred = ICI.getPredicate();
+ return pred == ICmpInst::ICMP_EQ || pred == ICmpInst::ICMP_UGE ||
+ pred == ICmpInst::ICMP_SGE || pred == ICmpInst::ICMP_ULE ||
+ pred == ICmpInst::ICMP_SLE;
+}
+
+/// @returns true if the specified compare instruction is
+/// true when both operands are equal...
+/// @brief Determine if the FCmpInst returns true if both operands are equal
+static bool isTrueWhenEqual(FCmpInst &FCI) {
+ FCmpInst::Predicate pred = FCI.getPredicate();
+ return pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ ||
+ pred == FCmpInst::FCMP_OGE || pred == FCmpInst::FCMP_UGE ||
+ pred == FCmpInst::FCMP_OLE || pred == FCmpInst::FCMP_ULE;
}
/// AssociativeOpt - Perform an optimization on an associative operator. This
@@ -1593,6 +1620,9 @@ static Value *FoldOperationIntoSelectOperand(Instruction &I, Value *SO,
Instruction *New;
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&I))
New = BinaryOperator::create(BO->getOpcode(), Op0, Op1,SO->getName()+".op");
+ else if (CmpInst *CI = dyn_cast<CmpInst>(&I))
+ New = CmpInst::create(CI->getOpcode(), CI->getPredicate(), Op0, Op1,
+ SO->getName()+".cmp");
else if (ShiftInst *SI = dyn_cast<ShiftInst>(&I))
New = new ShiftInst(SI->getOpcode(), Op0, Op1, SO->getName()+".sh");
else {
@@ -1671,13 +1701,21 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
for (unsigned i = 0; i != NumPHIValues; ++i) {
Value *InV;
if (Constant *InC = dyn_cast<Constant>(PN->getIncomingValue(i))) {
- InV = ConstantExpr::get(I.getOpcode(), InC, C);
+ if (CmpInst *CI = dyn_cast<CmpInst>(&I))
+ InV = ConstantExpr::getCompare(CI->getPredicate(), InC, C);
+ else
+ InV = ConstantExpr::get(I.getOpcode(), InC, C);
} else {
assert(PN->getIncomingBlock(i) == NonConstBB);
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(&I))
InV = BinaryOperator::create(BO->getOpcode(),
PN->getIncomingValue(i), C, "phitmp",
NonConstBB->getTerminator());
+ else if (CmpInst *CI = dyn_cast<CmpInst>(&I))
+ InV = CmpInst::create(CI->getOpcode(),
+ CI->getPredicate(),
+ PN->getIncomingValue(i), C, "phitmp",
+ NonConstBB->getTerminator());
else if (ShiftInst *SI = dyn_cast<ShiftInst>(&I))
InV = new ShiftInst(SI->getOpcode(),
PN->getIncomingValue(i), C, "phitmp",
@@ -2077,25 +2115,27 @@ Instruction *InstCombiner::visitSub(BinaryOperator &I) {
return 0;
}
-/// isSignBitCheck - Given an exploded setcc instruction, return true if it is
+/// isSignBitCheck - Given an exploded icmp instruction, return true if it
/// really just returns true if the most significant (sign) bit is set.
-static bool isSignBitCheck(unsigned Opcode, Value *LHS, ConstantInt *RHS) {
- if (RHS->getType()->isSigned()) {
- // True if source is LHS < 0 or LHS <= -1
- return Opcode == Instruction::SetLT && RHS->isNullValue() ||
- Opcode == Instruction::SetLE && RHS->isAllOnesValue();
- } else {
- ConstantInt *RHSC = cast<ConstantInt>(RHS);
- // True if source is LHS > 127 or LHS >= 128, where the constants depend on
- // the size of the integer type.
- if (Opcode == Instruction::SetGE)
- return RHSC->getZExtValue() ==
- 1ULL << (RHS->getType()->getPrimitiveSizeInBits()-1);
- if (Opcode == Instruction::SetGT)
- return RHSC->getZExtValue() ==
+static bool isSignBitCheck(ICmpInst::Predicate pred, ConstantInt *RHS) {
+ switch (pred) {
+ case ICmpInst::ICMP_SLT:
+ // True if LHS s< RHS and RHS == 0
+ return RHS->isNullValue();
+ case ICmpInst::ICMP_SLE:
+ // True if LHS s<= RHS and RHS == -1
+ return RHS->isAllOnesValue();
+ case ICmpInst::ICMP_UGE:
+ // True if LHS u>= RHS and RHS == high-bit-mask (2^7, 2^15, 2^31, etc)
+ return RHS->getZExtValue() == (1ULL <<
+ (RHS->getType()->getPrimitiveSizeInBits()-1));
+ case ICmpInst::ICMP_UGT:
+ // True if LHS u> RHS and RHS == high-bit-mask - 1
+ return RHS->getZExtValue() ==
(1ULL << (RHS->getType()->getPrimitiveSizeInBits()-1))-1;
+ default:
+ return false;
}
- return false;
}
Instruction *InstCombiner::visitMul(BinaryOperator &I) {
@@ -2179,14 +2219,14 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) {
if (CI->getOperand(0)->getType() == Type::BoolTy)
BoolCast = CI;
if (BoolCast) {
- if (SetCondInst *SCI = dyn_cast<SetCondInst>(BoolCast->getOperand(0))) {
+ if (ICmpInst *SCI = dyn_cast<ICmpInst>(BoolCast->getOperand(0))) {
Value *SCIOp0 = SCI->getOperand(0), *SCIOp1 = SCI->getOperand(1);
const Type *SCOpTy = SCIOp0->getType();
- // If the setcc is true iff the sign bit of X is set, then convert this
+ // If the icmp is true iff the sign bit of X is set, then convert this
// multiply into a shift/and combination.
if (isa<ConstantInt>(SCIOp1) &&
- isSignBitCheck(SCI->getOpcode(), SCIOp0, cast<ConstantInt>(SCIOp1))) {
+ isSignBitCheck(SCI->getPredicate(), cast<ConstantInt>(SCIOp1))) {
// Shift the X value right to turn it into "all signbits".
Constant *Amt = ConstantInt::get(Type::UByteTy,
SCOpTy->getPrimitiveSizeInBits()-1);
@@ -2613,27 +2653,27 @@ Instruction *InstCombiner::visitFRem(BinaryOperator &I) {
}
// isMaxValueMinusOne - return true if this is Max-1
-static bool isMaxValueMinusOne(const ConstantInt *C) {
- if (C->getType()->isUnsigned())
- return C->getZExtValue() == C->getType()->getIntegralTypeMask()-1;
-
- // Calculate 0111111111..11111
- unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
- int64_t Val = INT64_MAX; // All ones
- Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
- return C->getSExtValue() == Val-1;
+static bool isMaxValueMinusOne(const ConstantInt *C, bool isSigned) {
+ if (isSigned) {
+ // Calculate 0111111111..11111
+ unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
+ int64_t Val = INT64_MAX; // All ones
+ Val >>= 64-TypeBits; // Shift out unwanted 1 bits...
+ return C->getSExtValue() == Val-1;
+ }
+ return C->getZExtValue() == C->getType()->getIntegralTypeMask()-1;
}
// isMinValuePlusOne - return true if this is Min+1
-static bool isMinValuePlusOne(const ConstantInt *C) {
- if (C->getType()->isUnsigned())
- return C->getZExtValue() == 1;
-
- // Calculate 1111111111000000000000
- unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
- int64_t Val = -1; // All ones
- Val <<= TypeBits-1; // Shift over to the right spot
- return C->getSExtValue() == Val+1;
+static bool isMinValuePlusOne(const ConstantInt *C, bool isSigned) {
+ if (isSigned) {
+ // Calculate 1111111111000000000000
+ unsigned TypeBits = C->getType()->getPrimitiveSizeInBits();
+ int64_t Val = -1; // All ones
+ Val <<= TypeBits-1; // Shift over to the right spot
+ return C->getSExtValue() == Val+1;
+ }
+ return C->getZExtValue() == 1; // unsigned
}
// isOneBitSet - Return true if there is exactly one bit set in the specified
@@ -2669,71 +2709,116 @@ static bool isHighOnes(const ConstantInt *CI) {
return U && V && (U & V) == 0;
}
-
-/// getSetCondCode - Encode a setcc opcode into a three bit mask. These bits
+/// getICmpCode - Encode a icmp predicate into a three bit mask. These bits
/// are carefully arranged to allow folding of expressions such as:
///
/// (A < B) | (A > B) --> (A != B)
///
-/// Bit value '4' represents that the comparison is true if A > B, bit value '2'
-/// represents that the comparison is true if A == B, and bit value '1' is true
-/// if A < B.
+/// Note that this is only valid if the first and second predicates have the
+/// same sign. Is illegal to do: (A u< B) | (A s> B)
+///
+/// Three bits are used to represent the condition, as follows:
+/// 0 A > B
+/// 1 A == B
+/// 2 A < B
///
-static unsigned getSetCondCode(const SetCondInst *SCI) {
- switch (SCI->getOpcode()) {
+/// <=> Value Definition
+/// 000 0 Always false
+/// 001 1 A > B
+/// 010 2 A == B
+/// 011 3 A >= B
+/// 100 4 A < B
+/// 101 5 A != B
+/// 110 6 A <= B
+/// 111 7 Always true
+///
+static unsigned getICmpCode(const ICmpInst *ICI) {
+ switch (ICI->getPredicate()) {
// False -> 0
- case Instruction::SetGT: return 1;
- case Instruction::SetEQ: return 2;
- case Instruction::SetGE: return 3;
- case Instruction::SetLT: return 4;
- case Instruction::SetNE: return 5;
- case Instruction::SetLE: return 6;
+ case ICmpInst::ICMP_UGT: return 1; // 001
+ case ICmpInst::ICMP_SGT: return 1; // 001
+ case ICmpInst::ICMP_EQ: return 2; // 010
+ case ICmpInst::ICMP_UGE: return 3; // 011
+ case ICmpInst::ICMP_SGE: return 3; // 011
+ case ICmpInst::ICMP_ULT: return 4; // 100
+ case ICmpInst::ICMP_SLT: return 4; // 100
+ case ICmpInst::ICMP_NE: return 5; // 101
+ case ICmpInst::ICMP_ULE: return 6; // 110
+ case ICmpInst::ICMP_SLE: return 6; // 110
// True -> 7
default:
- assert(0 && "Invalid SetCC opcode!");
+ assert(0 && "Invalid ICmp predicate!");
return 0;
}
}
-/// getSetCCValue - This is the complement of getSetCondCode, which turns an
-/// opcode and two operands into either a constant true or false, or a brand new
-/// SetCC instruction.
-static Value *getSetCCValue(unsigned Opcode, Value *LHS, Value *RHS) {
- switch (Opcode) {
- case 0: return ConstantBool::getFalse();
- case 1: return new SetCondInst(Instruction::SetGT, LHS, RHS);
- case 2: return new SetCondInst(Instruction::SetEQ, LHS, RHS);
- case 3: return new SetCondInst(Instruction::SetGE, LHS, RHS);
- case 4: return new SetCondInst(Instruction::SetLT, LHS, RHS);
- case 5: return new SetCondInst(Instruction::SetNE, LHS, RHS);
- case 6: return new SetCondInst(Instruction::SetLE, LHS, RHS);
- case 7: return ConstantBool::getTrue();
- default: assert(0 && "Illegal SetCCCode!"); return 0;
+/// getICmpValue - This is the complement of getICmpCode, which turns an
+/// opcode and two operands into either a constant true or false, or a brand
+/// new /// ICmp instruction. The sign is passed in to determine which kind
+/// of predicate to use in new icmp instructions.
+static Value *getICmpValue(bool sign, unsigned code, Value *LHS, Value *RHS) {
+ switch (code) {
+ default: assert(0 && "Illegal ICmp code!");
+ case 0: return ConstantBool::getFalse();
+ case 1:
+ if (sign)
+ return new ICmpInst(ICmpInst::ICMP_SGT, LHS, RHS);
+ else
+ return new ICmpInst(ICmpInst::ICMP_UGT, LHS, RHS);
+ case 2: return new ICmpInst(ICmpInst::ICMP_EQ, LHS, RHS);
+ case 3:
+ if (sign)
+ return new ICmpInst(ICmpInst::ICMP_SGE, LHS, RHS);
+ else
+ return new ICmpInst(ICmpInst::ICMP_UGE, LHS, RHS);
+ case 4:
+ if (sign)
+ return new ICmpInst(ICmpInst::ICMP_SLT, LHS, RHS);
+ else
+ return new ICmpInst(ICmpInst::ICMP_ULT, LHS, RHS);
+ case 5: return new ICmpInst(ICmpInst::ICMP_NE, LHS, RHS);
+ case 6:
+ if (sign)
+ return new ICmpInst(ICmpInst::ICMP_SLE, LHS, RHS);
+ else
+ return new ICmpInst(ICmpInst::ICMP_ULE, LHS, RHS);
+ case 7: return ConstantBool::getTrue();
}
}
-// FoldSetCCLogical - Implements (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
-namespace {
-struct FoldSetCCLogical {
+static bool PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
+ return (ICmpInst::isSignedPredicate(p1) == ICmpInst::isSignedPredicate(p2)) ||
+ (ICmpInst::isSignedPredicate(p1) &&
+ (p2 == ICmpInst::ICMP_EQ || p2 == ICmpInst::ICMP_NE)) ||
+ (ICmpInst::isSignedPredicate(p2) &&
+ (p1 == ICmpInst::ICMP_EQ || p1 == ICmpInst::ICMP_NE));
+}
+
+namespace {
+// FoldICmpLogical - Implements (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
+struct FoldICmpLogical {
InstCombiner &IC;
Value *LHS, *RHS;
- FoldSetCCLogical(InstCombiner &ic, SetCondInst *SCI)
- : IC(ic), LHS(SCI->getOperand(0)), RHS(SCI->getOperand(1)) {}
+ ICmpInst::Predicate pred;
+ FoldICmpLogical(InstCombiner &ic, ICmpInst *ICI)
+ : IC(ic), LHS(ICI->getOperand(0)), RHS(ICI->getOperand(1)),
+ pred(ICI->getPredicate()) {}
bool shouldApply(Value *V) const {
- if (SetCondInst *SCI = dyn_cast<SetCondInst>(V))
- return (SCI->getOperand(0) == LHS && SCI->getOperand(1) == RHS ||
- SCI->getOperand(0) == RHS && SCI->getOperand(1) == LHS);
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(V))
+ if (PredicatesFoldable(pred, ICI->getPredicate()))
+ return (ICI->getOperand(0) == LHS && ICI->getOperand(1) == RHS ||
+ ICI->getOperand(0) == RHS && ICI->getOperand(1) == LHS);
return false;
}
- Instruction *apply(BinaryOperator &Log) const {
- SetCondInst *SCI = cast<SetCondInst>(Log.getOperand(0));
- if (SCI->getOperand(0) != LHS) {
- assert(SCI->getOperand(1) == LHS);
- SCI->swapOperands(); // Swap the LHS and RHS of the SetCC
+ Instruction *apply(Instruction &Log) const {
+ ICmpInst *ICI = cast<ICmpInst>(Log.getOperand(0));
+ if (ICI->getOperand(0) != LHS) {
+ assert(ICI->getOperand(1) == LHS);
+ ICI->swapOperands(); // Swap the LHS and RHS of the ICmp
}
- unsigned LHSCode = getSetCondCode(SCI);
- unsigned RHSCode = getSetCondCode(cast<SetCondInst>(Log.getOperand(1)));
+ unsigned LHSCode = getICmpCode(ICI);
+ unsigned RHSCode = getICmpCode(cast<ICmpInst>(Log.getOperand(1)));
unsigned Code;
switch (Log.getOpcode()) {
case Instruction::And: Code = LHSCode & RHSCode; break;
@@ -2742,7 +2827,7 @@ struct FoldSetCCLogical {
default: assert(0 && "Illegal logical opcode!"); return 0;
}
- Value *RV = getSetCCValue(Code, LHS, RHS);
+ Value *RV = getICmpValue(ICmpInst::isSignedPredicate(pred), Code, LHS, RHS);
if (Instruction *I = dyn_cast<Instruction>(RV))
return I;
// Otherwise, it's a constant boolean value...
@@ -2882,48 +2967,52 @@ Instruction *InstCombiner::OptAndOp(Instruction *Op,
/// InsertRangeTest - Emit a computation of: (V >= Lo && V < Hi) if Inside is
/// true, otherwise (V < Lo || V >= Hi). In pratice, we emit the more efficient
-/// (V-Lo) <u Hi-Lo. This method expects that Lo <= Hi. IB is the location to
+/// (V-Lo) <u Hi-Lo. This method expects that Lo <= Hi. isSigned indicates
+/// whether to treat the V, Lo and HI as signed or not. IB is the location to
/// insert new instructions.
Instruction *InstCombiner::InsertRangeTest(Value *V, Constant *Lo, Constant *Hi,
- bool Inside, Instruction &IB) {
- assert(cast<ConstantBool>(ConstantExpr::getSetLE(Lo, Hi))->getValue() &&
+ bool isSigned, bool Inside,
+ Instruction &IB) {
+ assert(cast<ConstantBool>(ConstantExpr::getICmp((isSigned ?
+ ICmpInst::ICMP_SLE:ICmpInst::ICMP_ULE), Lo, Hi))->getValue() &&
"Lo is not <= Hi in range emission code!");
+
if (Inside) {
if (Lo == Hi) // Trivially false.
- return new SetCondInst(Instruction::SetNE, V, V);
- if (cast<ConstantIntegral>(Lo)->isMinValue(Lo->getType()->isSigned()))
- return new SetCondInst(Instruction::SetLT, V, Hi);
+ return new ICmpInst(ICmpInst::ICMP_NE, V, V);
- Constant *AddCST = ConstantExpr::getNeg(Lo);
- Instruction *Add = BinaryOperator::createAdd(V, AddCST,V->getName()+".off");
+ // V >= Min && V < Hi --> V < Hi
+ if (cast<ConstantIntegral>(Lo)->isMinValue(isSigned)) {
+ ICmpInst::Predicate pred = (isSigned ?
+ ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT);
+ return new ICmpInst(pred, V, Hi);
+ }
+
+ // Emit V-Lo <u Hi-Lo
+ Constant *NegLo = ConstantExpr::getNeg(Lo);
+ Instruction *Add = BinaryOperator::createAdd(V, NegLo, V->getName()+".off");
InsertNewInstBefore(Add, IB);
- // Convert to unsigned for the comparison.
- const Type *UnsType = Add->getType()->getUnsignedVersion();
- Value *OffsetVal = InsertCastBefore(Instruction::BitCast, Add, UnsType, IB);
- AddCST = ConstantExpr::getAdd(AddCST, Hi);
- AddCST = ConstantExpr::getBitCast(AddCST, UnsType);
- return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
+ Constant *UpperBound = ConstantExpr::getAdd(NegLo, Hi);
+ return new ICmpInst(ICmpInst::ICMP_ULT, Add, UpperBound);
}
if (Lo == Hi) // Trivially true.
- return new SetCondInst(Instruction::SetEQ, V, V);
+ return new ICmpInst(ICmpInst::ICMP_EQ, V, V);
+ // V < Min || V >= Hi ->'V > Hi-1'
Hi = SubOne(cast<ConstantInt>(Hi));
+ if (cast<ConstantIntegral>(Lo)->isMinValue(isSigned)) {
+ ICmpInst::Predicate pred = (isSigned ?
+ ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT);
+ return new ICmpInst(pred, V, Hi);
+ }
- // V < 0 || V >= Hi ->'V > Hi-1'
- if (cast<ConstantIntegral>(Lo)->isMinValue(Lo->getType()->isSigned()))
- return new SetCondInst(Instruction::SetGT, V, Hi);
-
- // Emit X-Lo > Hi-Lo-1
- Constant *AddCST = ConstantExpr::getNeg(Lo);
- Instruction *Add = BinaryOperator::createAdd(V, AddCST, V->getName()+".off");
+ // Emit V-Lo > Hi-1-Lo
+ Constant *NegLo = ConstantExpr::getNeg(Lo);
+ Instruction *Add = BinaryOperator::createAdd(V, NegLo, V->getName()+".off");
InsertNewInstBefore(Add, IB);
- // Convert to unsigned for the comparison.
- const Type *UnsType = Add->getType()->getUnsignedVersion();
- Value *OffsetVal = InsertCastBefore(Instruction::BitCast, Add, UnsType, IB);
- AddCST = ConstantExpr::getAdd(AddCST, Hi);
- AddCST = ConstantExpr::getBitCast(AddCST, UnsType);
- return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
+ Constant *LowerBound = ConstantExpr::getAdd(NegLo, Hi);
+ return new ICmpInst(ICmpInst::ICMP_UGT, Add, LowerBound);
}
// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with
@@ -3163,62 +3252,72 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
}
}
-
- if (SetCondInst *RHS = dyn_cast<SetCondInst>(Op1)) {
- // (setcc1 A, B) & (setcc2 A, B) --> (setcc3 A, B)
- if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(Op1)) {
+ // (icmp1 A, B) & (icmp2 A, B) --> (icmp3 A, B)
+ if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
return R;
Value *LHSVal, *RHSVal;
ConstantInt *LHSCst, *RHSCst;
- Instruction::BinaryOps LHSCC, RHSCC;
- if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
- if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
- if (LHSVal == RHSVal && // Found (X setcc C1) & (X setcc C2)
- // Set[GL]E X, CST is folded to Set[GL]T elsewhere.
- LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE &&
- RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
+ ICmpInst::Predicate LHSCC, RHSCC;
+ if (match(Op0, m_ICmp(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
+ if (match(RHS, m_ICmp(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
+ if (LHSVal == RHSVal && // Found (X icmp C1) & (X icmp C2)
+ // ICMP_[GL]E X, CST is folded to ICMP_[GL]T elsewhere.
+ LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
+ RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
+ LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
+ RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE) {
// Ensure that the larger constant is on the RHS.
- Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
- SetCondInst *LHS = cast<SetCondInst>(Op0);
+ ICmpInst::Predicate GT = ICmpInst::isSignedPredicate(LHSCC) ?
+ ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+ Constant *Cmp = ConstantExpr::getICmp(GT, LHSCst, RHSCst);
+ ICmpInst *LHS = cast<ICmpInst>(Op0);
if (cast<ConstantBool>(Cmp)->getValue()) {
std::swap(LHS, RHS);
std::swap(LHSCst, RHSCst);
std::swap(LHSCC, RHSCC);
}
- // At this point, we know we have have two setcc instructions
+ // At this point, we know we have have two icmp instructions
// comparing a value against two constants and and'ing the result
// together. Because of the above check, we know that we only have
- // SetEQ, SetNE, SetLT, and SetGT here. We also know (from the
- // FoldSetCCLogical check above), that the two constants are not
- // equal.
+ // icmp eq, icmp ne, icmp [su]lt, and icmp [SU]gt here. We also know
+ // (from the FoldICmpLogical check above), that the two constants
+ // are not equal and that the larger constant is on the RHS
assert(LHSCst != RHSCst && "Compares not folded above?");
switch (LHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ:
+ case ICmpInst::ICMP_EQ:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X == 13 & X == 15) -> false
- case Instruction::SetGT: // (X == 13 & X > 15) -> false
+ case ICmpInst::ICMP_EQ: // (X == 13 & X == 15) -> false
+ case ICmpInst::ICMP_UGT: // (X == 13 & X > 15) -> false
+ case ICmpInst::ICMP_SGT: // (X == 13 & X > 15) -> false
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- case Instruction::SetNE: // (X == 13 & X != 15) -> X == 13
- case Instruction::SetLT: // (X == 13 & X < 15) -> X == 13
+ case ICmpInst::ICMP_NE: // (X == 13 & X != 15) -> X == 13
+ case ICmpInst::ICMP_ULT: // (X == 13 & X < 15) -> X == 13
+ case ICmpInst::ICMP_SLT: // (X == 13 & X < 15) -> X == 13
return ReplaceInstUsesWith(I, LHS);
}
- case Instruction::SetNE:
+ case ICmpInst::ICMP_NE:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetLT:
- if (LHSCst == SubOne(RHSCst)) // (X != 13 & X < 14) -> X < 13
- return new SetCondInst(Instruction::SetLT, LHSVal, LHSCst);
- break; // (X != 13 & X < 15) -> no change
- case Instruction::SetEQ: // (X != 13 & X == 15) -> X == 15
- case Instruction::SetGT: // (X != 13 & X > 15) -> X > 15
+ case ICmpInst::ICMP_ULT:
+ if (LHSCst == SubOne(RHSCst)) // (X != 13 & X u< 14) -> X < 13
+ return new ICmpInst(ICmpInst::ICMP_ULT, LHSVal, LHSCst);
+ break; // (X != 13 & X u< 15) -> no change
+ case ICmpInst::ICMP_SLT:
+ if (LHSCst == SubOne(RHSCst)) // (X != 13 & X s< 14) -> X < 13
+ return new ICmpInst(ICmpInst::ICMP_SLT, LHSVal, LHSCst);
+ break; // (X != 13 & X s< 15) -> no change
+ case ICmpInst::ICMP_EQ: // (X != 13 & X == 15) -> X == 15
+ case ICmpInst::ICMP_UGT: // (X != 13 & X u> 15) -> X u> 15
+ case ICmpInst::ICMP_SGT: // (X != 13 & X s> 15) -> X s> 15
return ReplaceInstUsesWith(I, RHS);
- case Instruction::SetNE:
- if (LHSCst == SubOne(RHSCst)) {// (X != 13 & X != 14) -> X-13 >u 1
+ case ICmpInst::ICMP_NE:
+ if (LHSCst == SubOne(RHSCst)){// (X != 13 & X != 14) -> X-13 >u 1
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
LHSVal->getName()+".off");
@@ -3228,35 +3327,81 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
UnsType, I);
AddCST = ConstantExpr::getSub(RHSCst, LHSCst);
AddCST = ConstantExpr::getBitCast(AddCST, UnsType);
- return new SetCondInst(Instruction::SetGT, OffsetVal, AddCST);
+ return new ICmpInst(ICmpInst::ICMP_UGT, OffsetVal, AddCST);
}
break; // (X != 13 & X != 15) -> no change
}
break;
- case Instruction::SetLT:
+ case ICmpInst::ICMP_ULT:
+ switch (RHSCC) {
+ default: assert(0 && "Unknown integer condition code!");
+ case ICmpInst::ICMP_EQ: // (X u< 13 & X == 15) -> false
+ case ICmpInst::ICMP_UGT: // (X u< 13 & X u> 15) -> false
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ case ICmpInst::ICMP_SGT: // (X u< 13 & X s> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE: // (X u< 13 & X != 15) -> X u< 13
+ case ICmpInst::ICMP_ULT: // (X u< 13 & X u< 15) -> X u< 13
+ return ReplaceInstUsesWith(I, LHS);
+ case ICmpInst::ICMP_SLT: // (X u< 13 & X s< 15) -> no change
+ break;
+ }
+ break;
+ case ICmpInst::ICMP_SLT:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X < 13 & X == 15) -> false
- case Instruction::SetGT: // (X < 13 & X > 15) -> false
+ case ICmpInst::ICMP_EQ: // (X s< 13 & X == 15) -> false
+ case ICmpInst::ICMP_SGT: // (X s< 13 & X s> 15) -> false
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- case Instruction::SetNE: // (X < 13 & X != 15) -> X < 13
- case Instruction::SetLT: // (X < 13 & X < 15) -> X < 13
+ case ICmpInst::ICMP_UGT: // (X s< 13 & X u> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE: // (X s< 13 & X != 15) -> X < 13
+ case ICmpInst::ICMP_SLT: // (X s< 13 & X s< 15) -> X < 13
+ return ReplaceInstUsesWith(I, LHS);
+ case ICmpInst::ICMP_ULT: // (X s< 13 & X u< 15) -> no change
+ break;
+ }
+ break;
+ case ICmpInst::ICMP_UGT:
+ switch (RHSCC) {
+ default: assert(0 && "Unknown integer condition code!");
+ case ICmpInst::ICMP_EQ: // (X u> 13 & X == 15) -> X > 13
return ReplaceInstUsesWith(I, LHS);
+ case ICmpInst::ICMP_UGT: // (X u> 13 & X u> 15) -> X u> 15
+ return ReplaceInstUsesWith(I, RHS);
+ case ICmpInst::ICMP_SGT: // (X u> 13 & X s> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE:
+ if (RHSCst == AddOne(LHSCst)) // (X u> 13 & X != 14) -> X u> 14
+ return new ICmpInst(LHSCC, LHSVal, RHSCst);
+ break; // (X u> 13 & X != 15) -> no change
+ case ICmpInst::ICMP_ULT: // (X u> 13 & X u< 15) ->(X-14) <u 1
+ return InsertRangeTest(LHSVal, AddOne(LHSCst), RHSCst, false,
+ true, I);
+ case ICmpInst::ICMP_SLT: // (X u> 13 & X s< 15) -> no change
+ break;
}
- case Instruction::SetGT:
+ break;
+ case ICmpInst::ICMP_SGT:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X > 13 & X == 15) -> X > 13
+ case ICmpInst::ICMP_EQ: // (X s> 13 & X == 15) -> X s> 13
return ReplaceInstUsesWith(I, LHS);
- case Instruction::SetGT: // (X > 13 & X > 15) -> X > 15
+ case ICmpInst::ICMP_SGT: // (X s> 13 & X s> 15) -> X s> 15
return ReplaceInstUsesWith(I, RHS);
- case Instruction::SetNE:
- if (RHSCst == AddOne(LHSCst)) // (X > 13 & X != 14) -> X > 14
- return new SetCondInst(Instruction::SetGT, LHSVal, RHSCst);
- break; // (X > 13 & X != 15) -> no change
- case Instruction::SetLT: // (X > 13 & X < 15) -> (X-14) <u 1
- return InsertRangeTest(LHSVal, AddOne(LHSCst), RHSCst, true, I);
+ case ICmpInst::ICMP_UGT: // (X s> 13 & X u> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE:
+ if (RHSCst == AddOne(LHSCst)) // (X s> 13 & X != 14) -> X s> 14
+ return new ICmpInst(LHSCC, LHSVal, RHSCst);
+ break; // (X s> 13 & X != 15) -> no change
+ case ICmpInst::ICMP_SLT: // (X s> 13 & X s< 15) ->(X-14) s< 1
+ return InsertRangeTest(LHSVal, AddOne(LHSCst), RHSCst, true,
+ true, I);
+ case ICmpInst::ICMP_ULT: // (X s> 13 & X u< 15) -> no change
+ break;
}
+ break;
}
}
}
@@ -3268,8 +3413,10 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) {
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
// Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
- ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+ ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
+ I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
+ I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createAnd(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -3570,97 +3717,142 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
}
}
- // (setcc1 A, B) | (setcc2 A, B) --> (setcc3 A, B)
- if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1))) {
- if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+ // (icmp1 A, B) | (icmp2 A, B) --> (icmp3 A, B)
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1))) {
+ if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
return R;
Value *LHSVal, *RHSVal;
ConstantInt *LHSCst, *RHSCst;
- Instruction::BinaryOps LHSCC, RHSCC;
- if (match(Op0, m_SetCond(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
- if (match(RHS, m_SetCond(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
- if (LHSVal == RHSVal && // Found (X setcc C1) | (X setcc C2)
- // Set[GL]E X, CST is folded to Set[GL]T elsewhere.
- LHSCC != Instruction::SetGE && LHSCC != Instruction::SetLE &&
- RHSCC != Instruction::SetGE && RHSCC != Instruction::SetLE) {
+ ICmpInst::Predicate LHSCC, RHSCC;
+ if (match(Op0, m_ICmp(LHSCC, m_Value(LHSVal), m_ConstantInt(LHSCst))))
+ if (match(RHS, m_ICmp(RHSCC, m_Value(RHSVal), m_ConstantInt(RHSCst))))
+ if (LHSVal == RHSVal && // Found (X icmp C1) | (X icmp C2)
+ // icmp [us][gl]e x, cst is folded to icmp [us][gl]t elsewhere.
+ LHSCC != ICmpInst::ICMP_UGE && LHSCC != ICmpInst::ICMP_ULE &&
+ RHSCC != ICmpInst::ICMP_UGE && RHSCC != ICmpInst::ICMP_ULE &&
+ LHSCC != ICmpInst::ICMP_SGE && LHSCC != ICmpInst::ICMP_SLE &&
+ RHSCC != ICmpInst::ICMP_SGE && RHSCC != ICmpInst::ICMP_SLE) {
// Ensure that the larger constant is on the RHS.
- Constant *Cmp = ConstantExpr::getSetGT(LHSCst, RHSCst);
- SetCondInst *LHS = cast<SetCondInst>(Op0);
+ ICmpInst::Predicate GT = ICmpInst::isSignedPredicate(LHSCC) ?
+ ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT;
+ Constant *Cmp = ConstantExpr::getICmp(GT, LHSCst, RHSCst);
+ ICmpInst *LHS = cast<ICmpInst>(Op0);
if (cast<ConstantBool>(Cmp)->getValue()) {
std::swap(LHS, RHS);
std::swap(LHSCst, RHSCst);
std::swap(LHSCC, RHSCC);
}
- // At this point, we know we have have two setcc instructions
+ // At this point, we know we have have two icmp instructions
// comparing a value against two constants and or'ing the result
// together. Because of the above check, we know that we only have
- // SetEQ, SetNE, SetLT, and SetGT here. We also know (from the
- // FoldSetCCLogical check above), that the two constants are not
+ // ICMP_EQ, ICMP_NE, ICMP_LT, and ICMP_GT here. We also know (from the
+ // FoldICmpLogical check above), that the two constants are not
// equal.
assert(LHSCst != RHSCst && "Compares not folded above?");
switch (LHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ:
+ case ICmpInst::ICMP_EQ:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ:
+ case ICmpInst::ICMP_EQ:
if (LHSCst == SubOne(RHSCst)) {// (X == 13 | X == 14) -> X-13 <u 2
Constant *AddCST = ConstantExpr::getNeg(LHSCst);
Instruction *Add = BinaryOperator::createAdd(LHSVal, AddCST,
LHSVal->getName()+".off");
InsertNewInstBefore(Add, I);
- const Type *UnsType = Add->getType()->getUnsignedVersion();
- Value *OffsetVal = InsertCastBefore(Instruction::BitCast, Add,
- UnsType, I);
AddCST = ConstantExpr::getSub(AddOne(RHSCst), LHSCst);
- AddCST = ConstantExpr::getBitCast(AddCST, UnsType);
- return new SetCondInst(Instruction::SetLT, OffsetVal, AddCST);
+ return new ICmpInst(ICmpInst::ICMP_ULT, Add, AddCST);
}
- break; // (X == 13 | X == 15) -> no change
-
- case Instruction::SetGT: // (X == 13 | X > 14) -> no change
+ break; // (X == 13 | X == 15) -> no change
+ case ICmpInst::ICMP_UGT: // (X == 13 | X u> 14) -> no change
+ case ICmpInst::ICMP_SGT: // (X == 13 | X s> 14) -> no change
break;
- case Instruction::SetNE: // (X == 13 | X != 15) -> X != 15
- case Instruction::SetLT: // (X == 13 | X < 15) -> X < 15
+ case ICmpInst::ICMP_NE: // (X == 13 | X != 15) -> X != 15
+ case ICmpInst::ICMP_ULT: // (X == 13 | X u< 15) -> X u< 15
+ case ICmpInst::ICMP_SLT: // (X == 13 | X s< 15) -> X s< 15
return ReplaceInstUsesWith(I, RHS);
}
break;
- case Instruction::SetNE:
+ case ICmpInst::ICMP_NE:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X != 13 | X == 15) -> X != 13
- case Instruction::SetGT: // (X != 13 | X > 15) -> X != 13
+ case ICmpInst::ICMP_EQ: // (X != 13 | X == 15) -> X != 13
+ case ICmpInst::ICMP_UGT: // (X != 13 | X u> 15) -> X != 13
+ case ICmpInst::ICMP_SGT: // (X != 13 | X s> 15) -> X != 13
return ReplaceInstUsesWith(I, LHS);
- case Instruction::SetNE: // (X != 13 | X != 15) -> true
- case Instruction::SetLT: // (X != 13 | X < 15) -> true
+ case ICmpInst::ICMP_NE: // (X != 13 | X != 15) -> true
+ case ICmpInst::ICMP_ULT: // (X != 13 | X u< 15) -> true
+ case ICmpInst::ICMP_SLT: // (X != 13 | X s< 15) -> true
return ReplaceInstUsesWith(I, ConstantBool::getTrue());
}
break;
- case Instruction::SetLT:
+ case ICmpInst::ICMP_ULT:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X < 13 | X == 14) -> no change
+ case ICmpInst::ICMP_EQ: // (X u< 13 | X == 14) -> no change
+ break;
+ case ICmpInst::ICMP_UGT: // (X u< 13 | X u> 15) ->(X-13) u> 2
+ return InsertRangeTest(LHSVal, LHSCst, AddOne(RHSCst), false,
+ false, I);
+ case ICmpInst::ICMP_SGT: // (X u< 13 | X s> 15) -> no change
break;
- case Instruction::SetGT: // (X < 13 | X > 15) -> (X-13) > 2
- return InsertRangeTest(LHSVal, LHSCst, AddOne(RHSCst), false, I);
- case Instruction::SetNE: // (X < 13 | X != 15) -> X != 15
- case Instruction::SetLT: // (X < 13 | X < 15) -> X < 15
+ case ICmpInst::ICMP_NE: // (X u< 13 | X != 15) -> X != 15
+ case ICmpInst::ICMP_ULT: // (X u< 13 | X u< 15) -> X u< 15
return ReplaceInstUsesWith(I, RHS);
+ case ICmpInst::ICMP_SLT: // (X u< 13 | X s< 15) -> no change
+ break;
}
break;
- case Instruction::SetGT:
+ case ICmpInst::ICMP_SLT:
switch (RHSCC) {
default: assert(0 && "Unknown integer condition code!");
- case Instruction::SetEQ: // (X > 13 | X == 15) -> X > 13
- case Instruction::SetGT: // (X > 13 | X > 15) -> X > 13
+ case ICmpInst::ICMP_EQ: // (X s< 13 | X == 14) -> no change
+ break;
+ case ICmpInst::ICMP_SGT: // (X s< 13 | X s> 15) ->(X-13) s> 2
+ return InsertRangeTest(LHSVal, LHSCst, AddOne(RHSCst), true,
+ false, I);
+ case ICmpInst::ICMP_UGT: // (X s< 13 | X u> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE: // (X s< 13 | X != 15) -> X != 15
+ case ICmpInst::ICMP_SLT: // (X s< 13 | X s< 15) -> X s< 15
+ return ReplaceInstUsesWith(I, RHS);
+ case ICmpInst::ICMP_ULT: // (X s< 13 | X u< 15) -> no change
+ break;
+ }
+ break;
+ case ICmpInst::ICMP_UGT:
+ switch (RHSCC) {
+ default: assert(0 && "Unknown integer condition code!");
+ case ICmpInst::ICMP_EQ: // (X u> 13 | X == 15) -> X u> 13
+ case ICmpInst::ICMP_UGT: // (X u> 13 | X u> 15) -> X u> 13
+ return ReplaceInstUsesWith(I, LHS);
+ case ICmpInst::ICMP_SGT: // (X u> 13 | X s> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE: // (X u> 13 | X != 15) -> true
+ case ICmpInst::ICMP_ULT: // (X u> 13 | X u< 15) -> true
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ case ICmpInst::ICMP_SLT: // (X u> 13 | X s< 15) -> no change
+ break;
+ }
+ break;
+ case ICmpInst::ICMP_SGT:
+ switch (RHSCC) {
+ default: assert(0 && "Unknown integer condition code!");
+ case ICmpInst::ICMP_EQ: // (X s> 13 | X == 15) -> X > 13
+ case ICmpInst::ICMP_SGT: // (X s> 13 | X s> 15) -> X > 13
return ReplaceInstUsesWith(I, LHS);
- case Instruction::SetNE: // (X > 13 | X != 15) -> true
- case Instruction::SetLT: // (X > 13 | X < 15) -> true
+ case ICmpInst::ICMP_UGT: // (X s> 13 | X u> 15) -> no change
+ break;
+ case ICmpInst::ICMP_NE: // (X s> 13 | X != 15) -> true
+ case ICmpInst::ICMP_SLT: // (X s> 13 | X s< 15) -> true
return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ case ICmpInst::ICMP_ULT: // (X s> 13 | X u< 15) -> no change
+ break;
}
+ break;
}
}
}
@@ -3672,8 +3864,10 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) {
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
// Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
- ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+ ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
+ I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
+ I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createOr(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -3719,13 +3913,13 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
return &I;
if (ConstantIntegral *RHS = dyn_cast<ConstantIntegral>(Op1)) {
- if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
- // xor (setcc A, B), true = not (setcc A, B) = setncc A, B
- if (SetCondInst *SCI = dyn_cast<SetCondInst>(Op0I))
- if (RHS == ConstantBool::getTrue() && SCI->hasOneUse())
- return new SetCondInst(SCI->getInverseCondition(),
- SCI->getOperand(0), SCI->getOperand(1));
+ // xor (icmp A, B), true = not (icmp A, B) = !icmp A, B
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(Op0))
+ if (RHS == ConstantBool::getTrue() && ICI->hasOneUse())
+ return new ICmpInst(ICI->getInversePredicate(),
+ ICI->getOperand(0), ICI->getOperand(1));
+ if (BinaryOperator *Op0I = dyn_cast<BinaryOperator>(Op0)) {
// ~(c-X) == X-c-1 == X+(-c-1)
if (Op0I->getOpcode() == Instruction::Sub && RHS->isAllOnesValue())
if (Constant *Op0I0C = dyn_cast<Constant>(Op0I->getOperand(0))) {
@@ -3842,9 +4036,9 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
}
}
- // (setcc1 A, B) ^ (setcc2 A, B) --> (setcc3 A, B)
- if (SetCondInst *RHS = dyn_cast<SetCondInst>(I.getOperand(1)))
- if (Instruction *R = AssociativeOpt(I, FoldSetCCLogical(*this, RHS)))
+ // (icmp1 A, B) ^ (icmp2 A, B) --> (icmp3 A, B)
+ if (ICmpInst *RHS = dyn_cast<ICmpInst>(I.getOperand(1)))
+ if (Instruction *R = AssociativeOpt(I, FoldICmpLogical(*this, RHS)))
return R;
// fold (xor (cast A), (cast B)) -> (cast (xor A, B))
@@ -3854,8 +4048,10 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) {
const Type *SrcTy = Op0C->getOperand(0)->getType();
if (SrcTy == Op1C->getOperand(0)->getType() && SrcTy->isIntegral() &&
// Only do this if the casts both really cause code to be generated.
- ValueRequiresCast(Op0C->getOperand(0), I.getType(), TD) &&
- ValueRequiresCast(Op1C->getOperand(0), I.getType(), TD)) {
+ ValueRequiresCast(Op0C->getOpcode(), Op0C->getOperand(0),
+ I.getType(), TD) &&
+ ValueRequiresCast(Op1C->getOpcode(), Op1C->getOperand(0),
+ I.getType(), TD)) {
Instruction *NewOp = BinaryOperator::createXor(Op0C->getOperand(0),
Op1C->getOperand(0),
I.getName());
@@ -3909,9 +4105,8 @@ static bool AddWithOverflow(ConstantInt *&Result, ConstantInt *In1,
static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) {
TargetData &TD = IC.getTargetData();
gep_type_iterator GTI = gep_type_begin(GEP);
- const Type *UIntPtrTy = TD.getIntPtrType();
- const Type *SIntPtrTy = UIntPtrTy->getSignedVersion();
- Value *Result = Constant::getNullValue(SIntPtrTy);
+ const Type *IntPtrTy = TD.getIntPtrType();
+ Value *Result = Constant::getNullValue(IntPtrTy);
// Build a mask for high order bits.
uint64_t PtrSizeMask = ~0ULL >> (64-TD.getPointerSize()*8);
@@ -3919,10 +4114,10 @@ static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) {
for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i, ++GTI) {
Value *Op = GEP->getOperand(i);
uint64_t Size = TD.getTypeSize(GTI.getIndexedType()) & PtrSizeMask;
- Constant *Scale = ConstantInt::get(SIntPtrTy, Size);
+ Constant *Scale = ConstantInt::get(IntPtrTy, Size);
if (Constant *OpC = dyn_cast<Constant>(Op)) {
if (!OpC->isNullValue()) {
- OpC = ConstantExpr::getIntegerCast(OpC, SIntPtrTy, true /*SExt*/);
+ OpC = ConstantExpr::getIntegerCast(OpC, IntPtrTy, true /*SExt*/);
Scale = ConstantExpr::getMul(OpC, Scale);
if (Constant *RC = dyn_cast<Constant>(Result))
Result = ConstantExpr::getAdd(RC, Scale);
@@ -3935,7 +4130,7 @@ static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) {
}
} else {
// Convert to correct type.
- Op = IC.InsertNewInstBefore(CastInst::createSExtOrBitCast(Op, SIntPtrTy,
+ Op = IC.InsertNewInstBefore(CastInst::createSExtOrBitCast(Op, IntPtrTy,
Op->getName()+".c"), I);
if (Size != 1)
// We'll let instcombine(mul) convert this to a shl if possible.
@@ -3950,11 +4145,11 @@ static Value *EmitGEPOffset(User *GEP, Instruction &I, InstCombiner &IC) {
return Result;
}
-/// FoldGEPSetCC - Fold comparisons between a GEP instruction and something
+/// FoldGEPICmp - Fold comparisons between a GEP instruction and something
/// else. At this point we know that the GEP is on the LHS of the comparison.
-Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
- Instruction::BinaryOps Cond,
- Instruction &I) {
+Instruction *InstCombiner::FoldGEPICmp(User *GEPLHS, Value *RHS,
+ ICmpInst::Predicate Cond,
+ Instruction &I) {
assert(dyn_castGetElementPtr(GEPLHS) && "LHS is not a getelementptr!");
if (CastInst *CI = dyn_cast<CastInst>(RHS))
@@ -3964,9 +4159,9 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
Value *PtrBase = GEPLHS->getOperand(0);
if (PtrBase == RHS) {
// As an optimization, we don't actually have to compute the actual value of
- // OFFSET if this is a seteq or setne comparison, just return whether each
- // index is zero or not.
- if (Cond == Instruction::SetEQ || Cond == Instruction::SetNE) {
+ // OFFSET if this is a icmp_eq or icmp_ne comparison, just return whether
+ // each index is zero or not.
+ if (Cond == ICmpInst::ICMP_EQ || Cond == ICmpInst::ICMP_NE) {
Instruction *InVal = 0;
gep_type_iterator GTI = gep_type_begin(GEPLHS);
for (unsigned i = 1, e = GEPLHS->getNumOperands(); i != e; ++i, ++GTI) {
@@ -3980,19 +4175,19 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
EmitIt = false; // This is indexing into a zero sized array?
} else if (isa<ConstantInt>(C))
return ReplaceInstUsesWith(I, // No comparison is needed here.
- ConstantBool::get(Cond == Instruction::SetNE));
+ ConstantBool::get(Cond == ICmpInst::ICMP_NE));
}
if (EmitIt) {
Instruction *Comp =
- new SetCondInst(Cond, GEPLHS->getOperand(i),
+ new ICmpInst(Cond, GEPLHS->getOperand(i),
Constant::getNullValue(GEPLHS->getOperand(i)->getType()));
if (InVal == 0)
InVal = Comp;
else {
InVal = InsertNewInstBefore(InVal, I);
InsertNewInstBefore(Comp, I);
- if (Cond == Instruction::SetNE) // True if any are unequal
+ if (Cond == ICmpInst::ICMP_NE) // True if any are unequal
InVal = BinaryOperator::createOr(InVal, Comp);
else // True if all are equal
InVal = BinaryOperator::createAnd(InVal, Comp);
@@ -4003,17 +4198,17 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
if (InVal)
return InVal;
else
- ReplaceInstUsesWith(I, // No comparison is needed here, all indexes = 0
- ConstantBool::get(Cond == Instruction::SetEQ));
+ // No comparison is needed here, all indexes = 0
+ ReplaceInstUsesWith(I, ConstantBool::get(Cond == ICmpInst::ICMP_EQ));
}
- // Only lower this if the setcc is the only user of the GEP or if we expect
+ // Only lower this if the icmp is the only user of the GEP or if we expect
// the result to fold to a constant!
if (isa<ConstantExpr>(GEPLHS) || GEPLHS->hasOneUse()) {
// ((gep Ptr, OFFSET) cmp Ptr) ---> (OFFSET cmp 0).
Value *Offset = EmitGEPOffset(GEPLHS, I, *this);
- return new SetCondInst(Cond, Offset,
- Constant::getNullValue(Offset->getType()));
+ return new ICmpInst(ICmpInst::getSignedPredicate(Cond), Offset,
+ Constant::getNullValue(Offset->getType()));
}
} else if (User *GEPRHS = dyn_castGetElementPtr(RHS)) {
// If the base pointers are different, but the indices are the same, just
@@ -4031,8 +4226,8 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
// If all indices are the same, just compare the base pointers.
if (IndicesTheSame)
- return new SetCondInst(Cond, GEPLHS->getOperand(0),
- GEPRHS->getOperand(0));
+ return new ICmpInst(ICmpInst::getSignedPredicate(Cond),
+ GEPLHS->getOperand(0), GEPRHS->getOperand(0));
// Otherwise, the base pointers are different and the indices are
// different, bail out.
@@ -4048,8 +4243,8 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
break;
}
if (AllZeros)
- return FoldGEPSetCC(GEPRHS, GEPLHS->getOperand(0),
- SetCondInst::getSwappedCondition(Cond), I);
+ return FoldGEPICmp(GEPRHS, GEPLHS->getOperand(0),
+ ICmpInst::getSwappedPredicate(Cond), I);
// If the other GEP has all zero indices, recurse.
AllZeros = true;
@@ -4060,7 +4255,7 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
break;
}
if (AllZeros)
- return FoldGEPSetCC(GEPLHS, GEPRHS->getOperand(0), Cond, I);
+ return FoldGEPICmp(GEPLHS, GEPRHS->getOperand(0), Cond, I);
if (GEPLHS->getNumOperands() == GEPRHS->getNumOperands()) {
// If the GEPs only differ by one index, compare it.
@@ -4081,49 +4276,103 @@ Instruction *InstCombiner::FoldGEPSetCC(User *GEPLHS, Value *RHS,
if (NumDifferences == 0) // SAME GEP?
return ReplaceInstUsesWith(I, // No comparison is needed here.
- ConstantBool::get(Cond == Instruction::SetEQ));
+ ConstantBool::get(Cond == ICmpInst::ICMP_EQ));
else if (NumDifferences == 1) {
Value *LHSV = GEPLHS->getOperand(DiffOperand);
Value *RHSV = GEPRHS->getOperand(DiffOperand);
-
- // Convert the operands to signed values to make sure to perform a
- // signed comparison.
- const Type *NewTy = LHSV->getType()->getSignedVersion();
- if (LHSV->getType() != NewTy)
- LHSV = InsertCastBefore(Instruction::BitCast, LHSV, NewTy, I);
- if (RHSV->getType() != NewTy)
- RHSV = InsertCastBefore(Instruction::BitCast, RHSV, NewTy, I);
- return new SetCondInst(Cond, LHSV, RHSV);
+ if (LHSV->getType() != RHSV->getType())
+ // Doesn't matter which one we bitconvert here.
+ LHSV = InsertCastBefore(Instruction::BitCast, LHSV, RHSV->getType(),
+ I);
+ // Make sure we do a signed comparison here.
+ return new ICmpInst(ICmpInst::getSignedPredicate(Cond), LHSV, RHSV);
}
}
- // Only lower this if the setcc is the only user of the GEP or if we expect
+ // Only lower this if the icmp is the only user of the GEP or if we expect
// the result to fold to a constant!
if ((isa<ConstantExpr>(GEPLHS) || GEPLHS->hasOneUse()) &&
(isa<ConstantExpr>(GEPRHS) || GEPRHS->hasOneUse())) {
// ((gep Ptr, OFFSET1) cmp (gep Ptr, OFFSET2) ---> (OFFSET1 cmp OFFSET2)
Value *L = EmitGEPOffset(GEPLHS, I, *this);
Value *R = EmitGEPOffset(GEPRHS, I, *this);
- return new SetCondInst(Cond, L, R);
+ return new ICmpInst(ICmpInst::getSignedPredicate(Cond), L, R);
}
}
return 0;
}
+Instruction *InstCombiner::visitFCmpInst(FCmpInst &I) {
+ bool Changed = SimplifyCompare(I);
+ Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
-Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
- bool Changed = SimplifyCommutative(I);
+ // fcmp pred X, X
+ if (Op0 == Op1)
+ return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
+
+ if (isa<UndefValue>(Op1)) // fcmp pred X, undef -> undef
+ return ReplaceInstUsesWith(I, UndefValue::get(Type::BoolTy));
+
+ // Handle fcmp with constant RHS
+ if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
+ if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
+ switch (LHSI->getOpcode()) {
+ case Instruction::PHI:
+ if (Instruction *NV = FoldOpIntoPhi(I))
+ return NV;
+ break;
+ case Instruction::Select:
+ // If either operand of the select is a constant, we can fold the
+ // comparison into the select arms, which will cause one to be
+ // constant folded and the select turned into a bitwise or.
+ Value *Op1 = 0, *Op2 = 0;
+ if (LHSI->hasOneUse()) {
+ if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1))) {
+ // Fold the known value into the constant operand.
+ Op1 = ConstantExpr::getCompare(I.getPredicate(), C, RHSC);
+ // Insert a new FCmp of the other select operand.
+ Op2 = InsertNewInstBefore(new FCmpInst(I.getPredicate(),
+ LHSI->getOperand(2), RHSC,
+ I.getName()), I);
+ } else if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2))) {
+ // Fold the known value into the constant operand.
+ Op2 = ConstantExpr::getCompare(I.getPredicate(), C, RHSC);
+ // Insert a new FCmp of the other select operand.
+ Op1 = InsertNewInstBefore(new FCmpInst(I.getPredicate(),
+ LHSI->getOperand(1), RHSC,
+ I.getName()), I);
+ }
+ }
+
+ if (Op1)
+ return new SelectInst(LHSI->getOperand(0), Op1, Op2);
+ break;
+ }
+ }
+
+ return Changed ? &I : 0;
+}
+
+Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
+ bool Changed = SimplifyCompare(I);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
const Type *Ty = Op0->getType();
- // setcc X, X
+ // icmp X, X
if (Op0 == Op1)
return ReplaceInstUsesWith(I, ConstantBool::get(isTrueWhenEqual(I)));
- if (isa<UndefValue>(Op1)) // X setcc undef -> undef
+ if (isa<UndefValue>(Op1)) // X icmp undef -> undef
return ReplaceInstUsesWith(I, UndefValue::get(Type::BoolTy));
- // setcc <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
+ // icmp of GlobalValues can never equal each other as long as they aren't
+ // external weak linkage type.
+ if (GlobalValue *GV0 = dyn_cast<GlobalValue>(Op0))
+ if (GlobalValue *GV1 = dyn_cast<GlobalValue>(Op1))
+ if (!GV0->hasExternalWeakLinkage() || !GV1->hasExternalWeakLinkage())
+ return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
+
+ // icmp <global/alloca*/null>, <global/alloca*/null> - Global/Stack value
// addresses never equal each other! We already know that Op0 != Op1.
if ((isa<GlobalValue>(Op0) || isa<AllocaInst>(Op0) ||
isa<ConstantPointerNull>(Op0)) &&
@@ -4131,30 +4380,34 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
isa<ConstantPointerNull>(Op1)))
return ReplaceInstUsesWith(I, ConstantBool::get(!isTrueWhenEqual(I)));
- // setcc's with boolean values can always be turned into bitwise operations
+ // icmp's with boolean values can always be turned into bitwise operations
if (Ty == Type::BoolTy) {
- switch (I.getOpcode()) {
- default: assert(0 && "Invalid setcc instruction!");
- case Instruction::SetEQ: { // seteq bool %A, %B -> ~(A^B)
+ switch (I.getPredicate()) {
+ default: assert(0 && "Invalid icmp instruction!");
+ case ICmpInst::ICMP_EQ: { // icmp eq bool %A, %B -> ~(A^B)
Instruction *Xor = BinaryOperator::createXor(Op0, Op1, I.getName()+"tmp");
InsertNewInstBefore(Xor, I);
return BinaryOperator::createNot(Xor);
}
- case Instruction::SetNE:
+ case ICmpInst::ICMP_NE: // icmp eq bool %A, %B -> A^B
return BinaryOperator::createXor(Op0, Op1);
- case Instruction::SetGT:
- std::swap(Op0, Op1); // Change setgt -> setlt
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ std::swap(Op0, Op1); // Change icmp gt -> icmp lt
// FALL THROUGH
- case Instruction::SetLT: { // setlt bool A, B -> ~X & Y
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT: { // icmp lt bool A, B -> ~X & Y
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::createAnd(Not, Op1);
}
- case Instruction::SetGE:
- std::swap(Op0, Op1); // Change setge -> setle
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ std::swap(Op0, Op1); // Change icmp ge -> icmp le
// FALL THROUGH
- case Instruction::SetLE: { // setle bool %A, %B -> ~A | B
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE: { // icmp le bool %A, %B -> ~A | B
Instruction *Not = BinaryOperator::createNot(Op0, I.getName()+"tmp");
InsertNewInstBefore(Not, I);
return BinaryOperator::createOr(Not, Op1);
@@ -4165,50 +4418,93 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// See if we are doing a comparison between a constant and an instruction that
// can be folded into the comparison.
if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
- // Check to see if we are comparing against the minimum or maximum value...
- if (CI->isMinValue(CI->getType()->isSigned())) {
- if (I.getOpcode() == Instruction::SetLT) // A < MIN -> FALSE
+ switch (I.getPredicate()) {
+ default: break;
+ case ICmpInst::ICMP_ULT: // A <u MIN -> FALSE
+ if (CI->isMinValue(false))
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- if (I.getOpcode() == Instruction::SetGE) // A >= MIN -> TRUE
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (I.getOpcode() == Instruction::SetLE) // A <= MIN -> A == MIN
- return BinaryOperator::createSetEQ(Op0, Op1);
- if (I.getOpcode() == Instruction::SetGT) // A > MIN -> A != MIN
- return BinaryOperator::createSetNE(Op0, Op1);
+ if (CI->isMaxValue(false)) // A <u MAX -> A != MAX
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0,Op1);
+ if (isMinValuePlusOne(CI,false)) // A <u MIN+1 -> A == MIN
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
+ break;
- } else if (CI->isMaxValue(CI->getType()->isSigned())) {
- if (I.getOpcode() == Instruction::SetGT) // A > MAX -> FALSE
+ case ICmpInst::ICMP_SLT:
+ if (CI->isMinValue(true)) // A <s MIN -> FALSE
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- if (I.getOpcode() == Instruction::SetLE) // A <= MAX -> TRUE
+ if (CI->isMaxValue(true)) // A <s MAX -> A != MAX
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+ if (isMinValuePlusOne(CI,true)) // A <s MIN+1 -> A == MIN
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, SubOne(CI));
+ break;
+
+ case ICmpInst::ICMP_UGT:
+ if (CI->isMaxValue(false)) // A >u MAX -> FALSE
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ if (CI->isMinValue(false)) // A >u MIN -> A != MIN
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+ if (isMaxValueMinusOne(CI, false)) // A >u MAX-1 -> A == MAX
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
+ break;
+
+ case ICmpInst::ICMP_SGT:
+ if (CI->isMaxValue(true)) // A >s MAX -> FALSE
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ if (CI->isMinValue(true)) // A >s MIN -> A != MIN
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, Op1);
+ if (isMaxValueMinusOne(CI, true)) // A >s MAX-1 -> A == MAX
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, AddOne(CI));
+ break;
+
+ case ICmpInst::ICMP_ULE:
+ if (CI->isMaxValue(false)) // A <=u MAX -> TRUE
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (CI->isMinValue(false)) // A <=u MIN -> A == MIN
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
+ if (isMaxValueMinusOne(CI,false)) // A <=u MAX-1 -> A != MAX
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, AddOne(CI));
+ break;
+
+ case ICmpInst::ICMP_SLE:
+ if (CI->isMaxValue(true)) // A <=s MAX -> TRUE
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (CI->isMinValue(true)) // A <=s MIN -> A == MIN
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
+ if (isMaxValueMinusOne(CI,true)) // A <=s MAX-1 -> A != MAX
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, AddOne(CI));
+ break;
+
+ case ICmpInst::ICMP_UGE:
+ if (CI->isMinValue(false)) // A >=u MIN -> TRUE
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (CI->isMaxValue(false)) // A >=u MAX -> A == MAX
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
+ if (isMinValuePlusOne(CI,false)) // A >=u MIN-1 -> A != MIN
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, SubOne(CI));
+ break;
+
+ case ICmpInst::ICMP_SGE:
+ if (CI->isMinValue(true)) // A >=s MIN -> TRUE
return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (I.getOpcode() == Instruction::SetGE) // A >= MAX -> A == MAX
- return BinaryOperator::createSetEQ(Op0, Op1);
- if (I.getOpcode() == Instruction::SetLT) // A < MAX -> A != MAX
- return BinaryOperator::createSetNE(Op0, Op1);
-
- // Comparing against a value really close to min or max?
- } else if (isMinValuePlusOne(CI)) {
- if (I.getOpcode() == Instruction::SetLT) // A < MIN+1 -> A == MIN
- return BinaryOperator::createSetEQ(Op0, SubOne(CI));
- if (I.getOpcode() == Instruction::SetGE) // A >= MIN-1 -> A != MIN
- return BinaryOperator::createSetNE(Op0, SubOne(CI));
-
- } else if (isMaxValueMinusOne(CI)) {
- if (I.getOpcode() == Instruction::SetGT) // A > MAX-1 -> A == MAX
- return BinaryOperator::createSetEQ(Op0, AddOne(CI));
- if (I.getOpcode() == Instruction::SetLE) // A <= MAX-1 -> A != MAX
- return BinaryOperator::createSetNE(Op0, AddOne(CI));
- }
-
- // If we still have a setle or setge instruction, turn it into the
- // appropriate setlt or setgt instruction. Since the border cases have
+ if (CI->isMaxValue(true)) // A >=s MAX -> A == MAX
+ return new ICmpInst(ICmpInst::ICMP_EQ, Op0, Op1);
+ if (isMinValuePlusOne(CI,true)) // A >=s MIN-1 -> A != MIN
+ return new ICmpInst(ICmpInst::ICMP_NE, Op0, SubOne(CI));
+ break;
+ }
+
+ // If we still have a icmp le or icmp ge instruction, turn it into the
+ // appropriate icmp lt or icmp gt instruction. Since the border cases have
// already been handled above, this requires little checking.
//
- if (I.getOpcode() == Instruction::SetLE)
- return BinaryOperator::createSetLT(Op0, AddOne(CI));
- if (I.getOpcode() == Instruction::SetGE)
- return BinaryOperator::createSetGT(Op0, SubOne(CI));
-
+ if (I.getPredicate() == ICmpInst::ICMP_ULE)
+ return new ICmpInst(ICmpInst::ICMP_ULT, Op0, AddOne(CI));
+ if (I.getPredicate() == ICmpInst::ICMP_SLE)
+ return new ICmpInst(ICmpInst::ICMP_SLT, Op0, AddOne(CI));
+ if (I.getPredicate() == ICmpInst::ICMP_UGE)
+ return new ICmpInst( ICmpInst::ICMP_UGT, Op0, SubOne(CI));
+ if (I.getPredicate() == ICmpInst::ICMP_SGE)
+ return new ICmpInst(ICmpInst::ICMP_SGT, Op0, SubOne(CI));
// See if we can fold the comparison based on bits known to be zero or one
// in the input.
@@ -4220,68 +4516,59 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// Given the known and unknown bits, compute a range that the LHS could be
// in.
if (KnownOne | KnownZero) {
- if (Ty->isUnsigned()) { // Unsigned comparison.
- uint64_t Min, Max;
- uint64_t RHSVal = CI->getZExtValue();
- ComputeUnsignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne,
- Min, Max);
- switch (I.getOpcode()) { // LE/GE have been folded already.
- default: assert(0 && "Unknown setcc opcode!");
- case Instruction::SetEQ:
- if (Max < RHSVal || Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- case Instruction::SetNE:
- if (Max < RHSVal || Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- break;
- case Instruction::SetLT:
- if (Max < RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- case Instruction::SetGT:
- if (Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (Max < RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- }
- } else { // Signed comparison.
- int64_t Min, Max;
- int64_t RHSVal = CI->getSExtValue();
- ComputeSignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne,
- Min, Max);
- switch (I.getOpcode()) { // LE/GE have been folded already.
- default: assert(0 && "Unknown setcc opcode!");
- case Instruction::SetEQ:
- if (Max < RHSVal || Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- case Instruction::SetNE:
- if (Max < RHSVal || Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- break;
- case Instruction::SetLT:
- if (Max < RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- case Instruction::SetGT:
- if (Min > RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getTrue());
- if (Max < RHSVal)
- return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- break;
- }
+ // Compute the Min, Max and RHS values based on the known bits. For the
+ // EQ and NE we use unsigned values.
+ uint64_t UMin, UMax, URHSVal;
+ int64_t SMin, SMax, SRHSVal;
+ if (ICmpInst::isSignedPredicate(I.getPredicate())) {
+ SRHSVal = CI->getSExtValue();
+ ComputeSignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne, SMin,
+ SMax);
+ } else {
+ URHSVal = CI->getZExtValue();
+ ComputeUnsignedMinMaxValuesFromKnownBits(Ty, KnownZero, KnownOne, UMin,
+ UMax);
+ }
+ switch (I.getPredicate()) { // LE/GE have been folded already.
+ default: assert(0 && "Unknown icmp opcode!");
+ case ICmpInst::ICMP_EQ:
+ if (UMax < URHSVal || UMin > URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ break;
+ case ICmpInst::ICMP_NE:
+ if (UMax < URHSVal || UMin > URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ break;
+ case ICmpInst::ICMP_ULT:
+ if (UMax < URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (UMin > URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ break;
+ case ICmpInst::ICMP_UGT:
+ if (UMin > URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (UMax < URHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ break;
+ case ICmpInst::ICMP_SLT:
+ if (SMax < SRHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (SMin > SRHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ break;
+ case ICmpInst::ICMP_SGT:
+ if (SMin > SRHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getTrue());
+ if (SMax < SRHSVal)
+ return ReplaceInstUsesWith(I, ConstantBool::getFalse());
+ break;
}
}
- // Since the RHS is a constantInt (CI), if the left hand side is an
+ // Since the RHS is a ConstantInt (CI), if the left hand side is an
// instruction, see if that instruction also has constants so that the
- // instruction can be folded into the setcc
+ // instruction can be folded into the icmp
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
switch (LHSI->getOpcode()) {
case Instruction::And:
@@ -4289,7 +4576,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
LHSI->getOperand(0)->hasOneUse()) {
ConstantInt *AndCST = cast<ConstantInt>(LHSI->getOperand(1));
- // If an operand is an AND of a truncating cast, we can widen the
+ // If the LHS is an AND of a truncating cast, we can widen the
// and/compare to be the input width without changing the value
// produced, eliminating a cast.
if (CastInst *Cast = dyn_cast<CastInst>(LHSI->getOperand(0))) {
@@ -4318,7 +4605,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
BinaryOperator::createAnd(Cast->getOperand(0), NewCST,
LHSI->getName());
InsertNewInstBefore(NewAnd, I);
- return new SetCondInst(I.getOpcode(), NewAnd, NewCI);
+ return new ICmpInst(I.getPredicate(), NewAnd, NewCI);
}
}
@@ -4372,9 +4659,9 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// If we shifted bits out, the fold is not going to work out.
// As a special case, check to see if this means that the
// result is always true or false now.
- if (I.getOpcode() == Instruction::SetEQ)
+ if (I.getPredicate() == ICmpInst::ICMP_EQ)
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- if (I.getOpcode() == Instruction::SetNE)
+ if (I.getPredicate() == ICmpInst::ICMP_NE)
return ReplaceInstUsesWith(I, ConstantBool::getTrue());
} else {
I.setOperand(1, NewCst);
@@ -4438,7 +4725,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
}
break;
- case Instruction::Shl: // (setcc (shl X, ShAmt), CI)
+ case Instruction::Shl: // (icmp pred (shl X, ShAmt), CI)
if (ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
if (I.isEquality()) {
unsigned TypeBits = CI->getType()->getPrimitiveSizeInBits();
@@ -4454,8 +4741,8 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
Constant *Comp =
ConstantExpr::getShl(ConstantExpr::getLShr(CI, ShAmt), ShAmt);
if (Comp != CI) {// Comparing against a bit that we know is zero.
- bool IsSetNE = I.getOpcode() == Instruction::SetNE;
- Constant *Cst = ConstantBool::get(IsSetNE);
+ bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE;
+ Constant *Cst = ConstantBool::get(IsICMP_NE);
return ReplaceInstUsesWith(I, Cst);
}
@@ -4477,14 +4764,14 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
BinaryOperator::createAnd(LHSI->getOperand(0),
Mask, LHSI->getName()+".mask");
Value *And = InsertNewInstBefore(AndI, I);
- return new SetCondInst(I.getOpcode(), And,
+ return new ICmpInst(I.getPredicate(), And,
ConstantExpr::getLShr(CI, ShAmt));
}
}
}
break;
- case Instruction::LShr: // (setcc (shr X, ShAmt), CI)
+ case Instruction::LShr: // (icmp pred (shr X, ShAmt), CI)
case Instruction::AShr:
if (ConstantInt *ShAmt = dyn_cast<ConstantInt>(LHSI->getOperand(1))) {
if (I.isEquality()) {
@@ -4506,8 +4793,8 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
ShAmt);
if (Comp != CI) {// Comparing against a bit that we know is zero.
- bool IsSetNE = I.getOpcode() == Instruction::SetNE;
- Constant *Cst = ConstantBool::get(IsSetNE);
+ bool IsICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE;
+ Constant *Cst = ConstantBool::get(IsICMP_NE);
return ReplaceInstUsesWith(I, Cst);
}
@@ -4530,7 +4817,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
BinaryOperator::createAnd(LHSI->getOperand(0),
Mask, LHSI->getName()+".mask");
Value *And = InsertNewInstBefore(AndI, I);
- return new SetCondInst(I.getOpcode(), And,
+ return new ICmpInst(I.getPredicate(), And,
ConstantExpr::getShl(CI, ShAmt));
}
}
@@ -4539,7 +4826,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
case Instruction::SDiv:
case Instruction::UDiv:
- // Fold: setcc ([us]div X, C1), C2 -> range test
+ // Fold: icmp pred ([us]div X, C1), C2 -> range test
// Fold this div into the comparison, producing a range check.
// Determine, based on the divide type, what the range is being
// checked. If there is an overflow on the low or high side, remember
@@ -4554,11 +4841,8 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// (x /u C1) <u C2. Simply casting the operands and result won't
// work. :( The if statement below tests that condition and bails
// if it finds it.
- const Type *DivRHSTy = DivRHS->getType();
- unsigned DivOpCode = LHSI->getOpcode();
- if (I.isEquality() &&
- ((DivOpCode == Instruction::SDiv && DivRHSTy->isUnsigned()) ||
- (DivOpCode == Instruction::UDiv && DivRHSTy->isSigned())))
+ bool DivIsSigned = LHSI->getOpcode() == Instruction::SDiv;
+ if (!I.isEquality() && DivIsSigned != I.isSignedPredicate())
break;
// Initialize the variables that will indicate the nature of the
@@ -4577,16 +4861,15 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// not equal to the divide. Make sure we do the same kind of divide
// as in the LHS instruction that we're folding.
bool ProdOV = !DivRHS->isNullValue() &&
- (DivOpCode == Instruction::SDiv ?
- ConstantExpr::getSDiv(Prod, DivRHS) :
+ (DivIsSigned ? ConstantExpr::getSDiv(Prod, DivRHS) :
ConstantExpr::getUDiv(Prod, DivRHS)) != CI;
- // Get the SetCC opcode
- Instruction::BinaryOps Opcode = I.getOpcode();
+ // Get the ICmp opcode
+ ICmpInst::Predicate predicate = I.getPredicate();
if (DivRHS->isNullValue()) {
// Don't hack on divide by zeros!
- } else if (DivOpCode == Instruction::UDiv) { // udiv
+ } else if (!DivIsSigned) { // udiv
LoBound = Prod;
LoOverflow = ProdOV;
HiOverflow = ProdOV || AddWithOverflow(HiBound, LoBound, DivRHS);
@@ -4624,48 +4907,59 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
}
// Dividing by a negate swaps the condition.
- Opcode = SetCondInst::getSwappedCondition(Opcode);
+ predicate = ICmpInst::getSwappedPredicate(predicate);
}
if (LoBound) {
Value *X = LHSI->getOperand(0);
- switch (Opcode) {
- default: assert(0 && "Unhandled setcc opcode!");
- case Instruction::SetEQ:
+ switch (predicate) {
+ default: assert(0 && "Unhandled icmp opcode!");
+ case ICmpInst::ICMP_EQ:
if (LoOverflow && HiOverflow)
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
else if (HiOverflow)
- return new SetCondInst(Instruction::SetGE, X, LoBound);
+ return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE :
+ ICmpInst::ICMP_UGE, X, LoBound);
else if (LoOverflow)
- return new SetCondInst(Instruction::SetLT, X, HiBound);
+ return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT :
+ ICmpInst::ICMP_ULT, X, HiBound);
else
- return InsertRangeTest(X, LoBound, HiBound, true, I);
- case Instruction::SetNE:
+ return InsertRangeTest(X, LoBound, HiBound, DivIsSigned,
+ true, I);
+ case ICmpInst::ICMP_NE:
if (LoOverflow && HiOverflow)
return ReplaceInstUsesWith(I, ConstantBool::getTrue());
else if (HiOverflow)
- return new SetCondInst(Instruction::SetLT, X, LoBound);
+ return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SLT :
+ ICmpInst::ICMP_ULT, X, LoBound);
else if (LoOverflow)
- return new SetCondInst(Instruction::SetGE, X, HiBound);
+ return new ICmpInst(DivIsSigned ? ICmpInst::ICMP_SGE :
+ ICmpInst::ICMP_UGE, X, HiBound);
else
- return InsertRangeTest(X, LoBound, HiBound, false, I);
- case Instruction::SetLT:
+ return InsertRangeTest(X, LoBound, HiBound, DivIsSigned,
+ false, I);
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT:
if (LoOverflow)
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- return new SetCondInst(Instruction::SetLT, X, LoBound);
- case Instruction::SetGT:
+ return new ICmpInst(predicate, X, LoBound);
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
if (HiOverflow)
return ReplaceInstUsesWith(I, ConstantBool::getFalse());
- return new SetCondInst(Instruction::SetGE, X, HiBound);
+ if (predicate == ICmpInst::ICMP_UGT)
+ return new ICmpInst(ICmpInst::ICMP_UGE, X, HiBound);
+ else
+ return new ICmpInst(ICmpInst::ICMP_SGE, X, HiBound);
}
}
}
break;
}
- // Simplify seteq and setne instructions with integer constant RHS.
+ // Simplify icmp_eq and icmp_ne instructions with integer constant RHS.
if (I.isEquality()) {
- bool isSetNE = I.getOpcode() == Instruction::SetNE;
+ bool isICMP_NE = I.getPredicate() == ICmpInst::ICMP_NE;
// If the first operand is (add|sub|and|or|xor|rem) with a constant, and
// the second operand is a constant, simplify a bit.
@@ -4679,8 +4973,8 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
if (V > 1 && isPowerOf2_64(V)) {
Value *NewRem = InsertNewInstBefore(BinaryOperator::createURem(
BO->getOperand(0), BO->getOperand(1), BO->getName()), I);
- return BinaryOperator::create(I.getOpcode(), NewRem,
- Constant::getNullValue(BO->getType()));
+ return new ICmpInst(I.getPredicate(), NewRem,
+ Constant::getNullValue(BO->getType()));
}
}
break;
@@ -4688,22 +4982,22 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// Replace ((add A, B) != C) with (A != C-B) if B & C are constants.
if (ConstantInt *BOp1C = dyn_cast<ConstantInt>(BO->getOperand(1))) {
if (BO->hasOneUse())
- return new SetCondInst(I.getOpcode(), BO->getOperand(0),
- ConstantExpr::getSub(CI, BOp1C));
+ return new ICmpInst(I.getPredicate(), BO->getOperand(0),
+ ConstantExpr::getSub(CI, BOp1C));
} else if (CI->isNullValue()) {
// Replace ((add A, B) != 0) with (A != -B) if A or B is
// efficiently invertible, or if the add has just this one use.
Value *BOp0 = BO->getOperand(0), *BOp1 = BO->getOperand(1);
if (Value *NegVal = dyn_castNegVal(BOp1))
- return new SetCondInst(I.getOpcode(), BOp0, NegVal);
+ return new ICmpInst(I.getPredicate(), BOp0, NegVal);
else if (Value *NegVal = dyn_castNegVal(BOp0))
- return new SetCondInst(I.getOpcode(), NegVal, BOp1);
+ return new ICmpInst(I.getPredicate(), NegVal, BOp1);
else if (BO->hasOneUse()) {
Instruction *Neg = BinaryOperator::createNeg(BOp1, BO->getName());
BO->setName("");
InsertNewInstBefore(Neg, I);
- return new SetCondInst(I.getOpcode(), BOp0, Neg);
+ return new ICmpInst(I.getPredicate(), BOp0, Neg);
}
}
break;
@@ -4711,15 +5005,15 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// For the xor case, we can xor two constants together, eliminating
// the explicit xor.
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1)))
- return BinaryOperator::create(I.getOpcode(), BO->getOperand(0),
- ConstantExpr::getXor(CI, BOC));
+ return new ICmpInst(I.getPredicate(), BO->getOperand(0),
+ ConstantExpr::getXor(CI, BOC));
// FALLTHROUGH
case Instruction::Sub:
// Replace (([sub|xor] A, B) != 0) with (A != B)
if (CI->isNullValue())
- return new SetCondInst(I.getOpcode(), BO->getOperand(0),
- BO->getOperand(1));
+ return new ICmpInst(I.getPredicate(), BO->getOperand(0),
+ BO->getOperand(1));
break;
case Instruction::Or:
@@ -4728,7 +5022,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
if (Constant *BOC = dyn_cast<Constant>(BO->getOperand(1))) {
Constant *NotCI = ConstantExpr::getNot(CI);
if (!ConstantExpr::getAnd(BOC, NotCI)->isNullValue())
- return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+ return ReplaceInstUsesWith(I, ConstantBool::get(isICMP_NE));
}
break;
@@ -4738,16 +5032,15 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// comparison can never succeed!
if (!ConstantExpr::getAnd(CI,
ConstantExpr::getNot(BOC))->isNullValue())
- return ReplaceInstUsesWith(I, ConstantBool::get(isSetNE));
+ return ReplaceInstUsesWith(I, ConstantBool::get(isICMP_NE));
// If we have ((X & C) == C), turn it into ((X & C) != 0).
if (CI == BOC && isOneBitSet(CI))
- return new SetCondInst(isSetNE ? Instruction::SetEQ :
- Instruction::SetNE, Op0,
- Constant::getNullValue(CI->getType()));
+ return new ICmpInst(isICMP_NE ? ICmpInst::ICMP_EQ :
+ ICmpInst::ICMP_NE, Op0,
+ Constant::getNullValue(CI->getType()));
- // Replace (and X, (1 << size(X)-1) != 0) with x < 0, converting X
- // to be a signed value as appropriate.
+ // Replace (and X, (1 << size(X)-1) != 0) with x s< 0
if (isSignBit(BOC)) {
Value *X = BO->getOperand(0);
// If 'X' is not signed, insert a cast now...
@@ -4755,25 +5048,19 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
const Type *DestTy = BOC->getType()->getSignedVersion();
X = InsertCastBefore(Instruction::BitCast, X, DestTy, I);
}
- return new SetCondInst(isSetNE ? Instruction::SetLT :
- Instruction::SetGE, X,
- Constant::getNullValue(X->getType()));
+ Constant *Zero = Constant::getNullValue(X->getType());
+ ICmpInst::Predicate pred = isICMP_NE ?
+ ICmpInst::ICMP_SLT : ICmpInst::ICMP_SGE;
+ return new ICmpInst(pred, X, Zero);
}
// ((X & ~7) == 0) --> X < 8
if (CI->isNullValue() && isHighOnes(BOC)) {
Value *X = BO->getOperand(0);
Constant *NegX = ConstantExpr::getNeg(BOC);
-
- // If 'X' is signed, insert a cast now.
- if (NegX->getType()->isSigned()) {
- const Type *DestTy = NegX->getType()->getUnsignedVersion();
- X = InsertCastBefore(Instruction::BitCast, X, DestTy, I);
- NegX = ConstantExpr::getBitCast(NegX, DestTy);
- }
-
- return new SetCondInst(isSetNE ? Instruction::SetGE :
- Instruction::SetLT, X, NegX);
+ ICmpInst::Predicate pred = isICMP_NE ?
+ ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
+ return new ICmpInst(pred, X, NegX);
}
}
@@ -4783,19 +5070,22 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
// Handle set{eq|ne} <intrinsic>, intcst.
switch (II->getIntrinsicID()) {
default: break;
- case Intrinsic::bswap_i16: // seteq (bswap(x)), c -> seteq(x,bswap(c))
+ case Intrinsic::bswap_i16:
+ // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c))
WorkList.push_back(II); // Dead?
I.setOperand(0, II->getOperand(1));
I.setOperand(1, ConstantInt::get(Type::UShortTy,
ByteSwap_16(CI->getZExtValue())));
return &I;
- case Intrinsic::bswap_i32: // seteq (bswap(x)), c -> seteq(x,bswap(c))
+ case Intrinsic::bswap_i32:
+ // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c))
WorkList.push_back(II); // Dead?
I.setOperand(0, II->getOperand(1));
I.setOperand(1, ConstantInt::get(Type::UIntTy,
ByteSwap_32(CI->getZExtValue())));
return &I;
- case Intrinsic::bswap_i64: // seteq (bswap(x)), c -> seteq(x,bswap(c))
+ case Intrinsic::bswap_i64:
+ // icmp eq (bswap(x)), c -> icmp eq (x,bswap(c))
WorkList.push_back(II); // Dead?
I.setOperand(0, II->getOperand(1));
I.setOperand(1, ConstantInt::get(Type::ULongTy,
@@ -4803,53 +5093,47 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
return &I;
}
}
- } else { // Not a SetEQ/SetNE
- // If the LHS is a cast from an integral value of the same size,
+ } else { // Not a ICMP_EQ/ICMP_NE
+ // If the LHS is a cast from an integral value of the same size, then
+ // since we know the RHS is a constant, try to simlify.
if (CastInst *Cast = dyn_cast<CastInst>(Op0)) {
Value *CastOp = Cast->getOperand(0);
const Type *SrcTy = CastOp->getType();
unsigned SrcTySize = SrcTy->getPrimitiveSizeInBits();
- if (SrcTy != Cast->getType() && SrcTy->isInteger() &&
+ if (SrcTy->isInteger() &&
SrcTySize == Cast->getType()->getPrimitiveSizeInBits()) {
- assert((SrcTy->isSigned() ^ Cast->getType()->isSigned()) &&
- "Source and destination signednesses should differ!");
- if (Cast->getType()->isSigned()) {
- // If this is a signed comparison, check for comparisons in the
- // vicinity of zero.
- if (I.getOpcode() == Instruction::SetLT && CI->isNullValue())
- // X < 0 => x > 127
- return BinaryOperator::createSetGT(CastOp,
- ConstantInt::get(SrcTy, (1ULL << (SrcTySize-1))-1));
- else if (I.getOpcode() == Instruction::SetGT &&
- cast<ConstantInt>(CI)->getSExtValue() == -1)
- // X > -1 => x < 128
- return BinaryOperator::createSetLT(CastOp,
- ConstantInt::get(SrcTy, 1ULL << (SrcTySize-1)));
- } else {
- ConstantInt *CUI = cast<ConstantInt>(CI);
- if (I.getOpcode() == Instruction::SetLT &&
- CUI->getZExtValue() == 1ULL << (SrcTySize-1))
- // X < 128 => X > -1
- return BinaryOperator::createSetGT(CastOp,
- ConstantInt::get(SrcTy, -1));
- else if (I.getOpcode() == Instruction::SetGT &&
- CUI->getZExtValue() == (1ULL << (SrcTySize-1))-1)
- // X > 127 => X < 0
- return BinaryOperator::createSetLT(CastOp,
- Constant::getNullValue(SrcTy));
+ // If this is an unsigned comparison, try to make the comparison use
+ // smaller constant values.
+ switch (I.getPredicate()) {
+ default: break;
+ case ICmpInst::ICMP_ULT: { // X u< 128 => X s> -1
+ ConstantInt *CUI = cast<ConstantInt>(CI);
+ if (CUI->getZExtValue() == 1ULL << (SrcTySize-1))
+ return new ICmpInst(ICmpInst::ICMP_SGT, CastOp,
+ ConstantInt::get(SrcTy, -1));
+ break;
+ }
+ case ICmpInst::ICMP_UGT: { // X u> 127 => X s< 0
+ ConstantInt *CUI = cast<ConstantInt>(CI);
+ if (CUI->getZExtValue() == (1ULL << (SrcTySize-1))-1)
+ return new ICmpInst(ICmpInst::ICMP_SLT, CastOp,
+ Constant::getNullValue(SrcTy));
+ break;
+ }
}
+
}
}
}
}
- // Handle setcc with constant RHS's that can be integer, FP or pointer.
+ // Handle icmp with constant RHS
if (Constant *RHSC = dyn_cast<Constant>(Op1)) {
if (Instruction *LHSI = dyn_cast<Instruction>(Op0))
switch (LHSI->getOpcode()) {
case Instruction::GetElementPtr:
if (RHSC->isNullValue()) {
- // Transform setcc GEP P, int 0, int 0, int 0, null -> setcc P, null
+ // icmp pred GEP (P, int 0, int 0, int 0), null -> icmp pred P, null
bool isAllZeros = true;
for (unsigned i = 1, e = LHSI->getNumOperands(); i != e; ++i)
if (!isa<Constant>(LHSI->getOperand(i)) ||
@@ -4858,7 +5142,7 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
break;
}
if (isAllZeros)
- return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),
+ return new ICmpInst(I.getPredicate(), LHSI->getOperand(0),
Constant::getNullValue(LHSI->getOperand(0)->getType()));
}
break;
@@ -4875,18 +5159,18 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
if (LHSI->hasOneUse()) {
if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(1))) {
// Fold the known value into the constant operand.
- Op1 = ConstantExpr::get(I.getOpcode(), C, RHSC);
- // Insert a new SetCC of the other select operand.
- Op2 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
- LHSI->getOperand(2), RHSC,
- I.getName()), I);
+ Op1 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
+ // Insert a new ICmp of the other select operand.
+ Op2 = InsertNewInstBefore(new ICmpInst(I.getPredicate(),
+ LHSI->getOperand(2), RHSC,
+ I.getName()), I);
} else if (Constant *C = dyn_cast<Constant>(LHSI->getOperand(2))) {
// Fold the known value into the constant operand.
- Op2 = ConstantExpr::get(I.getOpcode(), C, RHSC);
- // Insert a new SetCC of the other select operand.
- Op1 = InsertNewInstBefore(new SetCondInst(I.getOpcode(),
- LHSI->getOperand(1), RHSC,
- I.getName()), I);
+ Op2 = ConstantExpr::getICmp(I.getPredicate(), C, RHSC);
+ // Insert a new ICmp of the other select operand.
+ Op1 = InsertNewInstBefore(new ICmpInst(I.getPredicate(),
+ LHSI->getOperand(1), RHSC,
+ I.getName()), I);
}
}
@@ -4896,16 +5180,16 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
}
}
- // If we can optimize a 'setcc GEP, P' or 'setcc P, GEP', do so now.
+ // If we can optimize a 'icmp GEP, P' or 'icmp P, GEP', do so now.
if (User *GEP = dyn_castGetElementPtr(Op0))
- if (Instruction *NI = FoldGEPSetCC(GEP, Op1, I.getOpcode(), I))
+ if (Instruction *NI = FoldGEPICmp(GEP, Op1, I.getPredicate(), I))
return NI;
if (User *GEP = dyn_castGetElementPtr(Op1))
- if (Instruction *NI = FoldGEPSetCC(GEP, Op0,
- SetCondInst::getSwappedCondition(I.getOpcode()), I))
+ if (Instruction *NI = FoldGEPICmp(GEP, Op0,
+ ICmpInst::getSwappedPredicate(I.getPredicate()), I))
return NI;
- // Test to see if the operands of the setcc are casted versions of other
+ // Test to see if the operands of the icmp are casted versions of other
// values. If the cast can be stripped off both arguments, we do so now.
if (CastInst *CI = dyn_cast<CastInst>(Op0)) {
Value *CastOp0 = CI->getOperand(0);
@@ -4928,20 +5212,20 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
if (Constant *Op1C = dyn_cast<Constant>(Op1)) {
Op1 = ConstantExpr::getBitCast(Op1C, Op0->getType());
} else {
- // Otherwise, cast the RHS right before the setcc
+ // Otherwise, cast the RHS right before the icmp
Op1 = InsertCastBefore(Instruction::BitCast, Op1, Op0->getType(), I);
}
- return BinaryOperator::create(I.getOpcode(), Op0, Op1);
+ return new ICmpInst(I.getPredicate(), Op0, Op1);
}
- // Handle the special case of: setcc (cast bool to X), <cst>
+ // Handle the special case of: icmp (cast bool to X), <cst>
// This comes up when you have code like
// int X = A < B;
// if (X) ...
// For generality, we handle any zero-extension of any operand comparison
// with a constant or another cast from the same type.
if (isa<ConstantInt>(Op1) || isa<CastInst>(Op1))
- if (Instruction *R = visitSetCondInstWithCastAndCast(I))
+ if (Instruction *R = visitICmpInstWithCastAndCast(I))
return R;
}
@@ -4951,22 +5235,22 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
(A == Op1 || B == Op1)) {
// (A^B) == A -> B == 0
Value *OtherVal = A == Op1 ? B : A;
- return BinaryOperator::create(I.getOpcode(), OtherVal,
- Constant::getNullValue(A->getType()));
+ return new ICmpInst(I.getPredicate(), OtherVal,
+ Constant::getNullValue(A->getType()));
} else if (match(Op1, m_Xor(m_Value(A), m_Value(B))) &&
(A == Op0 || B == Op0)) {
// A == (A^B) -> B == 0
Value *OtherVal = A == Op0 ? B : A;
- return BinaryOperator::create(I.getOpcode(), OtherVal,
- Constant::getNullValue(A->getType()));
+ return new ICmpInst(I.getPredicate(), OtherVal,
+ Constant::getNullValue(A->getType()));
} else if (match(Op0, m_Sub(m_Value(A), m_Value(B))) && A == Op1) {
// (A-B) == A -> B == 0
- return BinaryOperator::create(I.getOpcode(), B,
- Constant::getNullValue(B->getType()));
+ return new ICmpInst(I.getPredicate(), B,
+ Constant::getNullValue(B->getType()));
} else if (match(Op1, m_Sub(m_Value(A), m_Value(B))) && A == Op0) {
// A == (A-B) -> B == 0
- return BinaryOperator::create(I.getOpcode(), B,
- Constant::getNullValue(B->getType()));
+ return new ICmpInst(I.getPredicate(), B,
+ Constant::getNullValue(B->getType()));
}
Value *C, *D;
@@ -4998,116 +5282,113 @@ Instruction *InstCombiner::visitSetCondInst(SetCondInst &I) {
return Changed ? &I : 0;
}
-// visitSetCondInstWithCastAndCast - Handle setcond (cast x to y), (cast/cst).
+// visitICmpInstWithCastAndCast - Handle icmp (cast x to y), (cast/cst).
// We only handle extending casts so far.
//
-Instruction *InstCombiner::visitSetCondInstWithCastAndCast(SetCondInst &SCI) {
- const CastInst *LHSCI = cast<CastInst>(SCI.getOperand(0));
+Instruction *InstCombiner::visitICmpInstWithCastAndCast(ICmpInst &ICI) {
+ const CastInst *LHSCI = cast<CastInst>(ICI.getOperand(0));
Value *LHSCIOp = LHSCI->getOperand(0);
const Type *SrcTy = LHSCIOp->getType();
- const Type *DestTy = SCI.getOperand(0)->getType();
+ const Type *DestTy = LHSCI->getType();
Value *RHSCIOp;
- if (!DestTy->isIntegral() || !SrcTy->isIntegral())
+ // We only handle extension cast instructions, so far. Enforce this.
+ if (LHSCI->getOpcode() != Instruction::ZExt &&
+ LHSCI->getOpcode() != Instruction::SExt)
return 0;
- unsigned SrcBits = SrcTy->getPrimitiveSizeInBits();
- unsigned DestBits = DestTy->getPrimitiveSizeInBits();
- if (SrcBits >= DestBits) return 0; // Only handle extending cast.
+ bool isSignedExt = LHSCI->getOpcode() == Instruction::SExt;
+ bool isSignedCmp = ICI.isSignedPredicate();
- // Is this a sign or zero extension?
- bool isSignSrc = SrcTy->isSigned();
- bool isSignDest = DestTy->isSigned();
-
- if (CastInst *CI = dyn_cast<CastInst>(SCI.getOperand(1))) {
+ if (CastInst *CI = dyn_cast<CastInst>(ICI.getOperand(1))) {
// Not an extension from the same type?
RHSCIOp = CI->getOperand(0);
- if (RHSCIOp->getType() != LHSCIOp->getType()) return 0;
- } else if (ConstantInt *CI = dyn_cast<ConstantInt>(SCI.getOperand(1))) {
- // Compute the constant that would happen if we truncated to SrcTy then
- // reextended to DestTy.
- Constant *Res1 = ConstantExpr::getTrunc(CI, SrcTy);
- Constant *Res2 = ConstantExpr::getCast(LHSCI->getOpcode(), Res1, DestTy);
-
- if (Res2 == CI) {
- // Make sure that src sign and dest sign match. For example,
- //
- // %A = cast short %X to uint
- // %B = setgt uint %A, 1330
- //
- // It is incorrect to transform this into
- //
- // %B = setgt short %X, 1330
- //
- // because %A may have negative value.
- // However, it is OK if SrcTy is bool (See cast-set.ll testcase)
- // OR operation is EQ/NE.
- if (isSignSrc == isSignDest || SrcTy == Type::BoolTy || SCI.isEquality())
- RHSCIOp = Res1;
- else
- return 0;
- } else {
- // If the value cannot be represented in the shorter type, we cannot emit
- // a simple comparison.
- if (SCI.getOpcode() == Instruction::SetEQ)
- return ReplaceInstUsesWith(SCI, ConstantBool::getFalse());
- if (SCI.getOpcode() == Instruction::SetNE)
- return ReplaceInstUsesWith(SCI, ConstantBool::getTrue());
-
- // Evaluate the comparison for LT.
- Value *Result;
- if (DestTy->isSigned()) {
- // We're performing a signed comparison.
- if (isSignSrc) {
- // Signed extend and signed comparison.
- if (cast<ConstantInt>(CI)->getSExtValue() < 0)// X < (small) --> false
- Result = ConstantBool::getFalse();
- else
- Result = ConstantBool::getTrue(); // X < (large) --> true
- } else {
- // Unsigned extend and signed comparison.
- if (cast<ConstantInt>(CI)->getSExtValue() < 0)
- Result = ConstantBool::getFalse();
- else
- Result = ConstantBool::getTrue();
- }
- } else {
- // We're performing an unsigned comparison.
- if (!isSignSrc) {
- // Unsigned extend & compare -> always true.
- Result = ConstantBool::getTrue();
- } else {
- // We're performing an unsigned comp with a sign extended value.
- // This is true if the input is >= 0. [aka >s -1]
- Constant *NegOne = ConstantIntegral::getAllOnesValue(SrcTy);
- Result = InsertNewInstBefore(BinaryOperator::createSetGT(LHSCIOp,
- NegOne, SCI.getName()), SCI);
- }
- }
+ if (RHSCIOp->getType() != LHSCIOp->getType())
+ return 0;
+ else
+ // Okay, just insert a compare of the reduced operands now!
+ return new ICmpInst(ICI.getPredicate(), LHSCIOp, RHSCIOp);
+ }
- // Finally, return the value computed.
- if (SCI.getOpcode() == Instruction::SetLT) {
- return ReplaceInstUsesWith(SCI, Result);
- } else {
- assert(SCI.getOpcode()==Instruction::SetGT &&"SetCC should be folded!");
- if (Constant *CI = dyn_cast<Constant>(Result))
- return ReplaceInstUsesWith(SCI, ConstantExpr::getNot(CI));
- else
- return BinaryOperator::createNot(Result);
- }
- }
- } else {
+ // If we aren't dealing with a constant on the RHS, exit early
+ ConstantInt *CI = dyn_cast<ConstantInt>(ICI.getOperand(1));
+ if (!CI)
return 0;
+
+ // Compute the constant that would happen if we truncated to SrcTy then
+ // reextended to DestTy.
+ Constant *Res1 = ConstantExpr::getTrunc(CI, SrcTy);
+ Constant *Res2 = ConstantExpr::getCast(LHSCI->getOpcode(), Res1, DestTy);
+
+ // If the re-extended constant didn't change...
+ if (Res2 == CI) {
+ // Make sure that sign of the Cmp and the sign of the Cast are the same.
+ // For example, we might have:
+ // %A = sext short %X to uint
+ // %B = icmp ugt uint %A, 1330
+ // It is incorrect to transform this into
+ // %B = icmp ugt short %X, 1330
+ // because %A may have negative value.
+ //
+ // However, it is OK if SrcTy is bool (See cast-set.ll testcase)
+ // OR operation is EQ/NE.
+ if (isSignedExt == isSignedCmp || SrcTy == Type::BoolTy || ICI.isEquality())
+ return new ICmpInst(ICI.getPredicate(), LHSCIOp, Res1);
+ else
+ return 0;
}
- // Okay, just insert a compare of the reduced operands now!
- return BinaryOperator::create(SCI.getOpcode(), LHSCIOp, RHSCIOp);
+ // The re-extended constant changed so the constant cannot be represented
+ // in the shorter type. Consequently, we cannot emit a simple comparison.
+
+ // First, handle some easy cases. We know the result cannot be equal at this
+ // point so handle the ICI.isEquality() cases
+ if (ICI.getPredicate() == ICmpInst::ICMP_EQ)
+ return ReplaceInstUsesWith(ICI, ConstantBool::getFalse());
+ if (ICI.getPredicate() == ICmpInst::ICMP_NE)
+ return ReplaceInstUsesWith(ICI, ConstantBool::getTrue());
+
+ // Evaluate the comparison for LT (we invert for GT below). LE and GE cases
+ // should have been folded away previously and not enter in here.
+ Value *Result;
+ if (isSignedCmp) {
+ // We're performing a signed comparison.
+ if (cast<ConstantInt>(CI)->getSExtValue() < 0)
+ Result = ConstantBool::getFalse(); // X < (small) --> false
+ else
+ Result = ConstantBool::getTrue(); // X < (large) --> true
+ } else {
+ // We're performing an unsigned comparison.
+ if (isSignedExt) {
+ // We're performing an unsigned comp with a sign extended value.
+ // This is true if the input is >= 0. [aka >s -1]
+ Constant *NegOne = ConstantIntegral::getAllOnesValue(SrcTy);
+ Result = InsertNewInstBefore(new ICmpInst(ICmpInst::ICMP_SGT, LHSCIOp,
+ NegOne, ICI.getName()), ICI);
+ } else {
+ // Unsigned extend & unsigned compare -> always true.
+ Result = ConstantBool::getTrue();
+ }
+ }
+
+ // Finally, return the value computed.
+ if (ICI.getPredicate() == ICmpInst::ICMP_ULT ||
+ ICI.getPredicate() == ICmpInst::ICMP_SLT) {
+ return ReplaceInstUsesWith(ICI, Result);
+ } else {
+ assert((ICI.getPredicate()==ICmpInst::ICMP_UGT ||
+ ICI.getPredicate()==ICmpInst::ICMP_SGT) &&
+ "ICmp should be folded!");
+ if (Constant *CI = dyn_cast<Constant>(Result))
+ return ReplaceInstUsesWith(ICI, ConstantExpr::getNot(CI));
+ else
+ return BinaryOperator::createNot(Result);
+ }
}
Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
assert(I.getOperand(1)->getType() == Type::UByteTy);
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
- bool isLeftShift = I.getOpcode() == Instruction::Shl;
// shl X, 0 == X and shr X, 0 == X
// shl 0, X == 0 and shr 0, X == 0
@@ -5115,17 +5396,17 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
Op0 == Constant::getNullValue(Op0->getType()))
return ReplaceInstUsesWith(I, Op0);
- if (isa<UndefValue>(Op0)) { // undef >>s X -> undef
- if (!isLeftShift && I.getType()->isSigned())
+ if (isa<UndefValue>(Op0)) {
+ if (I.getOpcode() == Instruction::AShr) // undef >>s X -> undef
return ReplaceInstUsesWith(I, Op0);
- else // undef << X -> 0 AND undef >>u X -> 0
+ else // undef << X -> 0, undef >>u X -> 0
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
}
if (isa<UndefValue>(Op1)) {
- if (isLeftShift || I.getType()->isUnsigned())// X << undef, X >>u undef -> 0
+ if (I.getOpcode() == Instruction::AShr) // X >>s undef -> X
+ return ReplaceInstUsesWith(I, Op0);
+ else // X << undef, X >>u undef -> 0
return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType()));
- else
- return ReplaceInstUsesWith(I, Op0); // X >>s undef -> X
}
// ashr int -1, X = -1 (for any arithmetic shift rights of ~0)
@@ -5157,9 +5438,8 @@ Instruction *InstCombiner::visitShiftInst(ShiftInst &I) {
Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
ShiftInst &I) {
- bool isLeftShift = I.getOpcode() == Instruction::Shl;
- bool isSignedShift = isLeftShift ? Op0->getType()->isSigned() :
- I.getOpcode() == Instruction::AShr;
+ bool isLeftShift = I.getOpcode() == Instruction::Shl;
+ bool isSignedShift = I.getOpcode() == Instruction::AShr;
bool isUnsignedShift = !isSignedShift;
// See if we can simplify any instructions used by the instruction whose sole
@@ -5348,10 +5628,8 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1,
// Find the operands and properties of the input shift. Note that the
// signedness of the input shift may differ from the current shift if there
// is a noop cast between the two.
- bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl;
- bool isShiftOfSignedShift = isShiftOfLeftShift ?
- ShiftOp->getType()->isSigned() :
- ShiftOp->getOpcode() == Instruction::AShr;
+ bool isShiftOfLeftShift = ShiftOp->getOpcode() == Instruction::Shl;
+ bool isShiftOfSignedShift = ShiftOp->getOpcode() == Instruction::AShr;
bool isShiftOfUnsignedShift = !isShiftOfSignedShift;
ConstantInt *ShiftAmt1C = cast<ConstantInt>(ShiftOp->getOperand(1));
@@ -5781,11 +6059,11 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
// If the source isn't an instruction or has more than one use then we
// can't do anything more.
- if (!isa<Instruction>(Src) || !Src->hasOneUse())
+ Instruction *SrcI = dyn_cast<Instruction>(Src);
+ if (!SrcI || !Src->hasOneUse())
return 0;
// Attempt to propagate the cast into the instruction.
- Instruction *SrcI = cast<Instruction>(Src);
int NumCastsRemoved = 0;
if (CanEvaluateInDifferentType(SrcI, DestTy, NumCastsRemoved)) {
// If this cast is a truncate, evaluting in a different type always
@@ -5867,8 +6145,8 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
// two casts to be inserted if the sizes are the same. This could
// only be converting signedness, which is a noop.
if (DestBitSize == SrcBitSize ||
- !ValueRequiresCast(Op1, DestTy,TD) ||
- !ValueRequiresCast(Op0, DestTy, TD)) {
+ !ValueRequiresCast(CI.getOpcode(), Op1, DestTy,TD) ||
+ !ValueRequiresCast(CI.getOpcode(), Op0, DestTy, TD)) {
Instruction::CastOps opcode = CI.getOpcode();
Value *Op0c = InsertOperandCastBefore(opcode, Op0, DestTy, SrcI);
Value *Op1c = InsertOperandCastBefore(opcode, Op1, DestTy, SrcI);
@@ -5881,7 +6159,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
if (isa<ZExtInst>(CI) && SrcBitSize == 1 &&
SrcI->getOpcode() == Instruction::Xor &&
Op1 == ConstantBool::getTrue() &&
- (!Op0->hasOneUse() || !isa<SetCondInst>(Op0))) {
+ (!Op0->hasOneUse() || !isa<CmpInst>(Op0))) {
Value *New = InsertOperandCastBefore(Instruction::ZExt, Op0, DestTy, &CI);
return BinaryOperator::createXor(New, ConstantInt::get(CI.getType(), 1));
}
@@ -5895,8 +6173,8 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
// Don't insert two casts if they cannot be eliminated. We allow
// two casts to be inserted if the sizes are the same. This could
// only be converting signedness, which is a noop.
- if (!ValueRequiresCast(Op1, DestTy,TD) ||
- !ValueRequiresCast(Op0, DestTy, TD)) {
+ if (!ValueRequiresCast(CI.getOpcode(), Op1, DestTy, TD) ||
+ !ValueRequiresCast(CI.getOpcode(), Op0, DestTy, TD)) {
Value *Op0c = InsertOperandCastBefore(Instruction::BitCast,
Op0, DestTy, SrcI);
Value *Op1c = InsertOperandCastBefore(Instruction::BitCast,
@@ -5935,10 +6213,9 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
}
break;
- case Instruction::SetEQ:
- case Instruction::SetNE:
- // If we are just checking for a seteq of a single bit and casting it
- // to an integer. If so, shift the bit to the appropriate place then
+ case Instruction::ICmp:
+ // If we are just checking for a icmp eq of a single bit and casting it
+ // to an integer, then shift the bit to the appropriate place and then
// cast to integer to avoid the comparison.
if (ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
uint64_t Op1CV = Op1C->getZExtValue();
@@ -5955,13 +6232,18 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
uint64_t KnownZero, KnownOne;
uint64_t TypeMask = Op1->getType()->getIntegralTypeMask();
ComputeMaskedBits(Op0, TypeMask, KnownZero, KnownOne);
+
+ // This only works for EQ and NE
+ ICmpInst::Predicate pred = cast<ICmpInst>(SrcI)->getPredicate();
+ if (pred != ICmpInst::ICMP_NE && pred != ICmpInst::ICMP_EQ)
+ break;
if (isPowerOf2_64(KnownZero^TypeMask)) { // Exactly 1 possible 1?
- bool isSetNE = SrcI->getOpcode() == Instruction::SetNE;
+ bool isNE = pred == ICmpInst::ICMP_NE;
if (Op1CV && (Op1CV != (KnownZero^TypeMask))) {
// (X&4) == 2 --> false
// (X&4) != 2 --> true
- Constant *Res = ConstantBool::get(isSetNE);
+ Constant *Res = ConstantBool::get(isNE);
Res = ConstantExpr::getZExt(Res, CI.getType());
return ReplaceInstUsesWith(CI, Res);
}
@@ -5977,7 +6259,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) {
In->getName()+".lobit"), CI);
}
- if ((Op1CV != 0) == isSetNE) { // Toggle the low bit.
+ if ((Op1CV != 0) == isNE) { // Toggle the low bit.
Constant *One = ConstantInt::get(In->getType(), 1);
In = BinaryOperator::createXor(In, One, "tmp");
InsertNewInstBefore(cast<Instruction>(In), CI);
@@ -6039,7 +6321,7 @@ Instruction *InstCombiner::visitTrunc(CastInst &CI) {
SrcI->getOperand(0),
"tmp"), CI);
Value *Zero = Constant::getNullValue(V->getType());
- return BinaryOperator::createSetNE(V, Zero);
+ return new ICmpInst(ICmpInst::ICMP_NE, V, Zero);
}
}
break;
@@ -6272,8 +6554,14 @@ Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI,
TI->getType());
}
- // Only handle binary operators here.
- if (!isa<ShiftInst>(TI) && !isa<BinaryOperator>(TI))
+ // Only handle binary, compare and shift operators here.
+ if (!isa<ShiftInst>(TI) && !isa<BinaryOperator>(TI) && !isa<CmpInst>(TI))
+ return 0;
+
+ // If the CmpInst predicates don't match, then the instructions aren't the
+ // same and we can't continue.
+ if (isa<CmpInst>(TI) && isa<CmpInst>(FI) &&
+ (cast<CmpInst>(TI)->getPredicate() != cast<CmpInst>(FI)->getPredicate()))
return 0;
// Figure out if the operations have any operands in common.
@@ -6387,20 +6675,20 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
return CastInst::create(Instruction::ZExt, NotCond, SI.getType());
}
- if (SetCondInst *IC = dyn_cast<SetCondInst>(SI.getCondition())) {
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition())) {
- // (x <s 0) ? -1 : 0 -> sra x, 31
- // (x >u 2147483647) ? -1 : 0 -> sra x, 31
+ // (x <s 0) ? -1 : 0 -> ashr x, 31
+ // (x >u 2147483647) ? -1 : 0 -> ashr x, 31
if (TrueValC->isAllOnesValue() && FalseValC->isNullValue())
if (ConstantInt *CmpCst = dyn_cast<ConstantInt>(IC->getOperand(1))) {
bool CanXForm = false;
- if (CmpCst->getType()->isSigned())
+ if (IC->isSignedPredicate())
CanXForm = CmpCst->isNullValue() &&
- IC->getOpcode() == Instruction::SetLT;
+ IC->getPredicate() == ICmpInst::ICMP_SLT;
else {
unsigned Bits = CmpCst->getType()->getPrimitiveSizeInBits();
CanXForm = (CmpCst->getZExtValue() == ~0ULL >> (64-Bits+1)) &&
- IC->getOpcode() == Instruction::SetGT;
+ IC->getPredicate() == ICmpInst::ICMP_UGT;
}
if (CanXForm) {
@@ -6428,7 +6716,7 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
// If one of the constants is zero (we know they can't both be) and we
- // have a setcc instruction with zero, and we have an 'and' with the
+ // have a fcmp instruction with zero, and we have an 'and' with the
// non-constant value, eliminate this whole mess. This corresponds to
// cases like this: ((X & 27) ? 27 : 0)
if (TrueValC->isNullValue() || FalseValC->isNullValue())
@@ -6441,10 +6729,10 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
ICA->getOperand(1) == FalseValC) &&
isOneBitSet(cast<ConstantInt>(ICA->getOperand(1)))) {
// Okay, now we know that everything is set up, we just don't
- // know whether we have a setne or seteq and whether the true or
- // false val is the zero.
+ // know whether we have a icmp_ne or icmp_eq and whether the
+ // true or false val is the zero.
bool ShouldNotVal = !TrueValC->isNullValue();
- ShouldNotVal ^= IC->getOpcode() == Instruction::SetNE;
+ ShouldNotVal ^= IC->getPredicate() == ICmpInst::ICMP_NE;
Value *V = ICA;
if (ShouldNotVal)
V = InsertNewInstBefore(BinaryOperator::create(
@@ -6455,22 +6743,44 @@ Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
}
// See if we are selecting two values based on a comparison of the two values.
- if (SetCondInst *SCI = dyn_cast<SetCondInst>(CondVal)) {
- if (SCI->getOperand(0) == TrueVal && SCI->getOperand(1) == FalseVal) {
+ if (FCmpInst *FCI = dyn_cast<FCmpInst>(CondVal)) {
+ if (FCI->getOperand(0) == TrueVal && FCI->getOperand(1) == FalseVal) {
// Transform (X == Y) ? X : Y -> Y
- if (SCI->getOpcode() == Instruction::SetEQ)
+ if (FCI->getPredicate() == FCmpInst::FCMP_OEQ)
return ReplaceInstUsesWith(SI, FalseVal);
// Transform (X != Y) ? X : Y -> X
- if (SCI->getOpcode() == Instruction::SetNE)
+ if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
return ReplaceInstUsesWith(SI, TrueVal);
// NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
- } else if (SCI->getOperand(0) == FalseVal && SCI->getOperand(1) == TrueVal){
+ } else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
// Transform (X == Y) ? Y : X -> X
- if (SCI->getOpcode() == Instruction::SetEQ)
+ if (FCI->getPredicate() == FCmpInst::FCMP_OEQ)
return ReplaceInstUsesWith(SI, FalseVal);
// Transform (X != Y) ? Y : X -> Y
- if (SCI->getOpcode() == Instruction::SetNE)
+ if (FCI->getPredicate() == FCmpInst::FCMP_ONE)
+ return ReplaceInstUsesWith(SI, TrueVal);
+ // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
+ }
+ }
+
+ // See if we are selecting two values based on a comparison of the two values.
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal)) {
+ if (ICI->getOperand(0) == TrueVal && ICI->getOperand(1) == FalseVal) {
+ // Transform (X == Y) ? X : Y -> Y
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ return ReplaceInstUsesWith(SI, FalseVal);
+ // Transform (X != Y) ? X : Y -> X
+ if (ICI->getPredicate() == ICmpInst::ICMP_NE)
+ return ReplaceInstUsesWith(SI, TrueVal);
+ // NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
+
+ } else if (ICI->getOperand(0) == FalseVal && ICI->getOperand(1) == TrueVal){
+ // Transform (X == Y) ? Y : X -> X
+ if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
+ return ReplaceInstUsesWith(SI, FalseVal);
+ // Transform (X != Y) ? Y : X -> Y
+ if (ICI->getPredicate() == ICmpInst::ICMP_NE)
return ReplaceInstUsesWith(SI, TrueVal);
// NOTE: if we wanted to, this is where to detect MIN/MAX/ABS/etc.
}
@@ -7096,7 +7406,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
Instruction *FirstInst = cast<Instruction>(PN.getIncomingValue(0));
assert(isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst) ||
- isa<GetElementPtrInst>(FirstInst));
+ isa<GetElementPtrInst>(FirstInst) || isa<CmpInst>(FirstInst));
unsigned Opc = FirstInst->getOpcode();
Value *LHSVal = FirstInst->getOperand(0);
Value *RHSVal = FirstInst->getOperand(1);
@@ -7109,11 +7419,17 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
for (unsigned i = 0; i != PN.getNumIncomingValues(); ++i) {
Instruction *I = dyn_cast<Instruction>(PN.getIncomingValue(i));
if (!I || I->getOpcode() != Opc || !I->hasOneUse() ||
- // Verify type of the LHS matches so we don't fold setcc's of different
+ // Verify type of the LHS matches so we don't fold cmp's of different
// types or GEP's with different index types.
I->getOperand(0)->getType() != LHSType ||
I->getOperand(1)->getType() != RHSType)
return 0;
+
+ // If they are CmpInst instructions, check their predicates
+ if (Opc == Instruction::ICmp || Opc == Instruction::FCmp)
+ if (cast<CmpInst>(I)->getPredicate() !=
+ cast<CmpInst>(FirstInst)->getPredicate())
+ return 0;
// Keep track of which operand needs a phi node.
if (I->getOperand(0) != LHSVal) LHSVal = 0;
@@ -7161,6 +7477,9 @@ Instruction *InstCombiner::FoldPHIArgBinOpIntoPHI(PHINode &PN) {
if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
return BinaryOperator::create(BinOp->getOpcode(), LHSVal, RHSVal);
+ else if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst))
+ return CmpInst::create(CIOp->getOpcode(), CIOp->getPredicate(), LHSVal,
+ RHSVal);
else if (ShiftInst *SI = dyn_cast<ShiftInst>(FirstInst))
return new ShiftInst(SI->getOpcode(), LHSVal, RHSVal);
else {
@@ -7198,9 +7517,10 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
bool isVolatile = false;
if (isa<CastInst>(FirstInst)) {
CastSrcTy = FirstInst->getOperand(0)->getType();
- } else if (isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst)) {
- // Can fold binop or shift here if the RHS is a constant, otherwise call
- // FoldPHIArgBinOpIntoPHI.
+ } else if (isa<BinaryOperator>(FirstInst) || isa<ShiftInst>(FirstInst) ||
+ isa<CmpInst>(FirstInst)) {
+ // Can fold binop, compare or shift here if the RHS is a constant,
+ // otherwise call FoldPHIArgBinOpIntoPHI.
ConstantOp = dyn_cast<Constant>(FirstInst->getOperand(1));
if (ConstantOp == 0)
return FoldPHIArgBinOpIntoPHI(PN);
@@ -7224,14 +7544,14 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
for (unsigned i = 1, e = PN.getNumIncomingValues(); i != e; ++i) {
if (!isa<Instruction>(PN.getIncomingValue(i))) return 0;
Instruction *I = cast<Instruction>(PN.getIncomingValue(i));
- if (!I->hasOneUse() || I->getOpcode() != FirstInst->getOpcode())
+ if (!I->hasOneUse() || !I->isSameOperationAs(FirstInst))
return 0;
if (CastSrcTy) {
if (I->getOperand(0)->getType() != CastSrcTy)
return 0; // Cast operation must match.
} else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
- // We can't sink the load if the loaded value could be modified between the
- // load and the PHI.
+ // We can't sink the load if the loaded value could be modified between
+ // the load and the PHI.
if (LI->isVolatile() != isVolatile ||
LI->getParent() != PN.getIncomingBlock(i) ||
!isSafeToSinkLoad(LI))
@@ -7276,6 +7596,9 @@ Instruction *InstCombiner::FoldPHIArgOpIntoPHI(PHINode &PN) {
return new LoadInst(PhiVal, "", isVolatile);
else if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(FirstInst))
return BinaryOperator::create(BinOp->getOpcode(), PhiVal, ConstantOp);
+ else if (CmpInst *CIOp = dyn_cast<CmpInst>(FirstInst))
+ return CmpInst::create(CIOp->getOpcode(), CIOp->getPredicate(),
+ PhiVal, ConstantOp);
else
return new ShiftInst(cast<ShiftInst>(FirstInst)->getOpcode(),
PhiVal, ConstantOp);
@@ -7380,11 +7703,9 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
}
} else if (SrcTy->getPrimitiveSize() < DestTy->getPrimitiveSize() &&
SrcTy->getPrimitiveSize() == 4) {
- // We can always eliminate a cast from int to [u]long. We can
- // eliminate a cast from uint to [u]long iff the target is a 32-bit
- // pointer target.
- if (SrcTy->isSigned() ||
- SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) {
+ // We can eliminate a cast from [u]int to [u]long iff the target
+ // is a 32-bit pointer target.
+ if (SrcTy->getPrimitiveSizeInBits() >= TD->getPointerSizeInBits()) {
MadeChange = true;
GEP.setOperand(i, Src);
}
@@ -7398,8 +7719,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
Value *Op = GEP.getOperand(i);
if (Op->getType()->getPrimitiveSize() > TD->getPointerSize())
if (Constant *C = dyn_cast<Constant>(Op)) {
- GEP.setOperand(i, ConstantExpr::getTrunc(C,
- TD->getIntPtrType()->getSignedVersion()));
+ GEP.setOperand(i, ConstantExpr::getTrunc(C, TD->getIntPtrType()));
MadeChange = true;
} else {
Op = InsertCastBefore(Instruction::Trunc, Op, TD->getIntPtrType(),
@@ -7407,7 +7727,6 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
GEP.setOperand(i, Op);
MadeChange = true;
}
-
// If this is a constant idx, make sure to canonicalize it to be a signed
// operand, otherwise CSE and other optimizations are pessimized.
if (ConstantInt *CUI = dyn_cast<ConstantInt>(Op))
@@ -7589,10 +7908,7 @@ Instruction *InstCombiner::visitGetElementPtrInst(GetElementPtrInst &GEP) {
isa<ConstantInt>(Inst->getOperand(1))) {
unsigned ShAmt =
cast<ConstantInt>(Inst->getOperand(1))->getZExtValue();
- if (Inst->getType()->isSigned())
- Scale = ConstantInt::get(Inst->getType(), 1ULL << ShAmt);
- else
- Scale = ConstantInt::get(Inst->getType(), 1ULL << ShAmt);
+ Scale = ConstantInt::get(Inst->getType(), 1ULL << ShAmt);
NewIdx = Inst->getOperand(0);
} else if (Inst->getOpcode() == Instruction::Mul &&
isa<ConstantInt>(Inst->getOperand(1))) {
@@ -8104,16 +8420,37 @@ Instruction *InstCombiner::visitBranchInst(BranchInst &BI) {
return &BI;
}
- // Cannonicalize setne -> seteq
- Instruction::BinaryOps Op; Value *Y;
- if (match(&BI, m_Br(m_SetCond(Op, m_Value(X), m_Value(Y)),
+ // Cannonicalize fcmp_one -> fcmp_oeq
+ FCmpInst::Predicate FPred; Value *Y;
+ if (match(&BI, m_Br(m_FCmp(FPred, m_Value(X), m_Value(Y)),
+ TrueDest, FalseDest)))
+ if ((FPred == FCmpInst::FCMP_ONE || FPred == FCmpInst::FCMP_OLE ||
+ FPred == FCmpInst::FCMP_OGE) && BI.getCondition()->hasOneUse()) {
+ FCmpInst *I = cast<FCmpInst>(BI.getCondition());
+ std::string Name = I->getName(); I->setName("");
+ FCmpInst::Predicate NewPred = FCmpInst::getInversePredicate(FPred);
+ Value *NewSCC = new FCmpInst(NewPred, X, Y, Name, I);
+ // Swap Destinations and condition...
+ BI.setCondition(NewSCC);
+ BI.setSuccessor(0, FalseDest);
+ BI.setSuccessor(1, TrueDest);
+ removeFromWorkList(I);
+ I->getParent()->getInstList().erase(I);
+ WorkList.push_back(cast<Instruction>(NewSCC));
+ return &BI;
+ }
+
+ // Cannonicalize icmp_ne -> icmp_eq
+ ICmpInst::Predicate IPred;
+ if (match(&BI, m_Br(m_ICmp(IPred, m_Value(X), m_Value(Y)),
TrueDest, FalseDest)))
- if ((Op == Instruction::SetNE || Op == Instruction::SetLE ||
- Op == Instruction::SetGE) && BI.getCondition()->hasOneUse()) {
- SetCondInst *I = cast<SetCondInst>(BI.getCondition());
+ if ((IPred == ICmpInst::ICMP_NE || IPred == ICmpInst::ICMP_ULE ||
+ IPred == ICmpInst::ICMP_SLE || IPred == ICmpInst::ICMP_UGE ||
+ IPred == ICmpInst::ICMP_SGE) && BI.getCondition()->hasOneUse()) {
+ ICmpInst *I = cast<ICmpInst>(BI.getCondition());
std::string Name = I->getName(); I->setName("");
- Instruction::BinaryOps NewOpcode = SetCondInst::getInverseCondition(Op);
- Value *NewSCC = BinaryOperator::create(NewOpcode, X, Y, Name, I);
+ ICmpInst::Predicate NewPred = ICmpInst::getInversePredicate(IPred);
+ Value *NewSCC = new ICmpInst(NewPred, X, Y, Name, I);
// Swap Destinations and condition...
BI.setCondition(NewSCC);
BI.setSuccessor(0, FalseDest);
@@ -8173,6 +8510,11 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
(CheapToScalarize(BO->getOperand(0), isConstant) ||
CheapToScalarize(BO->getOperand(1), isConstant)))
return true;
+ if (CmpInst *CI = dyn_cast<CmpInst>(I))
+ if (CI->hasOneUse() &&
+ (CheapToScalarize(CI->getOperand(0), isConstant) ||
+ CheapToScalarize(CI->getOperand(1), isConstant)))
+ return true;
return false;
}