[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