[llvm] [InstCombine] Fold `(A | B) ^ (A & C) --> A ? ~C : B` (PR #121906)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 7 01:09:22 PST 2025
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/121906
Closes https://github.com/llvm/llvm-project/issues/121773.
>From d0680ffbf270dc8b8b8b6295357d2fae119b1299 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 7 Jan 2025 16:44:24 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
llvm/test/Transforms/InstCombine/xor-and-or.ll | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/xor-and-or.ll b/llvm/test/Transforms/InstCombine/xor-and-or.ll
index 47275ce31070b5..01db9a543caa5e 100644
--- a/llvm/test/Transforms/InstCombine/xor-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll
@@ -25,6 +25,19 @@ define i1 @xor_logic_and_logic_or2(i1 %c, i1 %x, i1 %y) {
ret i1 %r
}
+define i1 @xor_logic_and_logic_or2_commuted(i1 %c, i1 %x, i1 %y) {
+; CHECK-LABEL: @xor_logic_and_logic_or2_commuted(
+; CHECK-NEXT: [[O:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[C:%.*]]
+; CHECK-NEXT: [[A:%.*]] = select i1 [[C]], i1 [[X:%.*]], i1 false
+; CHECK-NEXT: [[R:%.*]] = xor i1 [[O]], [[A]]
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %o = select i1 %y, i1 true, i1 %c
+ %a = select i1 %c, i1 %x, i1 false
+ %r = xor i1 %o, %a
+ ret i1 %r
+}
+
define i1 @xor_logic_and_logic_or3(i1 %c, i1 %x, i1 %y) {
; CHECK-LABEL: @xor_logic_and_logic_or3(
; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]]
>From 83c68c851ad8936931f5c7998f19378d010548e7 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Tue, 7 Jan 2025 16:58:33 +0800
Subject: [PATCH 2/2] [InstCombine] Fold `(A | B) ^ (A & C) --> A ? ~C : B`
---
llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp | 4 ++--
llvm/test/Transforms/InstCombine/xor-and-or.ll | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 37a7c4d88b234d..d8fd41de47869b 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -4972,8 +4972,8 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// (A & B) ^ (A | C) --> A ? ~B : C -- There are 4 commuted variants.
if (I.getType()->isIntOrIntVectorTy(1) &&
- match(Op0, m_OneUse(m_LogicalAnd(m_Value(A), m_Value(B)))) &&
- match(Op1, m_OneUse(m_LogicalOr(m_Value(C), m_Value(D))))) {
+ match(&I, m_c_Xor(m_OneUse(m_LogicalAnd(m_Value(A), m_Value(B))),
+ m_OneUse(m_LogicalOr(m_Value(C), m_Value(D)))))) {
bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) && B == D;
if (B == C || B == D)
std::swap(A, B);
diff --git a/llvm/test/Transforms/InstCombine/xor-and-or.ll b/llvm/test/Transforms/InstCombine/xor-and-or.ll
index 01db9a543caa5e..c380e2748f89bc 100644
--- a/llvm/test/Transforms/InstCombine/xor-and-or.ll
+++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll
@@ -27,9 +27,8 @@ define i1 @xor_logic_and_logic_or2(i1 %c, i1 %x, i1 %y) {
define i1 @xor_logic_and_logic_or2_commuted(i1 %c, i1 %x, i1 %y) {
; CHECK-LABEL: @xor_logic_and_logic_or2_commuted(
-; CHECK-NEXT: [[O:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[C:%.*]]
-; CHECK-NEXT: [[A:%.*]] = select i1 [[C]], i1 [[X:%.*]], i1 false
-; CHECK-NEXT: [[R:%.*]] = xor i1 [[O]], [[A]]
+; CHECK-NEXT: [[TMP1:%.*]] = xor i1 [[X:%.*]], true
+; CHECK-NEXT: [[R:%.*]] = select i1 [[C:%.*]], i1 [[TMP1]], i1 [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%o = select i1 %y, i1 true, i1 %c
More information about the llvm-commits
mailing list