Skip to content

Commit

Permalink
[SelectionDAG] Add pattern to haveNoCommonBitsSet
Browse files Browse the repository at this point in the history
Correctly identify the following pattern, which has no common bits: (X & ~M) op (Y & M).

Differential Revision: https://reviews.llvm.org/D113970
  • Loading branch information
Omeriko12 authored and rotateright committed Dec 1, 2021
1 parent 0985911 commit 617ad14
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 69 deletions.
17 changes: 16 additions & 1 deletion llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4542,10 +4542,25 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
}

// FIXME: unify with llvm::haveNoCommonBitsSet.
// FIXME: could also handle masked merge pattern (X & ~M) op (Y & M)
bool SelectionDAG::haveNoCommonBitsSet(SDValue A, SDValue B) const {
assert(A.getValueType() == B.getValueType() &&
"Values must have the same type");
// Match masked merge pattern (X & ~M) op (Y & M)
if (A->getOpcode() == ISD::AND && B->getOpcode() == ISD::AND) {
auto MatchNoCommonBitsPattern = [&](SDValue NotM, SDValue And) {
if (isBitwiseNot(NotM, true)) {
SDValue NotOperand = NotM->getOperand(0);
return NotOperand == And->getOperand(0) ||
NotOperand == And->getOperand(1);
}
return false;
};
if (MatchNoCommonBitsPattern(A->getOperand(0), B) ||
MatchNoCommonBitsPattern(A->getOperand(1), B) ||
MatchNoCommonBitsPattern(B->getOperand(0), A) ||
MatchNoCommonBitsPattern(B->getOperand(1), A))
return true;
}
return KnownBits::haveNoCommonBitsSet(computeKnownBits(A),
computeKnownBits(B));
}
Expand Down
28 changes: 12 additions & 16 deletions llvm/test/CodeGen/X86/or-lea.ll
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,10 @@ define i32 @or_and_and_rhs_neg_i32(i32 %x, i32 %y, i32 %z) {
;
; BMI-LABEL: or_and_and_rhs_neg_i32:
; BMI: # %bb.0: # %entry
; BMI-NEXT: # kill: def $edx killed $edx def $rdx
; BMI-NEXT: andl %esi, %edx
; BMI-NEXT: andnl %edi, %esi, %eax
; BMI-NEXT: orl %edx, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: leal 1(%rdx,%rax), %eax
; BMI-NEXT: retq
entry:
%and1 = and i32 %z, %y
Expand All @@ -172,10 +172,10 @@ define i32 @or_and_and_lhs_neg_i32(i32 %x, i32 %y, i32 %z) {
;
; BMI-LABEL: or_and_and_lhs_neg_i32:
; BMI: # %bb.0: # %entry
; BMI-NEXT: # kill: def $edx killed $edx def $rdx
; BMI-NEXT: andl %esi, %edx
; BMI-NEXT: andnl %edi, %esi, %eax
; BMI-NEXT: orl %edx, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: leal 1(%rdx,%rax), %eax
; BMI-NEXT: retq
entry:
%and1 = and i32 %z, %y
Expand All @@ -198,10 +198,10 @@ define i32 @or_and_rhs_neg_and_i32(i32 %x, i32 %y, i32 %z) {
;
; BMI-LABEL: or_and_rhs_neg_and_i32:
; BMI: # %bb.0: # %entry
; BMI-NEXT: # kill: def $edi killed $edi def $rdi
; BMI-NEXT: andnl %edx, %esi, %eax
; BMI-NEXT: andl %esi, %edi
; BMI-NEXT: orl %edi, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: leal 1(%rax,%rdi), %eax
; BMI-NEXT: retq
entry:
%xor = xor i32 %y, -1
Expand All @@ -224,10 +224,10 @@ define i32 @or_and_lhs_neg_and_i32(i32 %x, i32 %y, i32 %z) {
;
; BMI-LABEL: or_and_lhs_neg_and_i32:
; BMI: # %bb.0: # %entry
; BMI-NEXT: # kill: def $edi killed $edi def $rdi
; BMI-NEXT: andnl %edx, %esi, %eax
; BMI-NEXT: andl %esi, %edi
; BMI-NEXT: orl %edi, %eax
; BMI-NEXT: incl %eax
; BMI-NEXT: leal 1(%rax,%rdi), %eax
; BMI-NEXT: retq
entry:
%xor = xor i32 %y, -1
Expand All @@ -251,8 +251,7 @@ define i64 @or_and_and_rhs_neg_i64(i64 %x, i64 %y, i64 %z) {
; BMI: # %bb.0: # %entry
; BMI-NEXT: andq %rsi, %rdx
; BMI-NEXT: andnq %rdi, %rsi, %rax
; BMI-NEXT: orq %rdx, %rax
; BMI-NEXT: incq %rax
; BMI-NEXT: leaq 1(%rdx,%rax), %rax
; BMI-NEXT: retq
entry:
%and1 = and i64 %z, %y
Expand All @@ -276,8 +275,7 @@ define i64 @or_and_and_lhs_neg_i64(i64 %x, i64 %y, i64 %z) {
; BMI: # %bb.0: # %entry
; BMI-NEXT: andq %rsi, %rdx
; BMI-NEXT: andnq %rdi, %rsi, %rax
; BMI-NEXT: orq %rdx, %rax
; BMI-NEXT: incq %rax
; BMI-NEXT: leaq 1(%rdx,%rax), %rax
; BMI-NEXT: retq
entry:
%and1 = and i64 %z, %y
Expand All @@ -301,8 +299,7 @@ define i64 @or_and_rhs_neg_and_i64(i64 %x, i64 %y, i64 %z) {
; BMI: # %bb.0: # %entry
; BMI-NEXT: andnq %rdx, %rsi, %rax
; BMI-NEXT: andq %rsi, %rdi
; BMI-NEXT: orq %rdi, %rax
; BMI-NEXT: incq %rax
; BMI-NEXT: leaq 1(%rax,%rdi), %rax
; BMI-NEXT: retq
entry:
%xor = xor i64 %y, -1
Expand All @@ -326,8 +323,7 @@ define i64 @or_and_lhs_neg_and_i64(i64 %x, i64 %y, i64 %z) {
; BMI: # %bb.0: # %entry
; BMI-NEXT: andnq %rdx, %rsi, %rax
; BMI-NEXT: andq %rsi, %rdi
; BMI-NEXT: orq %rdi, %rax
; BMI-NEXT: incq %rax
; BMI-NEXT: leaq 1(%rax,%rdi), %rax
; BMI-NEXT: retq
entry:
%xor = xor i64 %y, -1
Expand Down
60 changes: 8 additions & 52 deletions llvm/test/CodeGen/X86/vec_no-common-bits.ll
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,7 @@
define <2 x i32> @or_and_and_rhs_neg_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
; CHECK-LABEL: or_and_and_rhs_neg_vec_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm2
; CHECK-NEXT: pandn %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: por %xmm1, %xmm0
; CHECK-NEXT: paddd %xmm2, %xmm1
; CHECK-NEXT: psubd %xmm1, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%and1 = and <2 x i32> %z, %y
%xor = xor <2 x i32> %y, <i32 -1, i32 -1>
Expand All @@ -26,12 +21,7 @@ define <2 x i32> @or_and_and_rhs_neg_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i3
define <2 x i32> @or_and_and_lhs_neg_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
; CHECK-LABEL: or_and_and_lhs_neg_vec_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm2
; CHECK-NEXT: pandn %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: por %xmm1, %xmm0
; CHECK-NEXT: paddd %xmm2, %xmm1
; CHECK-NEXT: psubd %xmm1, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%and1 = and <2 x i32> %z, %y
%xor = xor <2 x i32> %y, <i32 -1, i32 -1>
Expand All @@ -45,13 +35,7 @@ define <2 x i32> @or_and_and_lhs_neg_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i3
define <2 x i32> @or_and_rhs_neg_and_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
; CHECK-LABEL: or_and_rhs_neg_and_vec_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm0
; CHECK-NEXT: pandn %xmm2, %xmm1
; CHECK-NEXT: movdqa %xmm1, %xmm2
; CHECK-NEXT: por %xmm0, %xmm2
; CHECK-NEXT: paddd %xmm0, %xmm1
; CHECK-NEXT: psubd %xmm1, %xmm2
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%xor = xor <2 x i32> %y, <i32 -1, i32 -1>
%and1 = and <2 x i32> %z, %xor
Expand All @@ -65,13 +49,7 @@ define <2 x i32> @or_and_rhs_neg_and_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i3
define <2 x i32> @or_and_lhs_neg_and_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i32> %z) {
; CHECK-LABEL: or_and_lhs_neg_and_vec_i32:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm0
; CHECK-NEXT: pandn %xmm2, %xmm1
; CHECK-NEXT: movdqa %xmm1, %xmm2
; CHECK-NEXT: por %xmm0, %xmm2
; CHECK-NEXT: paddd %xmm0, %xmm1
; CHECK-NEXT: psubd %xmm1, %xmm2
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%xor = xor <2 x i32> %y, <i32 -1, i32 -1>
%and1 = and <2 x i32> %xor, %z
Expand All @@ -85,12 +63,7 @@ define <2 x i32> @or_and_lhs_neg_and_vec_i32(<2 x i32> %x, <2 x i32> %y, <2 x i3
define <2 x i64> @or_and_and_rhs_neg_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) {
; CHECK-LABEL: or_and_and_rhs_neg_vec_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm2
; CHECK-NEXT: pandn %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: por %xmm1, %xmm0
; CHECK-NEXT: paddq %xmm2, %xmm1
; CHECK-NEXT: psubq %xmm1, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%and1 = and <2 x i64> %z, %y
%xor = xor <2 x i64> %y, <i64 -1, i64 -1>
Expand All @@ -104,12 +77,7 @@ define <2 x i64> @or_and_and_rhs_neg_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i6
define <2 x i64> @or_and_and_lhs_neg_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) {
; CHECK-LABEL: or_and_and_lhs_neg_vec_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm2
; CHECK-NEXT: pandn %xmm0, %xmm1
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: por %xmm1, %xmm0
; CHECK-NEXT: paddq %xmm2, %xmm1
; CHECK-NEXT: psubq %xmm1, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%and1 = and <2 x i64> %z, %y
%xor = xor <2 x i64> %y, <i64 -1, i64 -1>
Expand All @@ -123,13 +91,7 @@ define <2 x i64> @or_and_and_lhs_neg_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i6
define <2 x i64> @or_and_rhs_neg_and_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) {
; CHECK-LABEL: or_and_rhs_neg_and_vec_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm0
; CHECK-NEXT: pandn %xmm2, %xmm1
; CHECK-NEXT: movdqa %xmm1, %xmm2
; CHECK-NEXT: por %xmm0, %xmm2
; CHECK-NEXT: paddq %xmm0, %xmm1
; CHECK-NEXT: psubq %xmm1, %xmm2
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%xor = xor <2 x i64> %y, <i64 -1, i64 -1>
%and1 = and <2 x i64> %z, %xor
Expand All @@ -143,13 +105,7 @@ define <2 x i64> @or_and_rhs_neg_and_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i6
define <2 x i64> @or_and_lhs_neg_and_vec_i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) {
; CHECK-LABEL: or_and_lhs_neg_and_vec_i64:
; CHECK: # %bb.0:
; CHECK-NEXT: pand %xmm1, %xmm0
; CHECK-NEXT: pandn %xmm2, %xmm1
; CHECK-NEXT: movdqa %xmm1, %xmm2
; CHECK-NEXT: por %xmm0, %xmm2
; CHECK-NEXT: paddq %xmm0, %xmm1
; CHECK-NEXT: psubq %xmm1, %xmm2
; CHECK-NEXT: movdqa %xmm2, %xmm0
; CHECK-NEXT: xorps %xmm0, %xmm0
; CHECK-NEXT: retq
%xor = xor <2 x i64> %y, <i64 -1, i64 -1>
%and1 = and <2 x i64> %xor, %z
Expand Down

0 comments on commit 617ad14

Please sign in to comment.