Skip to content

Commit 77303af

Browse files
committed
[InstCombine] Implement ((B ^ C) & A) | B -> B | (A & C)
We already have this for the OR variant, but this works for XOR as well.
1 parent 6be58b3 commit 77303af

File tree

2 files changed

+16
-12
lines changed

2 files changed

+16
-12
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,14 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
35443544
if (match(Op1, m_c_And(m_c_Or(m_Specific(Op0), m_Value(C)), m_Value(A))))
35453545
return BinaryOperator::CreateOr(Op0, Builder.CreateAnd(A, C));
35463546

3547+
// ((B ^ C) & A) | B -> B | (A & C)
3548+
if (match(Op0, m_c_And(m_c_Xor(m_Specific(Op1), m_Value(C)), m_Value(A))))
3549+
return BinaryOperator::CreateOr(Op1, Builder.CreateAnd(A, C));
3550+
3551+
// B | ((B ^ C) & A) -> B | (A & C)
3552+
if (match(Op1, m_c_And(m_c_Xor(m_Specific(Op0), m_Value(C)), m_Value(A))))
3553+
return BinaryOperator::CreateOr(Op0, Builder.CreateAnd(A, C));
3554+
35473555
if (Instruction *DeMorgan = matchDeMorgansLaws(I, *this))
35483556
return DeMorgan;
35493557

llvm/test/Transforms/InstCombine/or.ll

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -801,9 +801,8 @@ define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {
801801

802802
define i32 @test45a(i32 %x, i32 %y, i32 %z) {
803803
; CHECK-LABEL: @test45a(
804-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], [[Z:%.*]]
805-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[X:%.*]]
806-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[Y]]
804+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
805+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
807806
; CHECK-NEXT: ret i32 [[OR]]
808807
;
809808
%xor = xor i32 %y, %z
@@ -815,9 +814,8 @@ define i32 @test45a(i32 %x, i32 %y, i32 %z) {
815814
define i32 @test45a_commuted1(i32 %x, i32 %y, i32 %z) {
816815
; CHECK-LABEL: @test45a_commuted1(
817816
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
818-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[YY]], [[Z:%.*]]
819-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[X:%.*]]
820-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[YY]], [[AND]]
817+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
818+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[YY]], [[TMP1]]
821819
; CHECK-NEXT: ret i32 [[OR]]
822820
;
823821
%yy = mul i32 %y, %y ; thwart complexity-based ordering
@@ -831,9 +829,8 @@ define i32 @test45a_commuted2(i32 %x, i32 %y, i32 %z) {
831829
; CHECK-LABEL: @test45a_commuted2(
832830
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
833831
; CHECK-NEXT: [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
834-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[YY]], [[Z:%.*]]
835-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[XX]], [[XOR]]
836-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[YY]]
832+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]
833+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[YY]], [[TMP1]]
837834
; CHECK-NEXT: ret i32 [[OR]]
838835
;
839836
%yy = mul i32 %y, %y ; thwart complexity-based ordering
@@ -848,9 +845,8 @@ define i32 @test45a_commuted3(i32 %x, i32 %y, i32 %z) {
848845
; CHECK-LABEL: @test45a_commuted3(
849846
; CHECK-NEXT: [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
850847
; CHECK-NEXT: [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]
851-
; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[ZZ]], [[YY]]
852-
; CHECK-NEXT: [[AND:%.*]] = and i32 [[XOR]], [[X:%.*]]
853-
; CHECK-NEXT: [[OR:%.*]] = or i32 [[AND]], [[YY]]
848+
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]
849+
; CHECK-NEXT: [[OR:%.*]] = or i32 [[YY]], [[TMP1]]
854850
; CHECK-NEXT: ret i32 [[OR]]
855851
;
856852
%yy = mul i32 %y, %y ; thwart complexity-based ordering

0 commit comments

Comments
 (0)