[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
Sat Aug 27 00:41:26 PDT 2022


Chenbing.Zheng created this revision.
Chenbing.Zheng added reviewers: spatel, craig.topper, RKSimon, benshi001.
Chenbing.Zheng added a project: LLVM.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
Chenbing.Zheng requested review of this revision.
Herald added subscribers: llvm-commits, jacquesguan.

For (X op Y) op Z --> (Y op Z) op X
we can still do transform when Y is multi-use. In D131356 <https://reviews.llvm.org/D131356>
limit it to one-use, this patch remove this limit.

This is still not a  complete solution, I add a todo test to show it.
In this case, X and Y are both multi use, we can't differentiate how to convert based on this.
But, At least the branch we added won't make the code worse,and it solves half the scenarios


Repository:
  rG LLVM Github Monorepo

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
@@ -1753,14 +1753,18 @@
   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_c_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.456085.patch
Type: text/x-patch
Size: 2955 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220827/73be1cdb/attachment.bin>


More information about the llvm-commits mailing list