[PATCH] D132783: [InstCombine] add support for multi-use Y of (X op Y) op Z --> (Y op Z) op X

Chenbing.Zheng via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 28 19:47:50 PDT 2022


Chenbing.Zheng updated this revision to Diff 456228.
Chenbing.Zheng added a reviewer: bcl5980.
Chenbing.Zheng added a comment.

address comment


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132783

Files:
  llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
  llvm/test/Transforms/InstCombine/and-or-not.ll


Index: llvm/test/Transforms/InstCombine/and-or-not.ll
===================================================================
--- llvm/test/Transforms/InstCombine/and-or-not.ll
+++ llvm/test/Transforms/InstCombine/and-or-not.ll
@@ -747,12 +747,8 @@
 
 define i4 @simplify_and_common_op_use1(i4 %x, i4 %y, i4 %z)  {
 ; CHECK-LABEL: @simplify_and_common_op_use1(
-; CHECK-NEXT:    [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT:    call void @use(i4 [[Y]])
-; CHECK-NEXT:    [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
-; CHECK-NEXT:    [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
-; CHECK-NEXT:    [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
-; CHECK-NEXT:    ret i4 [[R]]
+; CHECK-NEXT:    call void @use(i4 [[Y:%.*]])
+; CHECK-NEXT:    ret i4 0
 ;
   %xy = or i4 %x, %y
   call void @use(i4 %y)
@@ -766,6 +762,25 @@
 
 define i4 @simplify_and_common_op_use2(i4 %x, i4 %y, i4 %z)  {
 ; CHECK-LABEL: @simplify_and_common_op_use2(
+; CHECK-NEXT:    call void @use(i4 [[Y:%.*]])
+; CHECK-NEXT:    [[TMP1:%.*]] = or i4 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT:    [[XYZ:%.*]] = or i4 [[TMP1]], [[Y]]
+; CHECK-NEXT:    [[NOT_XYZ:%.*]] = xor i4 [[XYZ]], -1
+; CHECK-NEXT:    [[R:%.*]] = and i4 [[NOT_XYZ]], [[X]]
+; CHECK-NEXT:    ret i4 [[R]]
+;
+  %xy = or i4 %y, %x
+  call void @use(i4 %y)
+  %xyz = or i4 %xy, %z
+  %not_xyz = xor i4 %xyz, -1
+  %r = and i4 %not_xyz, %x
+  ret i4 %r
+}
+
+; TODO: This should simplify.
+
+define i4 @simplify_and_common_op_use3(i4 %x, i4 %y, i4 %z)  {
+; CHECK-LABEL: @simplify_and_common_op_use3(
 ; CHECK-NEXT:    [[XY:%.*]] = or i4 [[X:%.*]], [[Y:%.*]]
 ; CHECK-NEXT:    [[XYZ:%.*]] = or i4 [[XY]], [[Z:%.*]]
 ; CHECK-NEXT:    call void @use(i4 [[Z]])
Index: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1752,15 +1752,19 @@
                                        InstCombinerImpl::BuilderTy &Builder) {
   Instruction::BinaryOps Opcode = BO.getOpcode();
   Value *X, *Y, *Z;
-  if (match(&BO, m_c_BinOp(Opcode,
-                           m_OneUse(m_c_BinOp(Opcode, m_Value(X),
-                                              m_OneUse(m_Value(Y)))),
-                           m_OneUse(m_Value(Z))))) {
+  if (match(&BO,
+            m_c_BinOp(Opcode, m_OneUse(m_BinOp(Opcode, m_Value(X), m_Value(Y))),
+                      m_OneUse(m_Value(Z))))) {
     // (X op Y) op Z --> (Y op Z) op X
-    if (!isa<Constant>(X) && !isa<Constant>(Y) && !isa<Constant>(Z) &&
-        !X->hasOneUse()) {
-      Value *YZ = Builder.CreateBinOp(Opcode, Y, Z);
-      return BinaryOperator::Create(Opcode, YZ, X);
+    if (!isa<Constant>(X) && !isa<Constant>(Y) && !isa<Constant>(Z)) {
+      if (!X->hasOneUse()) {
+        Value *YZ = Builder.CreateBinOp(Opcode, Y, Z);
+        return BinaryOperator::Create(Opcode, YZ, X);
+      }
+      if (!Y->hasOneUse()) {
+        Value *XZ = Builder.CreateBinOp(Opcode, X, Z);
+        return BinaryOperator::Create(Opcode, XZ, Y);
+      }
     }
   }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132783.456228.patch
Type: text/x-patch
Size: 3103 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220829/dce02986/attachment.bin>


More information about the llvm-commits mailing list