[llvm] [TargetLowering][ExpandABD] Prefer selects over usubo if we do the same for ucmp (PR #159889)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Sep 20 08:16:11 PDT 2025
https://github.com/AZero13 updated https://github.com/llvm/llvm-project/pull/159889
>From 381bab5e04221655376e78eb648139b1ca68e1f7 Mon Sep 17 00:00:00 2001
From: AZero13 <gfunni234 at gmail.com>
Date: Fri, 19 Sep 2025 21:12:39 -0400
Subject: [PATCH] [TargetLowering] Prefer selects over usubo
Same deal we use for determining ucmp vs scmp.
---
.../CodeGen/SelectionDAG/TargetLowering.cpp | 11 ++--
llvm/test/CodeGen/AArch64/abdu-neg.ll | 24 ++++----
llvm/test/CodeGen/AArch64/abdu.ll | 60 ++++++++-----------
3 files changed, 41 insertions(+), 54 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index 80500e48351e4..05ebd59f4a8a9 100644
--- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -9775,11 +9775,12 @@ SDValue TargetLowering::expandABD(SDNode *N, SelectionDAG &DAG) const {
return DAG.getNode(ISD::SUB, dl, VT, Cmp, Xor);
}
- // Similar to the branchless expansion, use the (sign-extended) usubo overflow
- // flag if the (scalar) type is illegal as this is more likely to legalize
- // cleanly:
- // abdu(lhs, rhs) -> sub(xor(sub(lhs, rhs), uof(lhs, rhs)), uof(lhs, rhs))
- if (!IsSigned && VT.isScalarInteger() && !isTypeLegal(VT)) {
+ // Similar to the branchless expansion, if we don't prefer selects, use the
+ // (sign-extended) usubo overflow flag if the (scalar) type is illegal as this
+ // is more likely to legalize cleanly: abdu(lhs, rhs) -> sub(xor(sub(lhs,
+ // rhs), uof(lhs, rhs)), uof(lhs, rhs))
+ if (!IsSigned && VT.isScalarInteger() && !isTypeLegal(VT) &&
+ !shouldExpandCmpUsingSelects(VT)) {
SDValue USubO =
DAG.getNode(ISD::USUBO, dl, DAG.getVTList(VT, MVT::i1), {LHS, RHS});
SDValue Cmp = DAG.getNode(ISD::SIGN_EXTEND, dl, VT, USubO.getValue(1));
diff --git a/llvm/test/CodeGen/AArch64/abdu-neg.ll b/llvm/test/CodeGen/AArch64/abdu-neg.ll
index 79fc12ea76f63..269cbf03f32a0 100644
--- a/llvm/test/CodeGen/AArch64/abdu-neg.ll
+++ b/llvm/test/CodeGen/AArch64/abdu-neg.ll
@@ -180,13 +180,11 @@ define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_ext_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x8, x8, x10
-; CHECK-NEXT: sbc x9, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x8, x8, x10, lo
+; CHECK-NEXT: csel x9, x9, x11, lo
; CHECK-NEXT: negs x0, x8
; CHECK-NEXT: ngc x1, x9
; CHECK-NEXT: ret
@@ -203,13 +201,11 @@ define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_ext_i128_undef:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x8, x8, x10
-; CHECK-NEXT: sbc x9, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x8, x8, x10, lo
+; CHECK-NEXT: csel x9, x9, x11, lo
; CHECK-NEXT: negs x0, x8
; CHECK-NEXT: ngc x1, x9
; CHECK-NEXT: ret
diff --git a/llvm/test/CodeGen/AArch64/abdu.ll b/llvm/test/CodeGen/AArch64/abdu.ll
index 6db7693fb3a1c..3cbe648788a84 100644
--- a/llvm/test/CodeGen/AArch64/abdu.ll
+++ b/llvm/test/CodeGen/AArch64/abdu.ll
@@ -169,13 +169,11 @@ define i128 @abd_ext_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_ext_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x0, x8, x10
-; CHECK-NEXT: sbc x1, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x0, x8, x10, lo
+; CHECK-NEXT: csel x1, x9, x11, lo
; CHECK-NEXT: ret
%aext = zext i128 %a to i256
%bext = zext i128 %b to i256
@@ -189,13 +187,11 @@ define i128 @abd_ext_i128_undef(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_ext_i128_undef:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x0, x8, x10
-; CHECK-NEXT: sbc x1, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x0, x8, x10, lo
+; CHECK-NEXT: csel x1, x9, x11, lo
; CHECK-NEXT: ret
%aext = zext i128 %a to i256
%bext = zext i128 %b to i256
@@ -263,13 +259,11 @@ define i128 @abd_minmax_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_minmax_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x0, x8, x10
-; CHECK-NEXT: sbc x1, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x0, x8, x10, lo
+; CHECK-NEXT: csel x1, x9, x11, lo
; CHECK-NEXT: ret
%min = call i128 @llvm.umin.i128(i128 %a, i128 %b)
%max = call i128 @llvm.umax.i128(i128 %a, i128 %b)
@@ -339,13 +333,11 @@ define i128 @abd_cmp_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_cmp_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x0, x8, x10
-; CHECK-NEXT: sbc x1, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x0, x8, x10, lo
+; CHECK-NEXT: csel x1, x9, x11, lo
; CHECK-NEXT: ret
%cmp = icmp uge i128 %a, %b
%ab = sub i128 %a, %b
@@ -437,13 +429,11 @@ define i128 @abd_select_i128(i128 %a, i128 %b) nounwind {
; CHECK-LABEL: abd_select_i128:
; CHECK: // %bb.0:
; CHECK-NEXT: subs x8, x0, x2
-; CHECK-NEXT: sbcs x9, x1, x3
-; CHECK-NEXT: cset w10, lo
-; CHECK-NEXT: sbfx x10, x10, #0, #1
-; CHECK-NEXT: eor x8, x8, x10
-; CHECK-NEXT: eor x9, x9, x10
-; CHECK-NEXT: subs x0, x8, x10
-; CHECK-NEXT: sbc x1, x9, x10
+; CHECK-NEXT: sbc x9, x1, x3
+; CHECK-NEXT: subs x10, x2, x0
+; CHECK-NEXT: sbcs x11, x3, x1
+; CHECK-NEXT: csel x0, x8, x10, lo
+; CHECK-NEXT: csel x1, x9, x11, lo
; CHECK-NEXT: ret
%cmp = icmp ult i128 %a, %b
%ab = select i1 %cmp, i128 %a, i128 %b
More information about the llvm-commits
mailing list