[PATCH] D140666: [InstCombine] combine intersection for inequality icmps

Yingchi Long via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 06:03:05 PST 2023


inclyc updated this revision to Diff 491739.
inclyc added a comment.

unmerge instcombine


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140666/new/

https://reviews.llvm.org/D140666

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/icmp-logical.ll


Index: llvm/test/Transforms/InstCombine/icmp-logical.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-logical.ll
+++ llvm/test/Transforms/InstCombine/icmp-logical.ll
@@ -280,11 +280,8 @@
 
 define i1 @masked_or_eq(i32 %A) {
 ; CHECK-LABEL: @masked_or_eq(
-; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 15
-; CHECK-NEXT:    [[TST1:%.*]] = icmp eq i32 [[MASK1]], 3
-; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A]], 255
-; CHECK-NEXT:    [[TST2:%.*]] = icmp eq i32 [[MASK2]], 243
-; CHECK-NEXT:    [[RES:%.*]] = or i1 [[TST1]], [[TST2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT:    [[RES:%.*]] = icmp eq i32 [[TMP1]], 3
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %mask1 = and i32 %A, 15 ; 0x0f
@@ -314,11 +311,8 @@
 
 define i1 @masked_and_ne(i32 %A) {
 ; CHECK-LABEL: @masked_and_ne(
-; CHECK-NEXT:    [[MASK1:%.*]] = and i32 [[A:%.*]], 15
-; CHECK-NEXT:    [[TST1:%.*]] = icmp ne i32 [[MASK1]], 3
-; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A]], 255
-; CHECK-NEXT:    [[TST2:%.*]] = icmp ne i32 [[MASK2]], 243
-; CHECK-NEXT:    [[RES:%.*]] = and i1 [[TST1]], [[TST2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[A:%.*]], 15
+; CHECK-NEXT:    [[RES:%.*]] = icmp ne i32 [[TMP1]], 3
 ; CHECK-NEXT:    ret i1 [[RES]]
 ;
   %mask1 = and i32 %A, 15 ; 0x0f
@@ -346,19 +340,6 @@
   ret i1 %res
 }
 
-define i1 @masked_and_expected_false(i32 %A) {
-; CHECK-LABEL: @masked_and_expected_false(
-; CHECK-NEXT:    [[MASK2:%.*]] = and i32 [[A:%.*]], 255
-; CHECK-NEXT:    [[TST2:%.*]] = icmp ne i32 [[MASK2]], 242
-; CHECK-NEXT:    ret i1 [[TST2]]
-;
-  %mask1 = and i32 %A, 3 ; 0x0f
-  %tst1 = icmp ne i32 %mask1, 15 ; 0x03
-  %mask2 = and i32 %A, 255 ; 0xff
-  %tst2 = icmp ne i32 %mask2, 242 ; 0xf2
-  %res = and i1 %tst1, %tst2
-  ret i1 %res
-}
 
 define i1 @nomask_lhs(i32 %in) {
 ; CHECK-LABEL: @nomask_lhs(
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -654,6 +654,42 @@
     return Builder.CreateICmp(NewCC, NewAnd, NewOr2);
   }
 
+  if (Mask & BMask_NotMixed) {
+    // Check the intersection (B & D) for inequality.
+    // Assume that (B & D) == B || (B & D) == D, i.e B/D is a subset of D/B
+    // and (B & D) & (C ^ E) == 0, bits of C and E, which are shared by both the
+    // B and the D, don't contradict.
+    // Note that we can assume (~B & C) == 0 && (~D & E) == 0, previous
+    // operation should delete these icmps if it hadn't been met.
+
+    // (icmp ne (A & B), C) & (icmp ne (A & D), E)
+    // -> (icmp ne (A & (B & D)), (C & E))
+
+    NewCC = CmpInst::getInversePredicate(NewCC);
+
+    const APInt *OldConstC, *OldConstE;
+    if (!match(C, m_APInt(OldConstC)) || !match(E, m_APInt(OldConstE)))
+      return nullptr;
+
+    const APInt ConstC = PredL != NewCC ? *ConstB ^ *OldConstC : *OldConstC;
+    const APInt ConstE = PredR != NewCC ? *ConstD ^ *OldConstE : *OldConstE;
+
+    const APInt ConstT = *ConstB & *ConstD;
+    if (ConstT != *ConstB && ConstT != *ConstD)
+      return nullptr;
+
+    assert((~*ConstB & ConstC) == 0);
+    assert((~*ConstD & ConstE) == 0);
+
+    // If there is a conflict, we still have to check both sides.
+    if (((*ConstB & *ConstD) & (ConstC ^ ConstE)).getBoolValue())
+      return nullptr;
+
+    Value *NewAnd1 = Builder.CreateAnd(B, D);
+    Value *NewAnd2 = Builder.CreateAnd(A, NewAnd1);
+    Value *NewAnd3 = ConstantInt::get(A->getType(), ConstC & ConstE);
+    return Builder.CreateICmp(NewCC, NewAnd2, NewAnd3);
+  }
   return nullptr;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D140666.491739.patch
Type: text/x-patch
Size: 3715 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230124/5e335714/attachment.bin>


More information about the llvm-commits mailing list