-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[InstCombine] Handle commuted cases of the fold ((B|C)&A)|B -> B|(A&C)
#76565
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesAlive2: https://alive2.llvm.org/ce/z/diGuxt I found commit f1eda23 didn't handle other cases that commute operands when investigating issue #76554. Full diff: https://github.com/llvm/llvm-project/pull/76565.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 6958418ba7f3fa..1168cca12fb44c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3513,9 +3513,13 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
return BinaryOperator::CreateOr(Op0, C);
// ((B | C) & A) | B -> B | (A & C)
- if (match(Op0, m_And(m_Or(m_Specific(Op1), m_Value(C)), m_Value(A))))
+ if (match(Op0, m_c_And(m_c_Or(m_Specific(Op1), m_Value(C)), m_Value(A))))
return BinaryOperator::CreateOr(Op1, Builder.CreateAnd(A, C));
+ // B | ((B | C) & A) -> B | (A & C)
+ if (match(Op1, m_c_And(m_c_Or(m_Specific(Op0), m_Value(C)), m_Value(A))))
+ return BinaryOperator::CreateOr(Op0, Builder.CreateAnd(A, C));
+
if (Instruction *DeMorgan = matchDeMorgansLaws(I, *this))
return DeMorgan;
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index 010ef239744188..573a11599141a7 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -753,6 +753,52 @@ define i32 @test45(i32 %x, i32 %y, i32 %z) {
ret i32 %or1
}
+define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @test45_commuted1(
+; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[OR1]]
+;
+ %yy = mul i32 %y, %y ; thwart complexity-based ordering
+ %or = or i32 %yy, %z
+ %and = and i32 %or, %x
+ %or1 = or i32 %yy, %and
+ ret i32 %or1
+}
+
+define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @test45_commuted2(
+; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
+; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[OR1]]
+;
+ %yy = mul i32 %y, %y ; thwart complexity-based ordering
+ %xx = mul i32 %x, %x ; thwart complexity-based ordering
+ %or = or i32 %yy, %z
+ %and = and i32 %xx, %or
+ %or1 = or i32 %and, %yy
+ ret i32 %or1
+}
+
+define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: @test45_commuted3(
+; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
+; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
+; CHECK-NEXT: ret i32 [[OR1]]
+;
+ %yy = mul i32 %y, %y ; thwart complexity-based ordering
+ %zz = mul i32 %z, %z ; thwart complexity-based ordering
+ %or = or i32 %zz, %yy
+ %and = and i32 %or, %x
+ %or1 = or i32 %and, %yy
+ ret i32 %or1
+}
+
define i1 @test46(i8 signext %c) {
; CHECK-LABEL: @test46(
; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[C:%.*]], -33
@@ -1213,11 +1259,11 @@ define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
; CHECK: true:
-; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
-; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
+; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
; CHECK-NEXT: br label [[END]]
; CHECK: end:
-; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
+; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
; CHECK-NEXT: ret i32 [[T5]]
;
entry:
@@ -1245,11 +1291,11 @@ define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
; CHECK-NEXT: entry:
; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
; CHECK: true:
-; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
-; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
+; CHECK-NEXT: [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
; CHECK-NEXT: br label [[END]]
; CHECK: end:
-; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
+; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
; CHECK-NEXT: ret i32 [[T5]]
;
entry:
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
026f221
to
e71ceaa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Alive2: https://alive2.llvm.org/ce/z/Qdsqk6
I found commit f1eda23 didn't handle other cases that commute operands when investigating issue #76554.