match(Op1, m_c_And(m_Not(m_Specific(A)), m_Specific(B)))))
return Op0;
+ // (A & B) | (~A ^ B) -> (~A ^ B)
+ // (B & A) | (~A ^ B) -> (~A ^ B)
+ // (A & B) | (B ^ ~A) -> (B ^ ~A)
+ // (B & A) | (B ^ ~A) -> (B ^ ~A)
+ if (match(Op0, m_And(m_Value(A), m_Value(B))) &&
+ (match(Op1, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) ||
+ match(Op1, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
+ return Op1;
+
+ // (~A ^ B) | (A & B) -> (~A ^ B)
+ // (~A ^ B) | (B & A) -> (~A ^ B)
+ // (B ^ ~A) | (A & B) -> (B ^ ~A)
+ // (B ^ ~A) | (B & A) -> (B ^ ~A)
+ if (match(Op1, m_And(m_Value(A), m_Value(B))) &&
+ (match(Op0, m_c_Xor(m_Specific(A), m_Not(m_Specific(B)))) ||
+ match(Op0, m_c_Xor(m_Not(m_Specific(A)), m_Specific(B)))))
+ return Op0;
+
if (Value *V = simplifyAndOrOfICmps(Op0, Op1, false))
return V;
define i32 @test47(i32 %a, i32 %b) {
; CHECK-LABEL: @test47(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %a, %b
define i32 @test48(i32 %a, i32 %b) {
; CHECK-LABEL: @test48(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %a, %b
define i32 @test49(i32 %a, i32 %b) {
; CHECK-LABEL: @test49(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %b, %a
define i32 @test50(i32 %a, i32 %b) {
; CHECK-LABEL: @test50(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[XOR]], [[AND]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %b, %a
define i32 @test51(i32 %a, i32 %b) {
; CHECK-LABEL: @test51(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %a, %b
define i32 @test52(i32 %a, i32 %b) {
; CHECK-LABEL: @test52(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[A]], [[B:%.*]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %a, %b
define i32 @test53(i32 %a, i32 %b) {
; CHECK-LABEL: @test53(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B]], [[NEGA]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[B:%.*]], [[NEGA]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %b, %a
define i32 @test54(i32 %a, i32 %b) {
; CHECK-LABEL: @test54(
; CHECK-NEXT: [[NEGA:%.*]] = xor i32 [[A:%.*]], -1
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[B:%.*]], [[A]]
-; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B]]
-; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[XOR]]
-; CHECK-NEXT: ret i32 [[OR]]
+; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[NEGA]], [[B:%.*]]
+; CHECK-NEXT: ret i32 [[XOR]]
;
%nega = xor i32 %a, -1
%and = and i32 %b, %a