forked from OSchip/llvm-project
[SelectionDAG] Add pattern to haveNoCommonBitsSet
Correctly identify the following pattern, which has no common bits: (X & ~M) op (Y & M). Differential Revision: https://reviews.llvm.org/D113970
This commit is contained in:
parent
09859113ed
commit
617ad14060
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue