[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