[llvm] [DAGCombiner] Add pattern matching for negated subtraction in ABDU selection (PR #156217)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 30 18:45:49 PDT 2025


https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/156217

>From 764f19e786ac42701c04f8d26247d42c4501f344 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 30 Aug 2025 21:28:20 -0400
Subject: [PATCH 1/2] Pre-commit test (NFC)

---
 llvm/test/CodeGen/X86/abdu.ll | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/llvm/test/CodeGen/X86/abdu.ll b/llvm/test/CodeGen/X86/abdu.ll
index 043c9155f52f9..b9e01fda29615 100644
--- a/llvm/test/CodeGen/X86/abdu.ll
+++ b/llvm/test/CodeGen/X86/abdu.ll
@@ -953,6 +953,33 @@ define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
   ret i128 %sub
 }
 
+define i32 @abdu_select(i32 %x, i32 %y) {
+; X86-LABEL: abdu_select:
+; X86:       # %bb.0:
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT:    movl %eax, %edx
+; X86-NEXT:    subl %ecx, %edx
+; X86-NEXT:    negl %edx
+; X86-NEXT:    subl %ecx, %eax
+; X86-NEXT:    cmovbel %edx, %eax
+; X86-NEXT:    retl
+;
+; X64-LABEL: abdu_select:
+; X64:       # %bb.0:
+; X64-NEXT:    movl %edi, %eax
+; X64-NEXT:    subl %esi, %eax
+; X64-NEXT:    negl %eax
+; X64-NEXT:    subl %esi, %edi
+; X64-NEXT:    cmoval %edi, %eax
+; X64-NEXT:    retq
+  %sub = sub i32 %x, %y
+  %cmp = icmp ugt i32 %x, %y
+  %sub1 = sub i32 0, %sub
+  %cond = select i1 %cmp, i32 %sub, i32 %sub1
+  ret i32 %cond
+}
+
 declare i8 @llvm.abs.i8(i8, i1)
 declare i16 @llvm.abs.i16(i16, i1)
 declare i32 @llvm.abs.i32(i32, i1)

>From e88aceacf77ed7276e985f62aec7aaee51848f29 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Sat, 30 Aug 2025 21:37:39 -0400
Subject: [PATCH 2/2] [DAGCombiner] Add pattern matching for negated
 subtraction in ABDU selection

select(ugt x, y), sub(x, y), sub(0, sub(x, y)) -> abdu(x, y)

This is because -diff is the same as y - x.
---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 50 +++++++++++++------
 llvm/test/CodeGen/X86/abdu.ll                 | 12 ++---
 2 files changed, 39 insertions(+), 23 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 55aff0460e7d7..0bef4bdd79aad 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12177,27 +12177,45 @@ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
   case ISD::SETGT:
   case ISD::SETGE:
   case ISD::SETUGT:
-  case ISD::SETUGE:
-    if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS))) &&
-        sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS))))
-      return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
-    if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS))) &&
-        sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS))) &&
-        hasOperation(ABDOpc, VT))
-      return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+  case ISD::SETUGE: {
+    if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS)))) {
+      if (sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS))))
+        return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
+
+      if (sd_match(False, m_Neg(m_Sub(m_Specific(LHS), m_Specific(RHS)))))
+        return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
+    }
+
+    if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS)))) {
+      if (sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS))))
+        return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+
+      if (sd_match(False, m_Neg(m_Sub(m_Specific(RHS), m_Specific(LHS)))))
+        return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+    }
     break;
+  }
   case ISD::SETLT:
   case ISD::SETLE:
   case ISD::SETULT:
-  case ISD::SETULE:
-    if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS))) &&
-        sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS))))
-      return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
-    if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS))) &&
-        sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS))) &&
-        hasOperation(ABDOpc, VT))
-      return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+  case ISD::SETULE: {
+    if (sd_match(True, m_Sub(m_Specific(RHS), m_Specific(LHS)))) {
+      if (sd_match(False, m_Sub(m_Specific(LHS), m_Specific(RHS))))
+        return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
+
+      if (sd_match(False, m_Neg(m_Sub(m_Specific(RHS), m_Specific(LHS)))))
+        return DAG.getNode(ABDOpc, DL, VT, LHS, RHS);
+    }
+
+    if (sd_match(True, m_Sub(m_Specific(LHS), m_Specific(RHS)))) {
+      if (sd_match(False, m_Sub(m_Specific(RHS), m_Specific(LHS))))
+        return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+
+      if (sd_match(False, m_Neg(m_Sub(m_Specific(LHS), m_Specific(RHS)))))
+        return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
+    }
     break;
+  }
   default:
     break;
   }
diff --git a/llvm/test/CodeGen/X86/abdu.ll b/llvm/test/CodeGen/X86/abdu.ll
index b9e01fda29615..1403f4f03ef44 100644
--- a/llvm/test/CodeGen/X86/abdu.ll
+++ b/llvm/test/CodeGen/X86/abdu.ll
@@ -958,20 +958,18 @@ define i32 @abdu_select(i32 %x, i32 %y) {
 ; X86:       # %bb.0:
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl %eax, %edx
-; X86-NEXT:    subl %ecx, %edx
-; X86-NEXT:    negl %edx
+; X86-NEXT:    movl %ecx, %edx
+; X86-NEXT:    subl %eax, %edx
 ; X86-NEXT:    subl %ecx, %eax
-; X86-NEXT:    cmovbel %edx, %eax
+; X86-NEXT:    cmovbl %edx, %eax
 ; X86-NEXT:    retl
 ;
 ; X64-LABEL: abdu_select:
 ; X64:       # %bb.0:
 ; X64-NEXT:    movl %edi, %eax
 ; X64-NEXT:    subl %esi, %eax
-; X64-NEXT:    negl %eax
-; X64-NEXT:    subl %esi, %edi
-; X64-NEXT:    cmoval %edi, %eax
+; X64-NEXT:    subl %edi, %esi
+; X64-NEXT:    cmovael %esi, %eax
 ; X64-NEXT:    retq
   %sub = sub i32 %x, %y
   %cmp = icmp ugt i32 %x, %y



More information about the llvm-commits mailing list