summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp64
1 files changed, 16 insertions, 48 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index fec51aa5ec6..2be03bd7f04 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1052,69 +1052,37 @@ Instruction *InstCombiner::FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
APInt AP1 = CI1->getValue();
APInt AP2 = CI2->getValue();
- if (!AP1) {
- if (!AP2) {
- // Both Constants are 0.
- return getConstant(true);
- }
-
- if (cast<BinaryOperator>(Op)->isExact())
- return getConstant(false);
-
- if (AP2.isNegative()) {
- // MSB is set, so a lshr with a large enough 'A' would be undefined.
- return getConstant(false);
- }
+ assert(AP2 != 0 && "Handled in InstSimplify");
+ assert(!AP2.isAllOnesValue() && "Handled in InstSimplify");
+ if (!AP1)
// 'A' must be large enough to shift out the highest set bit.
return getICmp(I.ICMP_UGT, A,
ConstantInt::get(A->getType(), AP2.logBase2()));
- }
-
- if (!AP2) {
- // Shifting 0 by any value gives 0.
- return getConstant(false);
- }
- bool IsAShr = isa<AShrOperator>(Op);
- if (AP1 == AP2) {
- if (AP1.isAllOnesValue() && IsAShr) {
- // Arithmatic shift of -1 is always -1.
- return getConstant(true);
- }
+ if (AP1 == AP2)
return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType()));
- }
-
- bool IsNegative = false;
- if (IsAShr) {
- if (AP1.isNegative() != AP2.isNegative()) {
- // Arithmetic shift will never change the sign.
- return getConstant(false);
- }
- // Both the constants are negative, take their positive to calculate log.
- if (AP1.isNegative()) {
- if (AP1.slt(AP2))
- // Right-shifting won't increase the magnitude.
- return getConstant(false);
- IsNegative = true;
- }
- }
- if (!IsNegative && AP1.ugt(AP2))
- // Right-shifting will not increase the value.
- return getConstant(false);
+ bool IsAShr = isa<AShrOperator>(Op);
+ // If we are dealing with an arithmetic shift, both constants should agree in
+ // sign. InstSimplify's SimplifyICmpInst range analysis is supposed to catch
+ // the cases when they disagree.
+ assert((!IsAShr || (AP1.isNegative() == AP2.isNegative() && AP1.sgt(AP2))) &&
+ "Handled in InstSimplify");
// Get the distance between the highest bit that's set.
int Shift;
- if (IsNegative)
+ // Both the constants are negative, take their positive to calculate log.
+ if (IsAShr && AP1.isNegative())
// Get the ones' complement of AP2 and AP1 when computing the distance.
Shift = (~AP2).logBase2() - (~AP1).logBase2();
else
Shift = AP2.logBase2() - AP1.logBase2();
- if (IsAShr ? AP1 == AP2.ashr(Shift) : AP1 == AP2.lshr(Shift))
- return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
-
+ if (Shift > 0) {
+ if (IsAShr ? AP1 == AP2.ashr(Shift) : AP1 == AP2.lshr(Shift))
+ return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
+ }
// Shifting const2 will never be equal to const1.
return getConstant(false);
}
OpenPOWER on IntegriCloud