[llvm] r248073 - [InstCombine] FoldICmpCstShrCst didn't handle icmps of -1 in the ashr case correctly
Nuno Lopes via llvm-commits
llvm-commits at lists.llvm.org
Sun Sep 20 04:45:17 PDT 2015
FWIW, I've verified this fix with Alive
(https://github.com/nunoplopes/alive/commit/a87e542f3e3f882cfefe39b1d4bd9ad5511d069d).
BTW, the first pattern can be relaxed a bit. This is sufficient:
Name: Compares:1088
Pre: (countLeadingOnes(C1) - countLeadingOnes(C2)) > 0 && C1 == -1 &&
!isPowerOf2(C2)
%s = ashr C2, %a
%i = icmp eq %s, C1
=>
%i = icmp uge %a, countLeadingOnes(C1) - countLeadingOnes(C2)
Nuno
-----Original Message-----
From: David Majnemer via llvm-commits
Sent: Saturday, September 19, 2015 1:48 AM
Subject: [llvm] r248073 - [InstCombine] FoldICmpCstShrCst didn't handle
icmps of -1 in the ashr case correctly
Author: majnemer
Date: Fri Sep 18 19:48:26 2015
New Revision: 248073
URL: http://llvm.org/viewvc/llvm-project?rev=248073&view=rev
Log:
[InstCombine] FoldICmpCstShrCst didn't handle icmps of -1 in the ashr case
correctly
Modified:
llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp
URL:
http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp?rev=248073&r1=248072&r2=248073&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp (original)
+++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCompares.cpp Fri Sep 18
19:48:26 2015
@@ -1074,18 +1074,22 @@ Instruction *InstCombiner::FoldICmpCstSh
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);
More information about the llvm-commits
mailing list