Skip to content

Commit 3a8c2c1

Browse files
author
Suyog Sarda
committedJul 22, 2014
This patch implements optimization as mentioned in PR19753: Optimize comparisons with "ashr/lshr exact" of a constanst.
It handles the errors which were seen in PR19958 where wrong code was being emitted due to earlier patch. Added code for lshr as well as non-exact right shifts. It implements : (icmp eq/ne (ashr/lshr const2, A), const1)" -> (icmp eq/ne A, Log2(const2/const1)) -> (icmp eq/ne A, Log2(const2) - Log2(const1)) Differential Revision: http://reviews.llvm.org/D4068 llvm-svn: 213678
1 parent b60ec90 commit 3a8c2c1

File tree

3 files changed

+772
-0
lines changed

3 files changed

+772
-0
lines changed
 

‎llvm/lib/Transforms/InstCombine/InstCombine.h

+2
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ class LLVM_LIBRARY_VISIBILITY InstCombiner
172172
ConstantInt *DivRHS);
173173
Instruction *FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *DivI,
174174
ConstantInt *DivRHS);
175+
Instruction *FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
176+
ConstantInt *CI1, ConstantInt *CI2);
175177
Instruction *FoldICmpAddOpCst(Instruction &ICI, Value *X, ConstantInt *CI,
176178
ICmpInst::Predicate Pred);
177179
Instruction *FoldGEPICmp(GEPOperator *GEPLHS, Value *RHS,

‎llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

+93
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,90 @@ Instruction *InstCombiner::FoldICmpShrCst(ICmpInst &ICI, BinaryOperator *Shr,
10441044
return nullptr;
10451045
}
10461046

1047+
/// FoldICmpCstShrCst - Handle "(icmp eq/ne (ashr/lshr const2, A), const1)" ->
1048+
/// (icmp eq/ne A, Log2(const2/const1)) ->
1049+
/// (icmp eq/ne A, Log2(const2) - Log2(const1)).
1050+
Instruction *InstCombiner::FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
1051+
ConstantInt *CI1,
1052+
ConstantInt *CI2) {
1053+
assert(I.isEquality() && "Cannot fold icmp gt/lt");
1054+
1055+
auto getConstant = [&I, this](bool IsTrue) {
1056+
if (I.getPredicate() == I.ICMP_NE)
1057+
IsTrue = !IsTrue;
1058+
return ReplaceInstUsesWith(I, ConstantInt::get(I.getType(), IsTrue));
1059+
};
1060+
1061+
auto getICmp = [&I](CmpInst::Predicate Pred, Value *LHS, Value *RHS) {
1062+
if (I.getPredicate() == I.ICMP_NE)
1063+
Pred = CmpInst::getInversePredicate(Pred);
1064+
return new ICmpInst(Pred, LHS, RHS);
1065+
};
1066+
1067+
APInt AP1 = CI1->getValue();
1068+
APInt AP2 = CI2->getValue();
1069+
1070+
if (!AP1) {
1071+
if (!AP2) {
1072+
// Both Constants are 0.
1073+
return getConstant(true);
1074+
}
1075+
1076+
if (cast<BinaryOperator>(Op)->isExact())
1077+
return getConstant(false);
1078+
1079+
if (AP2.isNegative()) {
1080+
// MSB is set, so a lshr with a large enough 'A' would be undefined.
1081+
return getConstant(false);
1082+
}
1083+
1084+
// 'A' must be large enough to shift out the highest set bit.
1085+
return getICmp(I.ICMP_UGT, A,
1086+
ConstantInt::get(A->getType(), AP2.logBase2()));
1087+
}
1088+
1089+
if (!AP2) {
1090+
// Shifting 0 by any value gives 0.
1091+
return getConstant(false);
1092+
}
1093+
1094+
bool IsAShr = isa<AShrOperator>(Op);
1095+
if (AP1 == AP2) {
1096+
if (AP1.isAllOnesValue() && IsAShr) {
1097+
// Arithmatic shift of -1 is always -1.
1098+
return getConstant(true);
1099+
}
1100+
return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType()));
1101+
}
1102+
1103+
if (IsAShr) {
1104+
if (AP1.isNegative() != AP2.isNegative()) {
1105+
// Arithmetic shift will never change the sign.
1106+
return getConstant(false);
1107+
}
1108+
// Both the constants are negative, take their positive to calculate
1109+
// log.
1110+
if (AP1.isNegative()) {
1111+
AP1 = -AP1;
1112+
AP2 = -AP2;
1113+
}
1114+
}
1115+
1116+
if (AP1.ugt(AP2)) {
1117+
// Right-shifting will not increase the value.
1118+
return getConstant(false);
1119+
}
1120+
1121+
// Get the distance between the highest bit that's set.
1122+
int Shift = AP2.logBase2() - AP1.logBase2();
1123+
1124+
// Use lshr here, since we've canonicalized to +ve numbers.
1125+
if (AP1 == AP2.lshr(Shift))
1126+
return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
1127+
1128+
// Shifting const2 will never be equal to const1.
1129+
return getConstant(false);
1130+
}
10471131

10481132
/// visitICmpInstWithInstAndIntCst - Handle "icmp (instr, intcst)".
10491133
///
@@ -2469,6 +2553,15 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) {
24692553
Builder->getInt(CI->getValue()-1));
24702554
}
24712555

2556+
// (icmp eq/ne (ashr/lshr const2, A), const1)
2557+
if (I.isEquality()) {
2558+
ConstantInt *CI2;
2559+
if (match(Op0, m_AShr(m_ConstantInt(CI2), m_Value(A))) ||
2560+
match(Op0, m_LShr(m_ConstantInt(CI2), m_Value(A)))) {
2561+
return FoldICmpCstShrCst(I, Op0, A, CI, CI2);
2562+
}
2563+
}
2564+
24722565
// If this comparison is a normal comparison, it demands all
24732566
// bits, if it is a sign bit comparison, it only demands the sign bit.
24742567
bool UnusedBit;

0 commit comments

Comments
 (0)
Please sign in to comment.