[llvm] [SDAG] Combine select into ABD?, for const (PR #173581)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 25 14:02:37 PST 2025
https://github.com/DaKnig created https://github.com/llvm/llvm-project/pull/173581
(select (setcc ...) (sub a, b) (sub b, a))
When b is const, the `sub a, b` becomes `add a, -b` which we take care
of in this patch
>From 3d9e0c66c36ae4bc0854b10e2079261a10d1566c Mon Sep 17 00:00:00 2001
From: DaKnig <37626476+DaKnig at users.noreply.github.com>
Date: Thu, 25 Dec 2025 23:59:54 +0200
Subject: [PATCH 1/3] [SDAG] ABD? from select const
(select (setcc ...) (sub a, b) (sub b, a))
When b is const, the `sub a, b` becomes `add a, -b` which we take care
of in this patch
>From b3c14f1b0fb1615baaf7d23039c8f5ec6d8f7ab3 Mon Sep 17 00:00:00 2001
From: DaKnig <37626476+DaKnig at users.noreply.github.com>
Date: Fri, 26 Dec 2025 00:00:11 +0200
Subject: [PATCH 2/3] New test
---
llvm/test/CodeGen/AArch64/arm64-vabs.ll | 115 ++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
index 4d5542ab2d2e6..ace22b5e5b527 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
@@ -2019,6 +2019,121 @@ define <16 x i16> @uabd16b_i16(<16 x i8> %a, <16 x i8> %b) {
ret <16 x i16> %absel
}
+
+define <16 x i16> @uabd16b_i16_const_select(<16 x i8> %a) {
+; CHECK-SD-LABEL: uabd16b_i16_const_select:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: adrp x8, .LCPI106_1
+; CHECK-SD-NEXT: ushll2.8h v4, v0, #0
+; CHECK-SD-NEXT: ushll.8h v2, v0, #0
+; CHECK-SD-NEXT: ldr q1, [x8, :lo12:.LCPI106_1]
+; CHECK-SD-NEXT: adrp x8, .LCPI106_2
+; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI106_2]
+; CHECK-SD-NEXT: adrp x8, .LCPI106_3
+; CHECK-SD-NEXT: ldr q5, [x8, :lo12:.LCPI106_3]
+; CHECK-SD-NEXT: adrp x8, .LCPI106_0
+; CHECK-SD-NEXT: cmhi.8h v2, v1, v2
+; CHECK-SD-NEXT: ldr q6, [x8, :lo12:.LCPI106_0]
+; CHECK-SD-NEXT: uaddw2.8h v3, v3, v0
+; CHECK-SD-NEXT: usubw.8h v7, v1, v0
+; CHECK-SD-NEXT: uaddw.8h v5, v5, v0
+; CHECK-SD-NEXT: cmhi.8h v4, v6, v4
+; CHECK-SD-NEXT: usubw2.8h v0, v6, v0
+; CHECK-SD-NEXT: mov.16b v1, v4
+; CHECK-SD-NEXT: bsl.16b v1, v0, v3
+; CHECK-SD-NEXT: mov.16b v0, v2
+; CHECK-SD-NEXT: bsl.16b v0, v7, v5
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: uabd16b_i16_const_select:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI106_1
+; CHECK-GI-NEXT: mov d3, v0[1]
+; CHECK-GI-NEXT: ushll.8h v4, v0, #0
+; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI106_1]
+; CHECK-GI-NEXT: adrp x8, .LCPI106_0
+; CHECK-GI-NEXT: ushll2.8h v6, v0, #0
+; CHECK-GI-NEXT: ldr d2, [x8, :lo12:.LCPI106_0]
+; CHECK-GI-NEXT: ushll.8h v5, v1, #0
+; CHECK-GI-NEXT: usubl.8h v16, v0, v1
+; CHECK-GI-NEXT: usubl.8h v1, v1, v0
+; CHECK-GI-NEXT: ushll.8h v7, v2, #0
+; CHECK-GI-NEXT: usubl.8h v2, v3, v2
+; CHECK-GI-NEXT: cmhi.8h v3, v5, v4
+; CHECK-GI-NEXT: cmhi.8h v4, v7, v6
+; CHECK-GI-NEXT: usubw2.8h v5, v7, v0
+; CHECK-GI-NEXT: mov.16b v0, v3
+; CHECK-GI-NEXT: bsl.16b v0, v1, v16
+; CHECK-GI-NEXT: mov.16b v1, v4
+; CHECK-GI-NEXT: bsl.16b v1, v5, v2
+; CHECK-GI-NEXT: ret
+ %aext = zext <16 x i8> %a to <16 x i16>
+ %bext = zext <16 x i8> <i8 39, i8 42, i8 51, i8 51, i8 0, i8 0, i8 54, i8 57, i8 66, i8 69, i8 75, i8 69, i8 75, i8 81, i8 255, i8 99> to <16 x i16>
+ %neg.bext = sub <16 x i16> splat (i16 0), %bext
+ %abdiff = add nsw <16 x i16> %aext, %neg.bext
+ %abcmp = icmp ult <16 x i16> %aext, %bext
+ %ababs = sub nsw <16 x i16> %bext, %aext
+ %absel = select <16 x i1> %abcmp, <16 x i16> %ababs, <16 x i16> %abdiff
+ ret <16 x i16> %absel
+}
+
+define <16 x i16> @sabd16b_i16_const_select(<16 x i8> %a) {
+; CHECK-SD-LABEL: sabd16b_i16_const_select:
+; CHECK-SD: // %bb.0:
+; CHECK-SD-NEXT: adrp x8, .LCPI107_1
+; CHECK-SD-NEXT: sshll2.8h v4, v0, #0
+; CHECK-SD-NEXT: sshll.8h v2, v0, #0
+; CHECK-SD-NEXT: ldr q1, [x8, :lo12:.LCPI107_1]
+; CHECK-SD-NEXT: adrp x8, .LCPI107_2
+; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI107_2]
+; CHECK-SD-NEXT: adrp x8, .LCPI107_3
+; CHECK-SD-NEXT: ldr q5, [x8, :lo12:.LCPI107_3]
+; CHECK-SD-NEXT: adrp x8, .LCPI107_0
+; CHECK-SD-NEXT: cmgt.8h v2, v1, v2
+; CHECK-SD-NEXT: ldr q6, [x8, :lo12:.LCPI107_0]
+; CHECK-SD-NEXT: saddw2.8h v3, v3, v0
+; CHECK-SD-NEXT: ssubw.8h v7, v1, v0
+; CHECK-SD-NEXT: saddw.8h v5, v5, v0
+; CHECK-SD-NEXT: cmgt.8h v4, v6, v4
+; CHECK-SD-NEXT: ssubw2.8h v0, v6, v0
+; CHECK-SD-NEXT: mov.16b v1, v4
+; CHECK-SD-NEXT: bsl.16b v1, v0, v3
+; CHECK-SD-NEXT: mov.16b v0, v2
+; CHECK-SD-NEXT: bsl.16b v0, v7, v5
+; CHECK-SD-NEXT: ret
+;
+; CHECK-GI-LABEL: sabd16b_i16_const_select:
+; CHECK-GI: // %bb.0:
+; CHECK-GI-NEXT: adrp x8, .LCPI107_1
+; CHECK-GI-NEXT: mov d3, v0[1]
+; CHECK-GI-NEXT: sshll.8h v4, v0, #0
+; CHECK-GI-NEXT: ldr d1, [x8, :lo12:.LCPI107_1]
+; CHECK-GI-NEXT: adrp x8, .LCPI107_0
+; CHECK-GI-NEXT: sshll2.8h v6, v0, #0
+; CHECK-GI-NEXT: ldr d2, [x8, :lo12:.LCPI107_0]
+; CHECK-GI-NEXT: sshll.8h v5, v1, #0
+; CHECK-GI-NEXT: ssubl.8h v16, v0, v1
+; CHECK-GI-NEXT: ssubl.8h v1, v1, v0
+; CHECK-GI-NEXT: sshll.8h v7, v2, #0
+; CHECK-GI-NEXT: ssubl.8h v2, v3, v2
+; CHECK-GI-NEXT: cmgt.8h v3, v5, v4
+; CHECK-GI-NEXT: cmgt.8h v4, v7, v6
+; CHECK-GI-NEXT: ssubw2.8h v5, v7, v0
+; CHECK-GI-NEXT: mov.16b v0, v3
+; CHECK-GI-NEXT: bsl.16b v0, v1, v16
+; CHECK-GI-NEXT: mov.16b v1, v4
+; CHECK-GI-NEXT: bsl.16b v1, v5, v2
+; CHECK-GI-NEXT: ret
+ %aext = sext <16 x i8> %a to <16 x i16>
+ %bext = sext <16 x i8> <i8 -39, i8 42, i8 -51, i8 51, i8 0, i8 0, i8 -54, i8 57, i8 -66, i8 69, i8 75, i8 69, i8 75, i8 81, i8 -128, i8 99> to <16 x i16>
+ %neg.bext = sub <16 x i16> splat (i16 0), %bext
+ %abdiff = add nsw <16 x i16> %aext, %neg.bext
+ %abcmp = icmp slt <16 x i16> %aext, %bext
+ %ababs = sub nsw <16 x i16> %bext, %aext
+ %absel = select <16 x i1> %abcmp, <16 x i16> %ababs, <16 x i16> %abdiff
+ ret <16 x i16> %absel
+}
+
define <16 x i16> @sabd16b_i16_ext(<16 x i16> %aext, <16 x i8> %b) {
; CHECK-SD-LABEL: sabd16b_i16_ext:
; CHECK-SD: // %bb.0:
>From 94a355d4573208b6fbd14b440638fa153099fb66 Mon Sep 17 00:00:00 2001
From: DaKnig <37626476+DaKnig at users.noreply.github.com>
Date: Fri, 26 Dec 2025 00:00:18 +0200
Subject: [PATCH 3/3] pattern
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 30 ++++++++---
llvm/test/CodeGen/AArch64/arm64-vabs.ll | 52 +++++--------------
2 files changed, 36 insertions(+), 46 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index ff1e8af8b6c2e..ff56b534b3630 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -12360,17 +12360,27 @@ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
if (LegalOperations && !hasOperation(ABDOpc, VT))
return SDValue();
+ if (!VT.isInteger())
+ return SDValue();
+
+ // Hack to support constants. (sub a, const) becomes (add a, -const)
+ SDValue NegRHS = DAG.getNegative(RHS, SDLoc(RHS), VT),
+ NegLHS = DAG.getNegative(LHS, SDLoc(LHS), VT);
switch (CC) {
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))))
+ if (sd_match(True, m_AnyOf(m_Sub(m_Specific(LHS), m_Specific(RHS)),
+ m_Add(m_Specific(LHS), m_Specific(NegRHS)))) &&
+ sd_match(False, m_AnyOf(m_Sub(m_Specific(RHS), m_Specific(LHS)),
+ m_Add(m_Specific(RHS), m_Specific(NegLHS)))))
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))) &&
+ if (sd_match(True, m_AnyOf(m_Sub(m_Specific(RHS), m_Specific(LHS)),
+ m_Add(m_Specific(RHS), m_Specific(NegLHS)))) &&
+ sd_match(False, m_AnyOf(m_Sub(m_Specific(LHS), m_Specific(RHS)),
+ m_Add(m_Specific(LHS), m_Specific(NegRHS)))) &&
hasOperation(ABDOpc, VT))
return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
break;
@@ -12378,11 +12388,15 @@ SDValue DAGCombiner::foldSelectToABD(SDValue LHS, SDValue RHS, SDValue True,
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))))
+ if (sd_match(True, m_AnyOf(m_Sub(m_Specific(RHS), m_Specific(LHS)),
+ m_Add(m_Specific(RHS), m_Specific(NegLHS)))) &&
+ sd_match(False, m_AnyOf(m_Sub(m_Specific(LHS), m_Specific(RHS)),
+ m_Add(m_Specific(LHS), m_Specific(NegRHS)))))
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))) &&
+ if (sd_match(True, m_AnyOf(m_Sub(m_Specific(LHS), m_Specific(RHS)),
+ m_Add(m_Specific(LHS), m_Specific(NegRHS)))) &&
+ sd_match(False, m_AnyOf(m_Sub(m_Specific(RHS), m_Specific(LHS)),
+ m_Add(m_Specific(RHS), m_Specific(NegLHS)))) &&
hasOperation(ABDOpc, VT))
return DAG.getNegative(DAG.getNode(ABDOpc, DL, VT, LHS, RHS), DL, VT);
break;
diff --git a/llvm/test/CodeGen/AArch64/arm64-vabs.ll b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
index ace22b5e5b527..3271b2f49cbbf 100644
--- a/llvm/test/CodeGen/AArch64/arm64-vabs.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-vabs.ll
@@ -2023,26 +2023,14 @@ define <16 x i16> @uabd16b_i16(<16 x i8> %a, <16 x i8> %b) {
define <16 x i16> @uabd16b_i16_const_select(<16 x i8> %a) {
; CHECK-SD-LABEL: uabd16b_i16_const_select:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: adrp x8, .LCPI106_1
-; CHECK-SD-NEXT: ushll2.8h v4, v0, #0
-; CHECK-SD-NEXT: ushll.8h v2, v0, #0
-; CHECK-SD-NEXT: ldr q1, [x8, :lo12:.LCPI106_1]
-; CHECK-SD-NEXT: adrp x8, .LCPI106_2
-; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI106_2]
-; CHECK-SD-NEXT: adrp x8, .LCPI106_3
-; CHECK-SD-NEXT: ldr q5, [x8, :lo12:.LCPI106_3]
; CHECK-SD-NEXT: adrp x8, .LCPI106_0
-; CHECK-SD-NEXT: cmhi.8h v2, v1, v2
-; CHECK-SD-NEXT: ldr q6, [x8, :lo12:.LCPI106_0]
-; CHECK-SD-NEXT: uaddw2.8h v3, v3, v0
-; CHECK-SD-NEXT: usubw.8h v7, v1, v0
-; CHECK-SD-NEXT: uaddw.8h v5, v5, v0
-; CHECK-SD-NEXT: cmhi.8h v4, v6, v4
-; CHECK-SD-NEXT: usubw2.8h v0, v6, v0
-; CHECK-SD-NEXT: mov.16b v1, v4
-; CHECK-SD-NEXT: bsl.16b v1, v0, v3
-; CHECK-SD-NEXT: mov.16b v0, v2
-; CHECK-SD-NEXT: bsl.16b v0, v7, v5
+; CHECK-SD-NEXT: ushll.8h v2, v0, #0
+; CHECK-SD-NEXT: ushll2.8h v0, v0, #0
+; CHECK-SD-NEXT: adrp x9, .LCPI106_1
+; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI106_0]
+; CHECK-SD-NEXT: ldr q1, [x9, :lo12:.LCPI106_1]
+; CHECK-SD-NEXT: uabd.8h v1, v0, v1
+; CHECK-SD-NEXT: uabd.8h v0, v2, v3
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: uabd16b_i16_const_select:
@@ -2080,26 +2068,14 @@ define <16 x i16> @uabd16b_i16_const_select(<16 x i8> %a) {
define <16 x i16> @sabd16b_i16_const_select(<16 x i8> %a) {
; CHECK-SD-LABEL: sabd16b_i16_const_select:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: adrp x8, .LCPI107_1
-; CHECK-SD-NEXT: sshll2.8h v4, v0, #0
-; CHECK-SD-NEXT: sshll.8h v2, v0, #0
-; CHECK-SD-NEXT: ldr q1, [x8, :lo12:.LCPI107_1]
-; CHECK-SD-NEXT: adrp x8, .LCPI107_2
-; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI107_2]
-; CHECK-SD-NEXT: adrp x8, .LCPI107_3
-; CHECK-SD-NEXT: ldr q5, [x8, :lo12:.LCPI107_3]
; CHECK-SD-NEXT: adrp x8, .LCPI107_0
-; CHECK-SD-NEXT: cmgt.8h v2, v1, v2
-; CHECK-SD-NEXT: ldr q6, [x8, :lo12:.LCPI107_0]
-; CHECK-SD-NEXT: saddw2.8h v3, v3, v0
-; CHECK-SD-NEXT: ssubw.8h v7, v1, v0
-; CHECK-SD-NEXT: saddw.8h v5, v5, v0
-; CHECK-SD-NEXT: cmgt.8h v4, v6, v4
-; CHECK-SD-NEXT: ssubw2.8h v0, v6, v0
-; CHECK-SD-NEXT: mov.16b v1, v4
-; CHECK-SD-NEXT: bsl.16b v1, v0, v3
-; CHECK-SD-NEXT: mov.16b v0, v2
-; CHECK-SD-NEXT: bsl.16b v0, v7, v5
+; CHECK-SD-NEXT: sshll.8h v2, v0, #0
+; CHECK-SD-NEXT: sshll2.8h v0, v0, #0
+; CHECK-SD-NEXT: adrp x9, .LCPI107_1
+; CHECK-SD-NEXT: ldr q3, [x8, :lo12:.LCPI107_0]
+; CHECK-SD-NEXT: ldr q1, [x9, :lo12:.LCPI107_1]
+; CHECK-SD-NEXT: sabd.8h v1, v0, v1
+; CHECK-SD-NEXT: sabd.8h v0, v2, v3
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: sabd16b_i16_const_select:
More information about the llvm-commits
mailing list