[PATCH] D128790: [InstCombine] improve fold for icmp_eq_and to icmp_ult

Chenbing.Zheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 29 01:51:33 PDT 2022


Chenbing.Zheng created this revision.
Chenbing.Zheng added reviewers: spatel, RKSimon, benshi001.
Chenbing.Zheng added a project: LLVM.
Herald added a subscriber: hiraditya.
Herald added a project: All.
Chenbing.Zheng requested review of this revision.
Herald added subscribers: llvm-commits, jacquesguan.

In D95959 <https://reviews.llvm.org/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.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128790

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


Index: llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
===================================================================
--- llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
+++ llvm/test/Transforms/InstCombine/lshr-and-negC-icmpeq-zero.ll
@@ -177,15 +177,10 @@
   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,10 @@
   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 ult i32 [[LSHR]], 8
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %lshr = lshr i32 268435456, %y
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1767,11 +1767,19 @@
       return new ICmpInst(NewPred, X, Zero);
     }
 
+    const APInt *C3;
+    APInt newC2 = *C2;
+    // If if one of And's operands is lshr, ValueTracking will simplify the
+    // other constant of 'And'. It will break the fold below.
+    if (match(And->getOperand(0), m_LShr(m_APInt(C3), m_Value()))) {
+      newC2 = *C2 +
+              APInt::getHighBitsSet(C2->getBitWidth(), C3->countLeadingZeros());
+    }
+
     // Restrict this fold only for single-use 'and' (PR10267).
     // ((%x & C) == 0) --> %x u< (-C)  iff (-C) is power of two.
-    if ((~(*C2) + 1).isPowerOf2()) {
-      Constant *NegBOC =
-          ConstantExpr::getNeg(cast<Constant>(And->getOperand(1)));
+    if ((~(newC2) + 1).isPowerOf2()) {
+      Constant *NegBOC = ConstantInt::get(And->getType(), -newC2);
       auto NewPred = isICMP_NE ? ICmpInst::ICMP_UGE : ICmpInst::ICMP_ULT;
       return new ICmpInst(NewPred, X, NegBOC);
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128790.440893.patch
Type: text/x-patch
Size: 2508 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220629/cc845e04/attachment.bin>


More information about the llvm-commits mailing list