Skip to content

Commit d0e9879

Browse files
committed
[InstCombine] allow vector splat matching for bitwise logic folds
These transforms are also likely missing a one-use check, but that's another patch.
1 parent ae89841 commit d0e9879

File tree

3 files changed

+28
-31
lines changed

3 files changed

+28
-31
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,10 +2699,31 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
26992699
return BinaryOperator::CreateXor(Or, ConstantInt::get(I.getType(), *CV));
27002700
}
27012701

2702-
// (A & C)|(B & D)
2702+
// (A & C) | (B & D)
27032703
Value *A, *B, *C, *D;
27042704
if (match(Op0, m_And(m_Value(A), m_Value(C))) &&
27052705
match(Op1, m_And(m_Value(B), m_Value(D)))) {
2706+
2707+
const APInt *MaskC0, *MaskC1;
2708+
if (match(C, m_APInt(MaskC0)) && match(D, m_APInt(MaskC1)) &&
2709+
*MaskC0 == ~*MaskC1) {
2710+
Value *X;
2711+
2712+
// ((X | B) & C1) | (B & C2) -> (X & C1) | B iff C1 == ~C2
2713+
if (match(A, m_c_Or(m_Value(X), m_Specific(B))))
2714+
return BinaryOperator::CreateOr(Builder.CreateAnd(X, *MaskC0), B);
2715+
// (A & C2) | ((X | A) & C1) -> (X & C2) | A iff C1 == ~C2
2716+
if (match(B, m_c_Or(m_Specific(A), m_Value(X))))
2717+
return BinaryOperator::CreateOr(Builder.CreateAnd(X, *MaskC1), A);
2718+
2719+
// ((X ^ B) & C1) | (B & C2) -> (X & C1) ^ B iff C1 == ~C2
2720+
if (match(A, m_c_Xor(m_Value(X), m_Specific(B))))
2721+
return BinaryOperator::CreateXor(Builder.CreateAnd(X, *MaskC0), B);
2722+
// (A & C2) | ((X ^ A) & C1) -> (X & C2) ^ A iff C1 == ~C2
2723+
if (match(B, m_c_Xor(m_Specific(A), m_Value(X))))
2724+
return BinaryOperator::CreateXor(Builder.CreateAnd(X, *MaskC1), A);
2725+
}
2726+
27062727
// (A & C1)|(B & C2)
27072728
ConstantInt *C1, *C2;
27082729
if (match(C, m_ConstantInt(C1)) && match(D, m_ConstantInt(C2))) {
@@ -2738,24 +2759,6 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
27382759
Builder.getInt(C1->getValue()|C2->getValue()));
27392760
}
27402761
}
2741-
2742-
if (C1->getValue() == ~C2->getValue()) {
2743-
Value *X;
2744-
2745-
// ((X|B)&C1)|(B&C2) -> (X&C1) | B iff C1 == ~C2
2746-
if (match(A, m_c_Or(m_Value(X), m_Specific(B))))
2747-
return BinaryOperator::CreateOr(Builder.CreateAnd(X, C1), B);
2748-
// (A&C2)|((X|A)&C1) -> (X&C2) | A iff C1 == ~C2
2749-
if (match(B, m_c_Or(m_Specific(A), m_Value(X))))
2750-
return BinaryOperator::CreateOr(Builder.CreateAnd(X, C2), A);
2751-
2752-
// ((X^B)&C1)|(B&C2) -> (X&C1) ^ B iff C1 == ~C2
2753-
if (match(A, m_c_Xor(m_Value(X), m_Specific(B))))
2754-
return BinaryOperator::CreateXor(Builder.CreateAnd(X, C1), B);
2755-
// (A&C2)|((X^A)&C1) -> (X&C2) ^ A iff C1 == ~C2
2756-
if (match(B, m_c_Xor(m_Specific(A), m_Value(X))))
2757-
return BinaryOperator::CreateXor(Builder.CreateAnd(X, C2), A);
2758-
}
27592762
}
27602763

27612764
// Don't try to form a select if it's unlikely that we'll get rid of at

llvm/test/Transforms/InstCombine/and-or.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@ define i32 @or_and_not_constant_commute3(i32 %a, i32 %b) {
5757

5858
define <2 x i7> @or_and_not_constant_commute0_splat(<2 x i7> %a, <2 x i7> %b) {
5959
; CHECK-LABEL: @or_and_not_constant_commute0_splat(
60-
; CHECK-NEXT: [[T:%.*]] = or <2 x i7> [[B:%.*]], [[A:%.*]]
61-
; CHECK-NEXT: [[T1:%.*]] = and <2 x i7> [[T]], <i7 42, i7 42>
62-
; CHECK-NEXT: [[T2:%.*]] = and <2 x i7> [[B]], <i7 -43, i7 -43>
63-
; CHECK-NEXT: [[T3:%.*]] = or <2 x i7> [[T1]], [[T2]]
60+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i7> [[A:%.*]], <i7 42, i7 42>
61+
; CHECK-NEXT: [[T3:%.*]] = or <2 x i7> [[TMP1]], [[B:%.*]]
6462
; CHECK-NEXT: ret <2 x i7> [[T3]]
6563
;
6664
%t = or <2 x i7> %b, %a

llvm/test/Transforms/InstCombine/or-xor.ll

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,8 @@ define i9 @or_and_xor_not_constant_commute1(i9 %a, i9 %b) {
303303

304304
define <2 x i9> @or_and_xor_not_constant_commute2_splat(<2 x i9> %a, <2 x i9> %b) {
305305
; CHECK-LABEL: @or_and_xor_not_constant_commute2_splat(
306-
; CHECK-NEXT: [[OR:%.*]] = xor <2 x i9> [[B:%.*]], [[A:%.*]]
307-
; CHECK-NEXT: [[AND1:%.*]] = and <2 x i9> [[OR]], <i9 42, i9 42>
308-
; CHECK-NEXT: [[AND2:%.*]] = and <2 x i9> [[B]], <i9 -43, i9 -43>
309-
; CHECK-NEXT: [[XOR:%.*]] = or <2 x i9> [[AND2]], [[AND1]]
306+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], <i9 42, i9 42>
307+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]]
310308
; CHECK-NEXT: ret <2 x i9> [[XOR]]
311309
;
312310
%or = xor <2 x i9> %b, %a
@@ -318,10 +316,8 @@ define <2 x i9> @or_and_xor_not_constant_commute2_splat(<2 x i9> %a, <2 x i9> %b
318316

319317
define <2 x i9> @or_and_xor_not_constant_commute3_splat(<2 x i9> %a, <2 x i9> %b) {
320318
; CHECK-LABEL: @or_and_xor_not_constant_commute3_splat(
321-
; CHECK-NEXT: [[OR:%.*]] = xor <2 x i9> [[A:%.*]], [[B:%.*]]
322-
; CHECK-NEXT: [[AND1:%.*]] = and <2 x i9> [[OR]], <i9 42, i9 42>
323-
; CHECK-NEXT: [[AND2:%.*]] = and <2 x i9> [[B]], <i9 -43, i9 -43>
324-
; CHECK-NEXT: [[XOR:%.*]] = or <2 x i9> [[AND2]], [[AND1]]
319+
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i9> [[A:%.*]], <i9 42, i9 42>
320+
; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i9> [[TMP1]], [[B:%.*]]
325321
; CHECK-NEXT: ret <2 x i9> [[XOR]]
326322
;
327323
%or = xor <2 x i9> %a, %b

0 commit comments

Comments
 (0)