[PATCH] D31712: [InstCombine] add icmp fold with or mask of low bits (PR32542)

Sanjay Patel via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 5 09:47:15 PDT 2017


spatel created this revision.
Herald added a subscriber: mcrosier.

We already have these 'and' folds:

  // X & -C == -C -> X >  u ~C
  // X & -C != -C -> X <= u ~C
  //   iff C is a power of 2

...but we were missing the 'or' siblings.

http://rise4fun.com/Alive/n6

This should improve:
https://bugs.llvm.org/show_bug.cgi?id=32524
...but there are 2 or more other pieces to fix still.


https://reviews.llvm.org/D31712

Files:
  lib/Transforms/InstCombine/InstCombineCompares.cpp
  test/Transforms/InstCombine/icmp.ll


Index: test/Transforms/InstCombine/icmp.ll
===================================================================
--- test/Transforms/InstCombine/icmp.ll
+++ test/Transforms/InstCombine/icmp.ll
@@ -1876,12 +1876,12 @@
   ret <2 x i1> %cmp
 }
 
+; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
 ; X | C == C --> X <=u C (when C+1 is PowerOf2).
 
 define i1 @or1_eq1(i32 %x) {
 ; CHECK-LABEL: @or1_eq1(
-; CHECK-NEXT:    [[T0:%.*]] = or i32 %x, 1
-; CHECK-NEXT:    [[T1:%.*]] = icmp eq i32 [[T0]], 1
+; CHECK-NEXT:    [[T1:%.*]] = icmp ult i32 %x, 2
 ; CHECK-NEXT:    ret i1 [[T1]]
 ;
   %t0 = or i32 %x, 1
@@ -1893,8 +1893,7 @@
 
 define <2 x i1> @or3_eq3_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @or3_eq3_vec(
-; CHECK-NEXT:    [[T0:%.*]] = or <2 x i8> %x, <i8 3, i8 3>
-; CHECK-NEXT:    [[T1:%.*]] = icmp eq <2 x i8> [[T0]], <i8 3, i8 3>
+; CHECK-NEXT:    [[T1:%.*]] = icmp ult <2 x i8> %x, <i8 4, i8 4>
 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
 ;
   %t0 = or <2 x i8> %x, <i8 3, i8 3>
@@ -1906,8 +1905,7 @@
 
 define i1 @or7_ne7(i32 %x) {
 ; CHECK-LABEL: @or7_ne7(
-; CHECK-NEXT:    [[T0:%.*]] = or i32 %x, 7
-; CHECK-NEXT:    [[T1:%.*]] = icmp ne i32 [[T0]], 7
+; CHECK-NEXT:    [[T1:%.*]] = icmp ugt i32 %x, 7
 ; CHECK-NEXT:    ret i1 [[T1]]
 ;
   %t0 = or i32 %x, 7
@@ -1919,8 +1917,7 @@
 
 define <2 x i1> @or63_ne63_vec(<2 x i8> %x) {
 ; CHECK-LABEL: @or63_ne63_vec(
-; CHECK-NEXT:    [[T0:%.*]] = or <2 x i8> %x, <i8 63, i8 63>
-; CHECK-NEXT:    [[T1:%.*]] = icmp ne <2 x i8> [[T0]], <i8 63, i8 63>
+; CHECK-NEXT:    [[T1:%.*]] = icmp ugt <2 x i8> %x, <i8 63, i8 63>
 ; CHECK-NEXT:    ret <2 x i1> [[T1]]
 ;
   %t0 = or <2 x i8> %x, <i8 63, i8 63>
Index: lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1794,6 +1794,15 @@
                           ConstantInt::get(V->getType(), 1));
   }
 
+  // X | C == C --> X <=u C
+  // X | C != C --> X  >u C
+  //   iff C+1 is a power of 2 (C is a bitmask of the low bits)
+  if (Cmp.isEquality() && Cmp.getOperand(1) == Or->getOperand(1) &&
+      (*C + 1).isPowerOf2()) {
+    Pred = (Pred == CmpInst::ICMP_EQ) ? CmpInst::ICMP_ULE : CmpInst::ICMP_UGT;
+    return new ICmpInst(Pred, Or->getOperand(0), Or->getOperand(1));
+  }
+
   if (!Cmp.isEquality() || *C != 0 || !Or->hasOneUse())
     return nullptr;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D31712.94248.patch
Type: text/x-patch
Size: 2441 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170405/1f7a4634/attachment.bin>


More information about the llvm-commits mailing list