[llvm] [AArch64] Extend SBC combine to handle CSET HI (PR #192708)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 11:19:13 PDT 2026
https://github.com/edisongz updated https://github.com/llvm/llvm-project/pull/192708
>From ef9243852d46559795249d8ca1c811490c492aba Mon Sep 17 00:00:00 2001
From: Yijie Jiang <edisongz123 at gmail.com>
Date: Sat, 18 Apr 2026 02:05:31 +0800
Subject: [PATCH 1/2] [AArch64] Extend SBC combine to handle CSET HI
The `performSubWithBorrowCombine` previously only matched `CSET LO` (unsigned <).
This extends it to also handle `CSET HI` (unsigned >) by swapping the `SUBS`
operands, since `a > b` is equivalent to `b < a`.
This resolves the FIXME left in the test from #165271.
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 12 +++++++++++-
llvm/test/CodeGen/AArch64/sbc.ll | 7 ++-----
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 24d5ce1b9e167..d1a82254606b8 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -23100,6 +23100,7 @@ static SDValue performExtBinopLoadFold(SDNode *N, SelectionDAG &DAG) {
// Attempt to combine the following patterns:
// SUB x, (CSET LO, (CMP a, b)) -> SBC x, 0, (CMP a, b)
// SUB (SUB x, y), (CSET LO, (CMP a, b)) -> SBC x, y, (CMP a, b)
+// Also handles CSET HI by swapping the CMP operands (a > b ≡ b < a).
// The CSET may be preceded by a ZEXT.
static SDValue performSubWithBorrowCombine(SDNode *N, SelectionDAG &DAG) {
if (N->getOpcode() != ISD::SUB)
@@ -23112,13 +23113,22 @@ static SDValue performSubWithBorrowCombine(SDNode *N, SelectionDAG &DAG) {
SDValue N1 = N->getOperand(1);
if (N1.getOpcode() == ISD::ZERO_EXTEND && N1.hasOneUse())
N1 = N1.getOperand(0);
- if (!N1.hasOneUse() || getCSETCondCode(N1) != AArch64CC::LO)
+ auto CC = getCSETCondCode(N1);
+ if (!N1.hasOneUse() || (CC != AArch64CC::LO && CC != AArch64CC::HI))
return SDValue();
SDValue Flags = N1.getOperand(3);
if (Flags.getOpcode() != AArch64ISD::SUBS)
return SDValue();
+ // For HI (unsigned >), swap the SUBS operands to obtain LO (unsigned <).
+ if (CC == AArch64CC::HI) {
+ Flags = DAG.getNode(AArch64ISD::SUBS, SDLoc(Flags),
+ DAG.getVTList(VT, FlagsVT),
+ Flags.getOperand(1), Flags.getOperand(0));
+ Flags = Flags.getValue(1);
+ }
+
SDLoc DL(N);
SDValue N0 = N->getOperand(0);
if (N0->getOpcode() == ISD::SUB)
diff --git a/llvm/test/CodeGen/AArch64/sbc.ll b/llvm/test/CodeGen/AArch64/sbc.ll
index fff63c1709218..08f90eda41ff6 100644
--- a/llvm/test/CodeGen/AArch64/sbc.ll
+++ b/llvm/test/CodeGen/AArch64/sbc.ll
@@ -129,14 +129,11 @@ define i32 @test_sext_add(i32 %a, i32 %b, i32 %x, i32 %y) {
ret i32 %res
}
-; FIXME: This case could be supported with reversed operands to the CMP.
define i32 @test_ugt(i32 %a, i32 %b, i32 %x, i32 %y) {
; CHECK-SD-LABEL: test_ugt:
; CHECK-SD: // %bb.0:
-; CHECK-SD-NEXT: cmp w0, w1
-; CHECK-SD-NEXT: sub w8, w2, w3
-; CHECK-SD-NEXT: cset w9, hi
-; CHECK-SD-NEXT: sub w0, w8, w9
+; CHECK-SD-NEXT: cmp w1, w0
+; CHECK-SD-NEXT: sbc w0, w2, w3
; CHECK-SD-NEXT: ret
;
; CHECK-GI-LABEL: test_ugt:
>From 771f52be8e2ade23f91d17fd3cb78cbd0b26064a Mon Sep 17 00:00:00 2001
From: Yijie Jiang <edisongz123 at gmail.com>
Date: Sat, 18 Apr 2026 02:18:52 +0800
Subject: [PATCH 2/2] Apply code formatter
---
llvm/lib/Target/AArch64/AArch64ISelLowering.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d1a82254606b8..4a8aa4945e050 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -23123,9 +23123,9 @@ static SDValue performSubWithBorrowCombine(SDNode *N, SelectionDAG &DAG) {
// For HI (unsigned >), swap the SUBS operands to obtain LO (unsigned <).
if (CC == AArch64CC::HI) {
- Flags = DAG.getNode(AArch64ISD::SUBS, SDLoc(Flags),
- DAG.getVTList(VT, FlagsVT),
- Flags.getOperand(1), Flags.getOperand(0));
+ Flags =
+ DAG.getNode(AArch64ISD::SUBS, SDLoc(Flags), DAG.getVTList(VT, FlagsVT),
+ Flags.getOperand(1), Flags.getOperand(0));
Flags = Flags.getValue(1);
}
More information about the llvm-commits
mailing list