[PATCH] D154139: [InstCombine] Transform `(icmp eq/ne (or x, C), x)` -> `(icmp eq/ne (and x, C), C)`

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 29 12:50:44 PDT 2023


goldstein.w.n created this revision.
goldstein.w.n added reviewers: nikic, spatel, RKSimon.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
goldstein.w.n requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This eliminates a use on `x` which can enable other transforms. As
well `and` is often easier to analyze than `or`.

Proof (note constants are always noundef): https://alive2.llvm.org/ce/z/N4CcaK


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154139

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
  llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll


Index: llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
===================================================================
--- llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
+++ llvm/test/Transforms/InstCombine/icmp-or-x-with-x.ll
@@ -5,8 +5,8 @@
 define i1 @fold_or_eq(i8 %x) {
 ; CHECK-LABEL: define i1 @fold_or_eq
 ; CHECK-SAME: (i8 [[X:%.*]]) {
-; CHECK-NEXT:    [[XO:%.*]] = or i8 [[X]], 123
-; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[XO]], [[X]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X]], 123
+; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 123
 ; CHECK-NEXT:    ret i1 [[R]]
 ;
   %xo = or i8 %x, 123
@@ -18,8 +18,8 @@
 ; CHECK-LABEL: define <2 x i1> @fold_or_ne
 ; CHECK-SAME: (<2 x i8> [[XX:%.*]]) {
 ; CHECK-NEXT:    [[X:%.*]] = mul <2 x i8> [[XX]], [[XX]]
-; CHECK-NEXT:    [[XO:%.*]] = or <2 x i8> [[X]], <i8 123, i8 12>
-; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[X]], [[XO]]
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[X]], <i8 123, i8 12>
+; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], <i8 123, i8 12>
 ; CHECK-NEXT:    ret <2 x i1> [[R]]
 ;
   %x = mul <2 x i8> %xx, %xx
Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4878,17 +4878,27 @@
   // canoncalize:
   // (icmp eq/ne (and X, C), X)
   //    -> (icmp eq/ne (and X, ~C), 0)
-  {
+  // (icmp eq/ne (or X, C), X)
+  //    -> (icmp eq/ne (and X, C), C)
+  auto SimplifyBitwiseAndOrBitwiseOr =
+      [this, Pred](Value *BitwiseOp, Value *Operand) -> Instruction * {
     Constant *CMask;
-    A = nullptr;
-    if (match(Op0, m_OneUse(m_And(m_Specific(Op1), m_ImmConstant(CMask)))))
-      A = Op1;
-    else if (match(Op1, m_OneUse(m_And(m_Specific(Op0), m_ImmConstant(CMask)))))
-      A = Op0;
-    if (A)
-      return new ICmpInst(Pred, Builder.CreateAnd(A, Builder.CreateNot(CMask)),
-                          Constant::getNullValue(A->getType()));
-  }
+    if (!BitwiseOp->hasOneUse())
+      return nullptr;
+
+    if (match(BitwiseOp, m_And(m_Specific(Operand), m_ImmConstant(CMask))))
+      return new ICmpInst(Pred,
+                          Builder.CreateAnd(Operand, Builder.CreateNot(CMask)),
+                          Constant::getNullValue(Operand->getType()));
+    if (match(BitwiseOp, m_Or(m_Specific(Operand), m_ImmConstant(CMask))))
+      return new ICmpInst(Pred, Builder.CreateAnd(Operand, CMask), CMask);
+    return nullptr;
+  };
+
+  if (Instruction *R = SimplifyBitwiseAndOrBitwiseOr(Op0, Op1))
+    return R;
+  if (Instruction *R = SimplifyBitwiseAndOrBitwiseOr(Op1, Op0))
+    return R;
 
   if (match(Op1, m_Xor(m_Value(A), m_Value(B))) && (A == Op0 || B == Op0)) {
     // A == (A^B)  ->  B == 0


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154139.535962.patch
Type: text/x-patch
Size: 2849 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230629/90f8d8d9/attachment.bin>


More information about the llvm-commits mailing list