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 47275ce31070b..c380e2748f89b 100644 --- a/llvm/test/Transforms/InstCombine/xor-and-or.ll +++ b/llvm/test/Transforms/InstCombine/xor-and-or.ll @@ -25,6 +25,18 @@ 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: [[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 + %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:%.*]]