[llvm] b43dd2f - [InstCombine] improve fold for icmp_eq_and to icmp_ult

Chenbing Zheng via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 5 02:18:41 PDT 2022


Author: Chenbing Zheng
Date: 2022-07-05T17:18:23+08:00
New Revision: b43dd2f6c4a370f11a386dde73ad9bb51a0b6b5c

URL: https://github.com/llvm/llvm-project/commit/b43dd2f6c4a370f11a386dde73ad9bb51a0b6b5c
DIFF: https://github.com/llvm/llvm-project/commit/b43dd2f6c4a370f11a386dde73ad9bb51a0b6b5c.diff

LOG: [InstCombine] improve fold for icmp_eq_and to icmp_ult

In D95959, the improve analysis for "C >> X" broken the fold
((%x & C) == 0) --> %x u< (-C) iff (-C) is power of two.

It simplifies C, but fails to satisfy the fold condition.
This patch try to restore C before the fold.

Reviewed By: spatel

Differential Revision: https://reviews.llvm.org/D128790

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 49951d19b0c3..acfab42d957d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1777,11 +1777,16 @@ Instruction *InstCombinerImpl::foldICmpAndConstConst(ICmpInst &Cmp,
       return new ICmpInst(NewPred, X, Zero);
     }
 
+    APInt NewC2 = *C2;
+    KnownBits Know = computeKnownBits(And->getOperand(0), 0, And);
+    // Set high zeros of C2 to allow matching negated power-of-2.
+    NewC2 = *C2 + APInt::getHighBitsSet(C2->getBitWidth(),
+                                        Know.countMinLeadingZeros());
+
     // Restrict this fold only for single-use 'and' (PR10267).
     // ((%x & C) == 0) --> %x u< (-C)  iff (-C) is power of two.
-    if (C2->isNegatedPowerOf2()) {
-      Constant *NegBOC =
-          ConstantExpr::getNeg(cast<Constant>(And->getOperand(1)));
+    if (NewC2.isNegatedPowerOf2()) {
+      Constant *NegBOC = ConstantInt::get(And->getType(), -NewC2);
       auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
       return new ICmpInst(NewPred, X, NegBOC);
     }

diff  --git a/llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll b/llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
index 0b4d6c7f0781..9f9cbb4a26a8 100644
--- a/llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
+++ b/llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
@@ -177,15 +177,10 @@ define i1 @scalar_lshr_and_negC_eq_extra_use_lshr_and(i32 %x, i32 %y, i32 %z, i3
   ret i1 %r
 }
 
-; Negative tests
-
-; TODO: This could be reduced to lshr+icmp ult.
-
 define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant1(i32 %y) {
 ; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant1(
 ; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 12345, [[Y:%.*]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], 16376
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[LSHR]], 8
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %lshr = lshr i32 12345, %y
@@ -194,13 +189,9 @@ define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant1(i32 %y) {
   ret i1 %r
 }
 
-; TODO: This could be reduced to lshr+icmp ult.
-
 define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) {
 ; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant2(
-; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 268435456, [[Y:%.*]]
-; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], 536870904
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT:    [[R:%.*]] = icmp ugt i32 [[Y:%.*]], 25
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %lshr = lshr i32 268435456, %y
@@ -208,7 +199,31 @@ define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant2(i32 %y) {
   %r = icmp eq i32 %and, 0
   ret i1 %r
 }
+define i1 @scalar_i32_udiv_and_negC_eq_X_is_constant3(i32 %y) {
+; CHECK-LABEL: @scalar_i32_udiv_and_negC_eq_X_is_constant3(
+; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y:%.*]], 1544
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %lshr = udiv  i32 12345, %y
+  %and = and i32 %lshr, 16376    ; 0x3ff8
+  %r = icmp ne i32 %and, 0
+  ret i1 %r
+}
+
+; Negative test
 
+define i1 @scalar_i32_lshr_and_negC_eq_X_is_constant_negtive(i32 %y) {
+; CHECK-LABEL: @scalar_i32_lshr_and_negC_eq_X_is_constant_negtive(
+; CHECK-NEXT:    [[LSHR:%.*]] = lshr i32 16384, [[Y:%.*]]
+; CHECK-NEXT:    [[AND:%.*]] = and i32 [[LSHR]], 16376
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[AND]], 0
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %lshr = lshr i32 16384, %y    ; 0x4000
+  %and = and i32 %lshr, 16376   ; 0x3ff8
+  %r = icmp eq i32 %and, 0
+  ret i1 %r
+}
 ; Check 'slt' predicate
 
 define i1 @scalar_i32_lshr_and_negC_slt(i32 %x, i32 %y) {


        


More information about the llvm-commits mailing list