diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2265,6 +2265,19 @@ match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B))))) return Op0; + // (A | B) | (A ^ B) --> A | B + // (B | A) | (A ^ B) --> B | A + if (match(Op1, m_c_Xor(m_Value(A), m_Value(B))) && + match(Op0, m_c_Or(m_Specific(A), m_Specific(B)))) + return Op0; + + // Commute the outer 'or' operands. + // (A ^ B) | (A | B) --> A | B + // (A ^ B) | (B | A) --> B | A + if (match(Op0, m_c_Xor(m_Value(A), m_Value(B))) && + match(Op1, m_c_Or(m_Specific(A), m_Specific(B)))) + return Op1; + // (~A & B) | ~(A | B) --> ~A // (~A & B) | ~(B | A) --> ~A // (B & ~A) | ~(A | B) --> ~A diff --git a/llvm/test/Transforms/InstSimplify/or.ll b/llvm/test/Transforms/InstSimplify/or.ll --- a/llvm/test/Transforms/InstSimplify/or.ll +++ b/llvm/test/Transforms/InstSimplify/or.ll @@ -451,9 +451,7 @@ define i69 @or_or_xor(i69 %A, i69 %B) { ; CHECK-LABEL: @or_or_xor( ; CHECK-NEXT: [[I1:%.*]] = or i69 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[I2:%.*]] = xor i69 [[A]], [[B]] -; CHECK-NEXT: [[I3:%.*]] = or i69 [[I1]], [[I2]] -; CHECK-NEXT: ret i69 [[I3]] +; CHECK-NEXT: ret i69 [[I1]] ; %i1 = or i69 %A, %B %i2 = xor i69 %A, %B @@ -464,9 +462,7 @@ define <4 x i4> @or_or_xor_commuted(<4 x i4> %A, <4 x i4> %B) { ; CHECK-LABEL: @or_or_xor_commuted( ; CHECK-NEXT: [[I1:%.*]] = or <4 x i4> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[I2:%.*]] = xor <4 x i4> [[A]], [[B]] -; CHECK-NEXT: [[I3:%.*]] = or <4 x i4> [[I2]], [[I1]] -; CHECK-NEXT: ret <4 x i4> [[I3]] +; CHECK-NEXT: ret <4 x i4> [[I1]] ; %i1 = or <4 x i4> %A, %B %i2 = xor <4 x i4> %A, %B