[PATCH] D124772: [DAGCombine] Fold A + (B & ~A) to A | B

Nikita Popov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 2 07:29:22 PDT 2022


nikic created this revision.
nikic added reviewers: RKSimon, spatel, craig.topper.
Herald added subscribers: StephenFan, ecnelises, steven.zhang, pengfei, hiraditya.
Herald added a project: All.
nikic requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This is the DAGCombine companion fold for the InstCombine version in D124763 <https://reviews.llvm.org/D124763>. This time we only need to handle `A + (B & ~A)` to `A | B` (https://alive2.llvm.org/ce/z/N5fWZ9), because there's only one canonical form.

The reason why this needs to be a DAGCombine is that in the motivating case the add is actually a getelementptr, which only gets converted into an add on the DAG level. This patch is not quite sufficient to handle the getelementptr case yet, because of an interfering demanded bits simplification.


https://reviews.llvm.org/D124772

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


Index: llvm/test/CodeGen/X86/add-and-not.ll
===================================================================
--- llvm/test/CodeGen/X86/add-and-not.ll
+++ llvm/test/CodeGen/X86/add-and-not.ll
@@ -7,9 +7,8 @@
 ; 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 @@
 ; 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 @@
 ; 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 @@
 ; 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
@@ -103,11 +99,10 @@
 ; CHECK-NEXT:    movl %ebx, %edi
 ; CHECK-NEXT:    callq use at PLT
 ; CHECK-NEXT:    andb %r14b, %bl
-; CHECK-NEXT:    movzbl %bl, %ebx
-; CHECK-NEXT:    movl %ebx, %edi
+; CHECK-NEXT:    movzbl %bl, %edi
 ; CHECK-NEXT:    callq use at PLT
-; CHECK-NEXT:    addb %bpl, %bl
-; CHECK-NEXT:    movl %ebx, %eax
+; CHECK-NEXT:    orb %r14b, %bpl
+; CHECK-NEXT:    movl %ebp, %eax
 ; CHECK-NEXT:    popq %rbx
 ; CHECK-NEXT:    popq %r14
 ; CHECK-NEXT:    popq %rbp
Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2832,6 +2832,15 @@
                          DAG.getVTList(VT, Carry.getValueType()), N0,
                          DAG.getConstant(0, DL, VT), Carry);
 
+  if (N1.getOpcode() == ISD::AND) {
+    // (add X, (and ~X, Y)) -> (or X, Y)
+    if (isBitwiseNot(N1.getOperand(0)) && N1.getOperand(0).getOperand(0) == N0)
+      return DAG.getNode(ISD::OR, DL, VT, N0, N1.getOperand(1));
+    // (add X, (and Y, ~X)) -> (or X, Y)
+    if (isBitwiseNot(N1.getOperand(1)) && N1.getOperand(1).getOperand(0) == N0)
+      return DAG.getNode(ISD::OR, DL, VT, N0, N1.getOperand(0));
+  }
+
   return SDValue();
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D124772.426415.patch
Type: text/x-patch
Size: 2973 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220502/51f16191/attachment.bin>


More information about the llvm-commits mailing list