1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 12:02:58 +02:00

[InstCombine] FoldICmpCstShrCst didn't handle icmps of -1 in the ashr case correctly

llvm-svn: 248073
This commit is contained in:
David Majnemer 2015-09-19 00:48:26 +00:00
parent bd7c6a697f
commit d15737b6a9

View File

@ -1074,18 +1074,22 @@ Instruction *InstCombiner::FoldICmpCstShrCst(ICmpInst &I, Value *Op, Value *A,
if (AP1 == AP2)
return getICmp(I.ICMP_EQ, A, ConstantInt::getNullValue(A->getType()));
// Get the distance between the highest bit that's set.
int Shift;
// 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();
Shift = AP1.countLeadingOnes() - AP2.countLeadingOnes();
else
Shift = AP2.logBase2() - AP1.logBase2();
Shift = AP1.countLeadingZeros() - AP2.countLeadingZeros();
if (Shift > 0) {
if (IsAShr ? AP1 == AP2.ashr(Shift) : AP1 == AP2.lshr(Shift))
if (IsAShr && AP1 == AP2.ashr(Shift)) {
// There are multiple solutions if we are comparing against -1 and the LHS
// of the ashr is not a power of two..
if (AP1.isAllOnesValue() && !AP2.isPowerOf2())
return getICmp(I.ICMP_UGE, A, ConstantInt::get(A->getType(), Shift));
return getICmp(I.ICMP_EQ, A, ConstantInt::get(A->getType(), Shift));
} else if (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);