[llvm] [InstCombine] Handle commuted cases of the fold `((B|C)&A)|B -> B|(A&C)` (PR #76565)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 29 05:49:51 PST 2023
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/76565
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.
>From a89a9e213842d5b5934e86a0e3b14b5ec8562221 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 29 Dec 2023 21:33:31 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/or.ll | 61 +++++++++++++++++++++++---
1 file changed, 55 insertions(+), 6 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll
index 010ef239744188..af9e6ce2839b2d 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -753,6 +753,55 @@ 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: [[OR:%.*]] = or i32 [[YY]], [[Z:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR]], [[X:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[AND]]
+; 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: [[OR:%.*]] = or i32 [[YY]], [[Z:%.*]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[XX]], [[OR]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[YY]]
+; 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: [[OR:%.*]] = or i32 [[ZZ]], [[YY]]
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR]], [[X:%.*]]
+; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[YY]]
+; 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 +1262,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 +1294,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:
>From 026f221761edec4070b3ac26dac9497ee3591309 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Fri, 29 Dec 2023 21:44:15 +0800
Subject: [PATCH 2/2] [InstCombine] Handle commuted cases of the fold
`((B|C)&A)|B -> B|(A&C)`
---
.../InstCombine/InstCombineAndOrXor.cpp | 6 +++++-
llvm/test/Transforms/InstCombine/or.ll | 15 ++++++---------
2 files changed, 11 insertions(+), 10 deletions(-)
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 af9e6ce2839b2d..573a11599141a7 100644
--- a/llvm/test/Transforms/InstCombine/or.ll
+++ b/llvm/test/Transforms/InstCombine/or.ll
@@ -756,9 +756,8 @@ define i32 @test45(i32 %x, i32 %y, i32 %z) {
define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {
; CHECK-LABEL: @test45_commuted1(
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[YY]], [[Z:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR]], [[X:%.*]]
-; CHECK-NEXT: [[OR1:%.*]] = or i32 [[YY]], [[AND]]
+; 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
@@ -772,9 +771,8 @@ 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: [[OR:%.*]] = or i32 [[YY]], [[Z:%.*]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[XX]], [[OR]]
-; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[YY]]
+; 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
@@ -789,9 +787,8 @@ 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: [[OR:%.*]] = or i32 [[ZZ]], [[YY]]
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[OR]], [[X:%.*]]
-; CHECK-NEXT: [[OR1:%.*]] = or i32 [[AND]], [[YY]]
+; 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
More information about the llvm-commits
mailing list