[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