[llvm] 6d83962 - [InstCombine] Canonicalize (A & B_Pow2) eq/ne B_Pow2 patterns

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 9 03:48:36 PST 2023


Author: Noah Goldstein
Date: 2023-01-09T12:48:28+01:00
New Revision: 6d839621da8d0d85552c741c4c72369b4ada97c4

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

LOG: [InstCombine] Canonicalize (A & B_Pow2) eq/ne B_Pow2 patterns

1. A & B_Pow2 != B_Pow2 -> A & B_Pow2 == 0
   https://alive2.llvm.org/ce/z/KVUej4

2. A & B_Pow2 == B_Pow2 -> A & B_Pow2 != 0
   https://alive2.llvm.org/ce/z/PVv9FR

This allows the patterns to more easily be analyzed elsewhere.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/icmp-and-shift.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index 587700216008..1fcc78f8fa9e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4783,6 +4783,20 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
                         Add, ConstantInt::get(A->getType(), C.shl(1)));
   }
 
+  // Canonicalize:
+  // Assume B_Pow2 != 0
+  // 1. A & B_Pow2 != B_Pow2 -> A & B_Pow2 == 0
+  // 2. A & B_Pow2 == B_Pow2 -> A & B_Pow2 != 0
+  if (match(Op0, m_c_And(m_Specific(Op1), m_Value())) &&
+      isKnownToBeAPowerOfTwo(Op1, /* OrZero */ false, 0, &I))
+    return new ICmpInst(CmpInst::getInversePredicate(Pred), Op0,
+                        ConstantInt::getNullValue(Op0->getType()));
+
+  if (match(Op1, m_c_And(m_Specific(Op0), m_Value())) &&
+      isKnownToBeAPowerOfTwo(Op0, /* OrZero */ false, 0, &I))
+    return new ICmpInst(CmpInst::getInversePredicate(Pred), Op1,
+                        ConstantInt::getNullValue(Op1->getType()));
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
index 8dab225ce528..f9a4ec67b77e 100644
--- a/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-and-shift.ll
@@ -437,7 +437,7 @@ define i1 @eq_and_shl_one(i8 %x, i8 %y) {
 ; CHECK-LABEL: @eq_and_shl_one(
 ; CHECK-NEXT:    [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[POW2]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[AND]], [[POW2]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %pow2 = shl i8 1, %y
@@ -450,7 +450,7 @@ define <2 x i1> @ne_and_shl_one_commute(<2 x i8> %x, <2 x i8> %y) {
 ; CHECK-LABEL: @ne_and_shl_one_commute(
 ; CHECK-NEXT:    [[POW2:%.*]] = shl nuw <2 x i8> <i8 1, i8 poison>, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and <2 x i8> [[POW2]], [[X:%.*]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[POW2]], [[AND]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[AND]], zeroinitializer
 ; CHECK-NEXT:    ret <2 x i1> [[CMP]]
 ;
   %pow2 = shl <2 x i8> <i8 1, i8 poison>, %y
@@ -464,7 +464,7 @@ define i1 @ne_and_lshr_minval(i8 %px, i8 %y) {
 ; CHECK-NEXT:    [[X:%.*]] = mul i8 [[PX:%.*]], [[PX]]
 ; CHECK-NEXT:    [[POW2:%.*]] = lshr i8 -128, [[Y:%.*]]
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[POW2]]
-; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], [[POW2]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %x = mul i8 %px, %px ; thwart complexity-based canonicalization
@@ -481,7 +481,7 @@ define i1 @eq_and_lshr_minval_commute(i8 %px, i8 %y) {
 ; CHECK-NEXT:    call void @use(i8 [[POW2]])
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[X]], [[POW2]]
 ; CHECK-NEXT:    call void @use(i8 [[AND]])
-; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[POW2]], [[AND]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[AND]], 0
 ; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %x = mul i8 %px, %px ; thwart complexity-based canonicalization
@@ -493,6 +493,7 @@ define i1 @eq_and_lshr_minval_commute(i8 %px, i8 %y) {
   ret i1 %cmp
 }
 
+; Negative test: May be power of two or zero.
 define i1 @eq_and_shl_two(i8 %x, i8 %y) {
 ; CHECK-LABEL: @eq_and_shl_two(
 ; CHECK-NEXT:    [[POW2_OR_ZERO:%.*]] = shl i8 2, [[Y:%.*]]
@@ -506,6 +507,7 @@ define i1 @eq_and_shl_two(i8 %x, i8 %y) {
   ret i1 %cmp
 }
 
+; Negative test: Wrong predicate.
 define i1 @slt_and_shl_one(i8 %x, i8 %y) {
 ; CHECK-LABEL: @slt_and_shl_one(
 ; CHECK-NEXT:    [[POW2:%.*]] = shl nuw i8 1, [[Y:%.*]]


        


More information about the llvm-commits mailing list