[llvm] [AArch64] Add SUBS(CSEL) fold from brcond. (PR #142103)
via llvm-commits
llvm-commits at lists.llvm.org
Fri May 30 01:07:50 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
Author: David Green (davemgreen)
<details>
<summary>Changes</summary>
This folds away subs(csel(1, 0, cc)) from brcond, that can be produced in certain places from compares that are not already subs (like adc/sbc generated from i128 add_with_overflow intrinsics).
---
Full diff: https://github.com/llvm/llvm-project/pull/142103.diff
2 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64ISelLowering.cpp (+11)
- (modified) llvm/test/CodeGen/AArch64/i128_with_overflow.ll (+4-12)
``````````diff
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index f18d325148742..ff2bcec78760d 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -24458,6 +24458,17 @@ static SDValue performBRCONDCombine(SDNode *N,
if (CC != AArch64CC::EQ && CC != AArch64CC::NE)
return SDValue();
+ // Fold away brcond(NE, subs(csel(1, 0, CC, Cmp), 1)) -> brcond(CC, Cmp)
+ if (CC == AArch64CC::NE && isCMP(Cmp) && isOneConstant(Cmp.getOperand(1)) &&
+ Cmp.getOperand(0).getOpcode() == AArch64ISD::CSEL) {
+ SDValue CSel = Cmp.getOperand(0);
+ if (isOneConstant(CSel.getOperand(0)) &&
+ isNullConstant(CSel.getOperand(1))) {
+ return DAG.getNode(N->getOpcode(), SDLoc(N), N->getVTList(), Chain, Dest,
+ CSel.getOperand(2), CSel.getOperand(3));
+ }
+ }
+
unsigned CmpOpc = Cmp.getOpcode();
if (CmpOpc != AArch64ISD::ADDS && CmpOpc != AArch64ISD::SUBS)
return SDValue();
diff --git a/llvm/test/CodeGen/AArch64/i128_with_overflow.ll b/llvm/test/CodeGen/AArch64/i128_with_overflow.ll
index e3a8feebaa606..f677b11c1b118 100644
--- a/llvm/test/CodeGen/AArch64/i128_with_overflow.ll
+++ b/llvm/test/CodeGen/AArch64/i128_with_overflow.ll
@@ -10,9 +10,7 @@ define i128 @test_uadd_i128(i128 noundef %x, i128 noundef %y) {
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: adds x0, x0, x2
; CHECK-SD-NEXT: adcs x1, x1, x3
-; CHECK-SD-NEXT: cset w8, hs
-; CHECK-SD-NEXT: cmp w8, #1
-; CHECK-SD-NEXT: b.ne .LBB0_2
+; CHECK-SD-NEXT: b.hs .LBB0_2
; CHECK-SD-NEXT: // %bb.1: // %if.then
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
@@ -66,9 +64,7 @@ define i128 @test_sadd_i128(i128 noundef %x, i128 noundef %y) {
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: adds x0, x0, x2
; CHECK-SD-NEXT: adcs x1, x1, x3
-; CHECK-SD-NEXT: cset w8, vs
-; CHECK-SD-NEXT: cmp w8, #1
-; CHECK-SD-NEXT: b.ne .LBB1_2
+; CHECK-SD-NEXT: b.vs .LBB1_2
; CHECK-SD-NEXT: // %bb.1: // %if.then
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
@@ -122,9 +118,7 @@ define i128 @test_usub_i128(i128 noundef %x, i128 noundef %y) {
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: subs x0, x0, x2
; CHECK-SD-NEXT: sbcs x1, x1, x3
-; CHECK-SD-NEXT: cset w8, lo
-; CHECK-SD-NEXT: cmp w8, #1
-; CHECK-SD-NEXT: b.ne .LBB2_2
+; CHECK-SD-NEXT: b.lo .LBB2_2
; CHECK-SD-NEXT: // %bb.1: // %if.then
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
@@ -178,9 +172,7 @@ define i128 @test_ssub_i128(i128 noundef %x, i128 noundef %y) {
; CHECK-SD: // %bb.0: // %entry
; CHECK-SD-NEXT: subs x0, x0, x2
; CHECK-SD-NEXT: sbcs x1, x1, x3
-; CHECK-SD-NEXT: cset w8, vs
-; CHECK-SD-NEXT: cmp w8, #1
-; CHECK-SD-NEXT: b.ne .LBB3_2
+; CHECK-SD-NEXT: b.vs .LBB3_2
; CHECK-SD-NEXT: // %bb.1: // %if.then
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
``````````
</details>
https://github.com/llvm/llvm-project/pull/142103
More information about the llvm-commits
mailing list