[llvm] [InstCombine] Handle commuted cases of the fold `((B|C)&A)|B -> B|(A&C)` (PR #76565)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 29 05:50:17 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: Yingwei Zheng (dtcxzyw)
<details>
<summary>Changes</summary>
Alive2: https://alive2.llvm.org/ce/z/diGuxt
I found commit https://github.com/llvm/llvm-project/commit/f1eda235142ed071e219bd231310e44cda08f932 didn't handle other cases that commute operands when investigating issue https://github.com/llvm/llvm-project/issues/76554.
---
Full diff: https://github.com/llvm/llvm-project/pull/76565.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp (+5-1)
- (modified) llvm/test/Transforms/InstCombine/or.ll (+52-6)
``````````diff
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:
``````````
</details>
https://github.com/llvm/llvm-project/pull/76565
More information about the llvm-commits
mailing list