From d0680ffbf270dc8b8b8b6295357d2fae119b1299 Mon Sep 17 00:00:00 2001 From: Yingwei Zheng 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 47275ce31070b..01db9a543caa5 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 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 37a7c4d88b234..d8fd41de47869 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(Op0) && isa(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 01db9a543caa5..c380e2748f89b 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