[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