[llvm] 2171a89 - [SDAG] Handle A and B&~A in haveNoCommonBitsSet()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Tue May 3 06:47:12 PDT 2022


Author: Nikita Popov
Date: 2022-05-03T15:47:02+02:00
New Revision: 2171a896ed0059e3576fd9c36d0021a3de11d31a

URL: https://github.com/llvm/llvm-project/commit/2171a896ed0059e3576fd9c36d0021a3de11d31a
DIFF: https://github.com/llvm/llvm-project/commit/2171a896ed0059e3576fd9c36d0021a3de11d31a.diff

LOG: [SDAG] Handle A and B&~A in haveNoCommonBitsSet()

This is the DAG variant of D124763. The code already handles the
general pattern, but not this degenerate case.

This allows folding A + (B&~A) to A | (B&~A) which further holds
to A | B.

Handling on the SDAG level is needed because in the motivating
case the add is actually a getelementptr, which only gets converted
into an add on the SDAG level. However, this patch is not quite
sufficient to handle the getelementptr case yet, because of an
interfering demanded bits simplification.

Differential Revision: https://reviews.llvm.org/D124772

Added: 
    

Modified: 
    llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/test/CodeGen/X86/add-and-not.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 83c752b23ba00..90e4b5d71be60 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4686,18 +4686,21 @@ bool SelectionDAG::isEqualTo(SDValue A, SDValue B) const {
 
 static bool haveNoCommonBitsSetCommutative(SDValue A, SDValue B) {
   // 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;
-    };
+  // Including degenerate case (X & ~M) op M
+  auto MatchNoCommonBitsPattern = [&](SDValue NotM, SDValue Other) {
+    if (isBitwiseNot(NotM, true)) {
+      SDValue NotOperand = NotM->getOperand(0);
+      if (Other == NotOperand)
+        return true;
+      if (Other->getOpcode() == ISD::AND)
+        return NotOperand == Other->getOperand(0) ||
+               NotOperand == Other->getOperand(1);
+    }
+    return false;
+  };
+  if (A->getOpcode() == ISD::AND)
     return MatchNoCommonBitsPattern(A->getOperand(0), B) ||
            MatchNoCommonBitsPattern(A->getOperand(1), B);
-  }
   return false;
 }
 

diff  --git a/llvm/test/CodeGen/X86/add-and-not.ll b/llvm/test/CodeGen/X86/add-and-not.ll
index 98f9f1ae4be79..570aac6ea2e89 100644
--- a/llvm/test/CodeGen/X86/add-and-not.ll
+++ b/llvm/test/CodeGen/X86/add-and-not.ll
@@ -7,9 +7,8 @@ define i8 @add_and_xor(i8 %x, i8 %y) {
 ; CHECK-LABEL: add_and_xor:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    notb %al
-; CHECK-NEXT:    andb %sil, %al
-; CHECK-NEXT:    addb %dil, %al
+; CHECK-NEXT:    orl %esi, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %xor = xor i8 %x, -1
   %and = and i8 %xor, %y
@@ -51,9 +50,8 @@ define i8 @add_and_xor_commuted1(i8 %x, i8 %y) {
 ; CHECK-LABEL: add_and_xor_commuted1:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    notb %al
-; CHECK-NEXT:    andb %sil, %al
-; CHECK-NEXT:    addb %dil, %al
+; CHECK-NEXT:    orl %esi, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %xor = xor i8 %x, -1
   %and = and i8 %y, %xor
@@ -65,9 +63,8 @@ define i8 @add_and_xor_commuted2(i8 %x, i8 %y) {
 ; CHECK-LABEL: add_and_xor_commuted2:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    notb %al
-; CHECK-NEXT:    andb %sil, %al
-; CHECK-NEXT:    addb %dil, %al
+; CHECK-NEXT:    orl %esi, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %xor = xor i8 %x, -1
   %and = and i8 %xor, %y
@@ -79,9 +76,8 @@ define i8 @add_and_xor_commuted3(i8 %x, i8 %y) {
 ; CHECK-LABEL: add_and_xor_commuted3:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movl %edi, %eax
-; CHECK-NEXT:    notb %al
-; CHECK-NEXT:    andb %sil, %al
-; CHECK-NEXT:    addb %dil, %al
+; CHECK-NEXT:    orl %esi, %eax
+; CHECK-NEXT:    # kill: def $al killed $al killed $eax
 ; CHECK-NEXT:    retq
   %xor = xor i8 %x, -1
   %and = and i8 %y, %xor
@@ -95,18 +91,17 @@ define i8 @add_and_xor_extra_use(i8 %x, i8 %y) nounwind {
 ; CHECK-NEXT:    pushq %rbp
 ; CHECK-NEXT:    pushq %r14
 ; CHECK-NEXT:    pushq %rbx
-; CHECK-NEXT:    movl %esi, %r14d
-; CHECK-NEXT:    movl %edi, %ebp
-; CHECK-NEXT:    movl %ebp, %eax
+; CHECK-NEXT:    movl %esi, %ebx
+; CHECK-NEXT:    movl %edi, %r14d
+; CHECK-NEXT:    movl %r14d, %eax
 ; CHECK-NEXT:    notb %al
-; CHECK-NEXT:    movzbl %al, %ebx
-; CHECK-NEXT:    movl %ebx, %edi
+; CHECK-NEXT:    movzbl %al, %ebp
+; CHECK-NEXT:    movl %ebp, %edi
 ; CHECK-NEXT:    callq use at PLT
-; CHECK-NEXT:    andb %r14b, %bl
-; CHECK-NEXT:    movzbl %bl, %ebx
-; CHECK-NEXT:    movl %ebx, %edi
+; CHECK-NEXT:    andb %bl, %bpl
+; CHECK-NEXT:    movzbl %bpl, %edi
 ; CHECK-NEXT:    callq use at PLT
-; CHECK-NEXT:    addb %bpl, %bl
+; CHECK-NEXT:    orb %r14b, %bl
 ; CHECK-NEXT:    movl %ebx, %eax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    popq %r14


        


More information about the llvm-commits mailing list