[llvm] 91105df - [DAG] Peek through zext/trunc when matching (or (and X, (not Y)), Y).

Amaury Séchet via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 11 06:48:27 PDT 2023


Author: Amaury Séchet
Date: 2023-04-11T13:48:22Z
New Revision: 91105df3dfeb6c5589de987c1c1bdd3d7fe781d8

URL: https://github.com/llvm/llvm-project/commit/91105df3dfeb6c5589de987c1c1bdd3d7fe781d8
DIFF: https://github.com/llvm/llvm-project/commit/91105df3dfeb6c5589de987c1c1bdd3d7fe781d8.diff

LOG: [DAG] Peek through zext/trunc when matching (or (and X, (not Y)), Y).

This shows up in the wild, notably as a regression in D127115 .

Depends on D147821

Reviewed By: RKSimon

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 84c06321e4cc4..5f3c652750cd9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7449,24 +7449,39 @@ SDValue DAGCombiner::visitORLike(SDValue N0, SDValue N1, SDNode *N) {
 static SDValue visitORCommutative(SelectionDAG &DAG, SDValue N0, SDValue N1,
                                   SDNode *N) {
   EVT VT = N0.getValueType();
-  if (N0.getOpcode() == ISD::AND) {
-    SDValue N00 = N0.getOperand(0);
-    SDValue N01 = N0.getOperand(1);
+
+  auto peekThroughResize = [](SDValue V) {
+    if (V->getOpcode() == ISD::ZERO_EXTEND || V->getOpcode() == ISD::TRUNCATE)
+      return V->getOperand(0);
+    return V;
+  };
+
+  SDValue N0Resized = peekThroughResize(N0);
+  if (N0Resized.getOpcode() == ISD::AND) {
+    SDValue N1Resized = peekThroughResize(N1);
+    SDValue N00 = N0Resized.getOperand(0);
+    SDValue N01 = N0Resized.getOperand(1);
 
     // fold or (and x, y), x --> x
-    if (N00 == N1 || N01 == N1)
+    if (N00 == N1Resized || N01 == N1Resized)
       return N1;
 
     // fold (or (and X, (xor Y, -1)), Y) -> (or X, Y)
     // TODO: Set AllowUndefs = true.
-    if (getBitwiseNotOperand(N01, N00,
-                             /* AllowUndefs */ false) == N1)
-      return DAG.getNode(ISD::OR, SDLoc(N), VT, N00, N1);
+    if (SDValue NotOperand = getBitwiseNotOperand(N01, N00,
+                                                  /* AllowUndefs */ false)) {
+      if (peekThroughResize(NotOperand) == N1Resized)
+        return DAG.getNode(ISD::OR, SDLoc(N), VT,
+                           DAG.getZExtOrTrunc(N00, SDLoc(N), VT), N1);
+    }
 
     // fold (or (and (xor Y, -1), X), Y) -> (or X, Y)
-    if (getBitwiseNotOperand(N00, N01,
-                             /* AllowUndefs */ false) == N1)
-      return DAG.getNode(ISD::OR, SDLoc(N), VT, N01, N1);
+    if (SDValue NotOperand = getBitwiseNotOperand(N00, N01,
+                                                  /* AllowUndefs */ false)) {
+      if (peekThroughResize(NotOperand) == N1Resized)
+        return DAG.getNode(ISD::OR, SDLoc(N), VT,
+                           DAG.getZExtOrTrunc(N01, SDLoc(N), VT), N1);
+    }
   }
 
   if (N0.getOpcode() == ISD::XOR) {

diff  --git a/llvm/test/CodeGen/X86/add-and-not.ll b/llvm/test/CodeGen/X86/add-and-not.ll
index 4f2a3074dabbb..10e3a6bf6d533 100644
--- a/llvm/test/CodeGen/X86/add-and-not.ll
+++ b/llvm/test/CodeGen/X86/add-and-not.ll
@@ -318,10 +318,8 @@ define i64 @add_and_xor_const_zext_trunc(i64 %x) {
 ;
 ; X64-LABEL: add_and_xor_const_zext_trunc:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    notl %eax
-; X64-NEXT:    andl $1, %eax
-; X64-NEXT:    orq %rdi, %rax
+; X64-NEXT:    movq %rdi, %rax
+; X64-NEXT:    orq $1, %rax
 ; X64-NEXT:    retq
   %t = trunc i64 %x to i32
   %xor = xor i32 %t, -1
@@ -341,9 +339,7 @@ define i64 @add_and_xor_const_zext_trunc_var(i64 %x, i64 %y) {
 ;
 ; X64-LABEL: add_and_xor_const_zext_trunc_var:
 ; X64:       # %bb.0:
-; X64-NEXT:    movl %edi, %eax
-; X64-NEXT:    notl %eax
-; X64-NEXT:    andl %esi, %eax
+; X64-NEXT:    movl %esi, %eax
 ; X64-NEXT:    orq %rdi, %rax
 ; X64-NEXT:    retq
   %tx = trunc i64 %x to i32


        


More information about the llvm-commits mailing list