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 @@ -2226,6 +2226,14 @@ match(Y, m_c_Or(m_Specific(A), m_Specific(B)))) return ConstantInt::getAllOnesValue(Ty); + // (~A | B) | (A ^ B) --> -1 + // (~A | B) | (B ^ A) --> -1 + // (B | ~A) | (A ^ B) --> -1 + // (B | ~A) | (B ^ A) --> -1 + if (match(X, m_c_Or(m_Not(m_Value(A)), m_Value(B))) && + match(Y, m_c_Xor(m_Specific(A), m_Specific(B)))) + return ConstantInt::getAllOnesValue(Ty); + return nullptr; } 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 @@ -845,11 +845,7 @@ define i4 @or_xor_not_op_or(i4 %a, i4 %b){ ; CHECK-LABEL: @or_xor_not_op_or( -; CHECK-NEXT: [[XOR:%.*]] = xor i4 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[NOTA:%.*]] = xor i4 [[A]], -1 -; CHECK-NEXT: [[OR:%.*]] = or i4 [[NOTA]], [[B]] -; CHECK-NEXT: [[R:%.*]] = or i4 [[XOR]], [[OR]] -; CHECK-NEXT: ret i4 [[R]] +; CHECK-NEXT: ret i4 -1 ; %xor = xor i4 %a, %b %nota = xor i4 %a, -1 @@ -858,47 +854,100 @@ ret i4 %r } -; (A ^ B) | (~B | A) --> -1 +; (A ^ B) | (B | ~A) --> -1 define i71 @or_xor_not_op_or_commute1(i71 %a, i71 %b){ ; CHECK-LABEL: @or_xor_not_op_or_commute1( -; CHECK-NEXT: [[XOR:%.*]] = xor i71 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[NOTB:%.*]] = xor i71 [[B]], -1 -; CHECK-NEXT: [[OR:%.*]] = or i71 [[NOTB]], [[A]] -; CHECK-NEXT: [[R:%.*]] = or i71 [[XOR]], [[OR]] -; CHECK-NEXT: ret i71 [[R]] +; CHECK-NEXT: ret i71 -1 ; %xor = xor i71 %a, %b - %notb = xor i71 %b, -1 - %or = or i71 %notb, %a + %nota = xor i71 %a, -1 + %or = or i71 %b, %nota %r = or i71 %xor, %or ret i71 %r } -; (~A | B) | (A ^ B) --> -1 +; (B ^ A) | (~A | B) --> -1 define i32 @or_xor_not_op_or_commute2(i32 %a, i32 %b){ ; CHECK-LABEL: @or_xor_not_op_or_commute2( -; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[NOTA:%.*]] = xor i32 [[A]], -1 -; CHECK-NEXT: [[OR:%.*]] = or i32 [[NOTA]], [[B]] -; CHECK-NEXT: [[R:%.*]] = or i32 [[OR]], [[XOR]] -; CHECK-NEXT: ret i32 [[R]] +; CHECK-NEXT: ret i32 -1 +; + %xor = xor i32 %b, %a + %nota = xor i32 %a, -1 + %or = or i32 %nota, %b + %r = or i32 %xor, %or + ret i32 %r +} + +; (B ^ A) | (B | ~A) --> -1 + +define i32 @or_xor_not_op_or_commute3(i32 %a, i32 %b){ +; CHECK-LABEL: @or_xor_not_op_or_commute3( +; CHECK-NEXT: ret i32 -1 +; + %xor = xor i32 %b, %a + %nota = xor i32 %a, -1 + %or = or i32 %b, %nota + %r = or i32 %xor, %or + ret i32 %r +} + +; (~A | B) | (A ^ B) --> -1 + +define i32 @or_xor_not_op_or_commute4(i32 %a, i32 %b){ +; CHECK-LABEL: @or_xor_not_op_or_commute4( +; CHECK-NEXT: ret i32 -1 +; + %xor = xor i32 %a, %b + %nota = xor i32 %a, -1 + %or = or i32 %nota, %b + %r = or i32 %or, %xor + ret i32 %r +} + +; (B | ~A) | (A ^ B) --> -1 + +define i32 @or_xor_not_op_or_commute5(i32 %a, i32 %b){ +; CHECK-LABEL: @or_xor_not_op_or_commute5( +; CHECK-NEXT: ret i32 -1 ; %xor = xor i32 %a, %b %nota = xor i32 %a, -1 + %or = or i32 %b, %nota + %r = or i32 %or, %xor + ret i32 %r +} + +; (~A | B) | (B ^ A) --> -1 + +define i32 @or_xor_not_op_or_commute6(i32 %a, i32 %b){ +; CHECK-LABEL: @or_xor_not_op_or_commute6( +; CHECK-NEXT: ret i32 -1 +; + %xor = xor i32 %b, %a + %nota = xor i32 %a, -1 %or = or i32 %nota, %b %r = or i32 %or, %xor ret i32 %r } +; (B | ~A) | (B ^ A) --> -1 + +define i32 @or_xor_not_op_or_commute7(i32 %a, i32 %b){ +; CHECK-LABEL: @or_xor_not_op_or_commute7( +; CHECK-NEXT: ret i32 -1 +; + %xor = xor i32 %b, %a + %nota = xor i32 %a, -1 + %or = or i32 %b, %nota + %r = or i32 %or, %xor + ret i32 %r +} + define <2 x i4> @or_xor_not_op_or_undef_elt(<2 x i4> %a, <2 x i4> %b) { ; CHECK-LABEL: @or_xor_not_op_or_undef_elt( -; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i4> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[NOTA:%.*]] = xor <2 x i4> [[A]], -; CHECK-NEXT: [[OR:%.*]] = or <2 x i4> [[NOTA]], [[B]] -; CHECK-NEXT: [[R:%.*]] = or <2 x i4> [[XOR]], [[OR]] -; CHECK-NEXT: ret <2 x i4> [[R]] +; CHECK-NEXT: ret <2 x i4> ; %xor = xor <2 x i4> %a, %b %nota = xor <2 x i4> %a,