[llvm] 617ad14 - [SelectionDAG] Add pattern to haveNoCommonBitsSet

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 1 09:04:14 PST 2021


Author: Omer Aviram
Date: 2021-12-01T12:04:04-05:00
New Revision: 617ad14060dcdfa9f1f967a3edd9e097de8bf83a

URL: https://github.com/llvm/llvm-project/commit/617ad14060dcdfa9f1f967a3edd9e097de8bf83a
DIFF: https://github.com/llvm/llvm-project/commit/617ad14060dcdfa9f1f967a3edd9e097de8bf83a.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/test/CodeGen/X86/or-lea.ll
    llvm/test/CodeGen/X86/vec_no-common-bits.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 25e99d45c4ab..c282e03387dd 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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));
 }

diff  --git a/llvm/test/CodeGen/X86/or-lea.ll b/llvm/test/CodeGen/X86/or-lea.ll
index f497fc6bd51a..9ea15ee72cf9 100644
--- a/llvm/test/CodeGen/X86/or-lea.ll
+++ b/llvm/test/CodeGen/X86/or-lea.ll
@@ -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

diff  --git a/llvm/test/CodeGen/X86/vec_no-common-bits.ll b/llvm/test/CodeGen/X86/vec_no-common-bits.ll
index 6e03edbe8b53..192ec0336804 100644
--- a/llvm/test/CodeGen/X86/vec_no-common-bits.ll
+++ b/llvm/test/CodeGen/X86/vec_no-common-bits.ll
@@ -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


        


More information about the llvm-commits mailing list