[llvm] [AArch64] Decouple -aarch64-code-layout-opt-enable= from the Subtarget (PR #215044)

Jon Roelofs via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 16:06:48 PDT 2026


https://github.com/jroelofs updated https://github.com/llvm/llvm-project/pull/215044

>From 03fc09650ae8368e4c99f49ed5c6f84f8c77b1aa Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Sat, 8 Aug 2026 18:05:33 -0700
Subject: [PATCH 1/2] [AArch64] Decouple -aarch64-code-layout-opt-enable= from
 the Subtarget

This fixes a bug that would permanently enable the pass for all functions
encountered after observing one with the tuning attribute, as the pass would
mutate the cl::bits's value in response to the Subtarget features.

With the command line flag decoupled from the Subtarget, we also open up easier
experimentation on enabling or disabling the optimizations individually,
independent of whether the Subtarget has the feature or not.
---
 .../Target/AArch64/AArch64CodeLayoutOpt.cpp   |  51 ++-
 llvm/test/CodeGen/AArch64/code-layout-opt.ll  | 333 ++++++++++++------
 2 files changed, 266 insertions(+), 118 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
index 92ebd8592f854..e3bb52f014b69 100644
--- a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
@@ -21,6 +21,7 @@
 #include "AArch64.h"
 #include "AArch64InstrInfo.h"
 #include "AArch64Subtarget.h"
+#include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
@@ -37,14 +38,17 @@ using namespace llvm;
 #define AARCH64_CODE_LAYOUT_OPT_NAME "AArch64 Code Layout Optimization"
 
 enum CodeLayoutOpt {
-  CmpCsel,   // Align CMP/CMN-CSEL pairs
-  FcmpFcsel, // Align FCMP-FCSEL pairs
+  None = 0,
+  CmpCsel = 1 << 0,   // Align CMP/CMN-CSEL pairs
+  FcmpFcsel = 1 << 1, // Align FCMP-FCSEL pairs
+  LLVM_MARK_AS_BITMASK_ENUM(FcmpFcsel)
 };
 
 static cl::bits<CodeLayoutOpt> EnableCodeAlignment(
     "aarch64-code-layout-opt-enable", cl::Hidden, cl::CommaSeparated,
     cl::desc("Enable code alignment optimization for instruction pairs"),
     cl::values(
+        clEnumValN(None, "none", "Disable the code alignment pass"),
         clEnumValN(CmpCsel, "cmp-csel", "CMP/CMN-CSEL pair alignment (32-bit)"),
         clEnumValN(FcmpFcsel, "fcmp-fcsel", "FCMP-FCSEL pair alignment")));
 
@@ -83,13 +87,13 @@ class AArch64CodeLayoutOpt : public MachineFunctionPass {
   /// Align each fusible CMP/CMN-CSEL or FCMP-FCSEL pair in \p MBB by emitting
   /// .p2align before the lead instruction (splitting the block if needed).
   /// \returns true iff at least one pair was found and aligned.
-  bool alignLayoutSensitivePatterns(MachineBasicBlock *MBB);
+  bool alignLayoutSensitivePatterns(MachineBasicBlock *MBB, CodeLayoutOpt CLO);
 
   /// Emit .p2align before MI. Splits the block if MI is not at its start.
   void emitP2Align(MachineInstr &MI, Align DesiredAlign,
                    unsigned MaxSkipBytes = 4);
 
-  bool optimizeForCodeLayout(MachineFunction &MF);
+  bool optimizeForCodeLayout(MachineFunction &MF, CodeLayoutOpt CLO);
 };
 
 } // end anonymous namespace
@@ -169,19 +173,27 @@ bool AArch64CodeLayoutOpt::runOnMachineFunction(MachineFunction &MF) {
   const auto *Subtarget = &MF.getSubtarget<AArch64Subtarget>();
   TII = Subtarget->getInstrInfo();
 
-  // Default: enable when the subtarget opts in via FeatureAlignCmpCSelPairs.
-  if (!EnableCodeAlignment.getBits() && Subtarget->hasAlignCmpCSelPairs()) {
-    if (Subtarget->hasFuseCmpCSel())
-      EnableCodeAlignment.addValue(CmpCsel);
-    if (Subtarget->hasFuseFCmpFCSel())
-      EnableCodeAlignment.addValue(FcmpFcsel);
+  CodeLayoutOpt CLO = None;
+  if (EnableCodeAlignment.getNumOccurrences()) {
+    if (EnableCodeAlignment.isSet(CodeLayoutOpt::CmpCsel))
+      CLO |= CodeLayoutOpt::CmpCsel;
+
+    if (EnableCodeAlignment.isSet(CodeLayoutOpt::FcmpFcsel))
+      CLO |= CodeLayoutOpt::FcmpFcsel;
+  } else {
+    // Default: enable when the subtarget opts in via FeatureAlignCmpCSelPairs.
+    if (Subtarget->hasAlignCmpCSelPairs()) {
+      if (Subtarget->hasFuseCmpCSel())
+        CLO |= CodeLayoutOpt::CmpCsel;
+      if (Subtarget->hasFuseFCmpFCSel())
+        CLO |= CodeLayoutOpt::FcmpFcsel;
+    }
   }
 
-  if (!(EnableCodeAlignment.isSet(CmpCsel) && Subtarget->hasFuseCmpCSel()) &&
-      !(EnableCodeAlignment.isSet(FcmpFcsel) && Subtarget->hasFuseFCmpFCSel()))
+  if (CLO == None)
     return false;
 
-  return optimizeForCodeLayout(MF);
+  return optimizeForCodeLayout(MF, CLO);
 }
 
 void AArch64CodeLayoutOpt::emitP2Align(MachineInstr &MI, Align DesiredAlign,
@@ -204,8 +216,8 @@ void AArch64CodeLayoutOpt::emitP2Align(MachineInstr &MI, Align DesiredAlign,
 // A pair is: a qualifying lead instruction immediately followed by its
 // consumer (CMP/CMN→CSEL or FCMP→FCSEL), with no intervening instructions.
 // Returns true iff at least one pair was found and aligned.
-bool AArch64CodeLayoutOpt::alignLayoutSensitivePatterns(
-    MachineBasicBlock *MBB) {
+bool AArch64CodeLayoutOpt::alignLayoutSensitivePatterns(MachineBasicBlock *MBB,
+                                                        CodeLayoutOpt CLO) {
   auto End = MBB->instr_end();
   SmallVector<std::pair<MachineInstr *, bool>, 4> Pairs;
 
@@ -216,14 +228,14 @@ bool AArch64CodeLayoutOpt::alignLayoutSensitivePatterns(
       break;
 
     // --- CMP/CMN-CSEL detection ---
-    if (EnableCodeAlignment.isSet(CmpCsel) && isQualifyingIntCompare(MI) &&
+    if ((CLO & CodeLayoutOpt::CmpCsel) && isQualifyingIntCompare(MI) &&
         NextIt->getOpcode() == AArch64::CSELWr) {
       Pairs.push_back({&MI, true});
       continue;
     }
 
     // --- FCMP-FCSEL detection ---
-    if (EnableCodeAlignment.isSet(FcmpFcsel) &&
+    if ((CLO & CodeLayoutOpt::FcmpFcsel) &&
         isFloatingPointCompare(MI.getOpcode()) &&
         isFloatingPointConditionalSelect(NextIt->getOpcode())) {
       Pairs.push_back({&MI, false});
@@ -240,12 +252,13 @@ bool AArch64CodeLayoutOpt::alignLayoutSensitivePatterns(
   return !Pairs.empty();
 }
 
-bool AArch64CodeLayoutOpt::optimizeForCodeLayout(MachineFunction &MF) {
+bool AArch64CodeLayoutOpt::optimizeForCodeLayout(MachineFunction &MF,
+                                                 CodeLayoutOpt CLO) {
   DBG("optimizeForCodeLayout: " << MF.getName() << "\n");
 
   bool Changed = false;
   for (auto &MBB : MF)
-    Changed |= alignLayoutSensitivePatterns(&MBB);
+    Changed |= alignLayoutSensitivePatterns(&MBB, CLO);
 
   if (!Changed)
     return false;
diff --git a/llvm/test/CodeGen/AArch64/code-layout-opt.ll b/llvm/test/CodeGen/AArch64/code-layout-opt.ll
index adf5b05bd5305..46a684fb233e8 100644
--- a/llvm/test/CodeGen/AArch64/code-layout-opt.ll
+++ b/llvm/test/CodeGen/AArch64/code-layout-opt.ll
@@ -1,8 +1,11 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
 ; NOTE: Test cases for FCMP-FCSEL and CMP/CMN-CSEL code layout optimization
-; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin -mcpu=apple-m4 -aarch64-code-layout-opt-enable=fcmp-fcsel,cmp-csel | FileCheck %s
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin                -aarch64-code-layout-opt-enable=fcmp-fcsel,cmp-csel | FileCheck %s --check-prefixes=CHECK,ENABLED
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin -mcpu=apple-m4 -aarch64-code-layout-opt-enable=fcmp-fcsel,cmp-csel | FileCheck %s --check-prefixes=CHECK,ENABLED
 ; Default for -mcpu=apple-m4 enables both fcmp-fcsel and cmp-csel; expect identical output.
-; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin -mcpu=apple-m4 | FileCheck %s
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin -mcpu=apple-m4                                      | FileCheck %s --check-prefixes=CHECK,ENABLED
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin -mcpu=apple-m4 -aarch64-code-layout-opt-enable=none | FileCheck %s --check-prefixes=CHECK,DISABLED
+; RUN: llc < %s -verify-machineinstrs -mtriple=aarch64-apple-darwin                                                     | FileCheck %s --check-prefixes=CHECK,DEFAULT
 
 ; Test coverage for optimizeForCodeLayout function:
 ; * Basic FCMP-FCSEL instruction pair detection and function alignment (single/double precision)
@@ -15,15 +18,25 @@
 ; * CMP/CMN with immediate <=15 qualifies; immediate >15 is excluded
 
 ; * Basic single-precision FCMP-FCSEL instruction pair
-; CHECK: .globl _test_basic_fcmp_fcsel_single
-; CHECK-NEXT: .p2align 6
 define float @test_basic_fcmp_fcsel_single(float %a, float %b, float %c, float %d) {
-; CHECK-LABEL: test_basic_fcmp_fcsel_single:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    fcmp s0, s1
-; CHECK-NEXT:    fcsel s0, s2, s3, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_basic_fcmp_fcsel_single:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    fcmp s0, s1
+; ENABLED-NEXT:    fcsel s0, s2, s3, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_basic_fcmp_fcsel_single:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    fcmp s0, s1
+; DISABLED-NEXT:    fcsel s0, s2, s3, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_basic_fcmp_fcsel_single:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    fcmp s0, s1
+; DEFAULT-NEXT:    fcsel s0, s2, s3, eq
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = fcmp oeq float %a, %b
   %sel = select i1 %cmp, float %c, float %d
@@ -31,15 +44,25 @@ entry:
 }
 
 ; * Basic double-precision FCMP-FCSEL instruction pair
-; CHECK: .globl _test_basic_fcmp_fcsel_double
-; CHECK-NEXT: .p2align 6
 define double @test_basic_fcmp_fcsel_double(double %a, double %b, double %c, double %d) {
-; CHECK-LABEL: test_basic_fcmp_fcsel_double:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    fcmp d0, d1
-; CHECK-NEXT:    fcsel d0, d2, d3, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_basic_fcmp_fcsel_double:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    fcmp d0, d1
+; ENABLED-NEXT:    fcsel d0, d2, d3, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_basic_fcmp_fcsel_double:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    fcmp d0, d1
+; DISABLED-NEXT:    fcsel d0, d2, d3, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_basic_fcmp_fcsel_double:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    fcmp d0, d1
+; DEFAULT-NEXT:    fcsel d0, d2, d3, eq
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = fcmp oeq double %a, %b
   %sel = select i1 %cmp, double %c, double %d
@@ -47,19 +70,33 @@ entry:
 }
 
 ; * Multiple FCMP-FCSEL instruction pairs in same function
-; CHECK: .globl _test_multiple_patterns
-; CHECK-NEXT: .p2align 6
 define float @test_multiple_patterns(float %a, float %b, float %c, float %d, float %e, float %f) {
-; CHECK-LABEL: test_multiple_patterns:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    fcmp s0, s1
-; CHECK-NEXT:    fcsel s0, s2, s3, eq
-; CHECK-NEXT:    .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.1: ; %entry
-; CHECK-NEXT:    fcmp s0, s4
-; CHECK-NEXT:    fcsel s0, s0, s5, gt
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_multiple_patterns:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    fcmp s0, s1
+; ENABLED-NEXT:    fcsel s0, s2, s3, eq
+; ENABLED-NEXT:    .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.1: ; %entry
+; ENABLED-NEXT:    fcmp s0, s4
+; ENABLED-NEXT:    fcsel s0, s0, s5, gt
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_multiple_patterns:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    fcmp s0, s1
+; DISABLED-NEXT:    fcsel s0, s2, s3, eq
+; DISABLED-NEXT:    fcmp s0, s4
+; DISABLED-NEXT:    fcsel s0, s0, s5, gt
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_multiple_patterns:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    fcmp s0, s1
+; DEFAULT-NEXT:    fcsel s0, s2, s3, eq
+; DEFAULT-NEXT:    fcmp s0, s4
+; DEFAULT-NEXT:    fcsel s0, s0, s5, gt
+; DEFAULT-NEXT:    ret
 entry:
   %cmp1 = fcmp oeq float %a, %b
   %sel1 = select i1 %cmp1, float %c, float %d
@@ -70,8 +107,6 @@ entry:
 
 ; * FCMP with comparison to zero (immediate) - excluded from optimization
 ; FCMP #0.0 uses the ri-form opcode which is not in the detection list
-; CHECK: .globl _test_fcmp_immediate
-; CHECK-NEXT: .p2align 2
 define float @test_fcmp_immediate(float %a, float %b) {
 ; CHECK-LABEL: test_fcmp_immediate:
 ; CHECK:       ; %bb.0: ; %entry
@@ -85,21 +120,39 @@ entry:
 }
 
 ; * Mixed single and double precision in same function
-; CHECK: .globl _test_mixed_precision
-; CHECK-NEXT: .p2align 6
 define float @test_mixed_precision(float %a, float %b, double %c, double %d) {
-; CHECK-LABEL: test_mixed_precision:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    fcmp s0, s1
-; CHECK-NEXT:    fcsel s0, s0, s1, gt
-; CHECK-NEXT:    .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.1: ; %entry
-; CHECK-NEXT:    fcmp d2, d3
-; CHECK-NEXT:    fcsel d1, d2, d3, mi
-; CHECK-NEXT:    fcvt s1, d1
-; CHECK-NEXT:    fadd s0, s0, s1
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_mixed_precision:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    fcmp s0, s1
+; ENABLED-NEXT:    fcsel s0, s0, s1, gt
+; ENABLED-NEXT:    .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.1: ; %entry
+; ENABLED-NEXT:    fcmp d2, d3
+; ENABLED-NEXT:    fcsel d1, d2, d3, mi
+; ENABLED-NEXT:    fcvt s1, d1
+; ENABLED-NEXT:    fadd s0, s0, s1
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_mixed_precision:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    fcmp s0, s1
+; DISABLED-NEXT:    fcsel s0, s0, s1, gt
+; DISABLED-NEXT:    fcmp d2, d3
+; DISABLED-NEXT:    fcsel d1, d2, d3, mi
+; DISABLED-NEXT:    fcvt s1, d1
+; DISABLED-NEXT:    fadd s0, s0, s1
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_mixed_precision:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    fcmp s0, s1
+; DEFAULT-NEXT:    fcsel s0, s0, s1, gt
+; DEFAULT-NEXT:    fcmp d2, d3
+; DEFAULT-NEXT:    fcsel d1, d2, d3, mi
+; DEFAULT-NEXT:    fcvt s1, d1
+; DEFAULT-NEXT:    fadd s0, s0, s1
+; DEFAULT-NEXT:    ret
 entry:
   %cmp_single = fcmp ogt float %a, %b
   %sel_single = select i1 %cmp_single, float %a, float %b
@@ -111,23 +164,45 @@ entry:
 }
 
 ; * FCMP-FCSEL instruction pair with a function call present
-; CHECK: .globl _test_with_function_calls
-; CHECK-NEXT: .p2align 6
 declare float @external_func(float)
 define float @test_with_function_calls(float %a, float %b, float %c, float %d) {
-; CHECK-LABEL: test_with_function_calls:
-; CHECK:       ; %bb.0: ; %entry
-; CHECK-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
-; CHECK-NEXT:    .cfi_def_cfa_offset 16
-; CHECK-NEXT:    .cfi_offset w30, -8
-; CHECK-NEXT:    .cfi_offset w29, -16
-; CHECK-NEXT:    .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.1: ; %entry
-; CHECK-NEXT:    fcmp s0, s1
-; CHECK-NEXT:    fcsel s0, s2, s3, gt
-; CHECK-NEXT:    bl _external_func
-; CHECK-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_with_function_calls:
+; ENABLED:       ; %bb.0: ; %entry
+; ENABLED-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; ENABLED-NEXT:    .cfi_def_cfa_offset 16
+; ENABLED-NEXT:    .cfi_offset w30, -8
+; ENABLED-NEXT:    .cfi_offset w29, -16
+; ENABLED-NEXT:    .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.1: ; %entry
+; ENABLED-NEXT:    fcmp s0, s1
+; ENABLED-NEXT:    fcsel s0, s2, s3, gt
+; ENABLED-NEXT:    bl _external_func
+; ENABLED-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_with_function_calls:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; DISABLED-NEXT:    .cfi_def_cfa_offset 16
+; DISABLED-NEXT:    .cfi_offset w30, -8
+; DISABLED-NEXT:    .cfi_offset w29, -16
+; DISABLED-NEXT:    fcmp s0, s1
+; DISABLED-NEXT:    fcsel s0, s2, s3, gt
+; DISABLED-NEXT:    bl _external_func
+; DISABLED-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_with_function_calls:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
+; DEFAULT-NEXT:    .cfi_def_cfa_offset 16
+; DEFAULT-NEXT:    .cfi_offset w30, -8
+; DEFAULT-NEXT:    .cfi_offset w29, -16
+; DEFAULT-NEXT:    fcmp s0, s1
+; DEFAULT-NEXT:    fcsel s0, s2, s3, gt
+; DEFAULT-NEXT:    bl _external_func
+; DEFAULT-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = fcmp ogt float %a, %b
   %sel = select i1 %cmp, float %c, float %d
@@ -136,8 +211,6 @@ entry:
 }
 
 ; * Verify no false positives - FCMP without FCSEL
-; CHECK: .globl _test_fcmp_without_fcsel
-; CHECK-NEXT: .p2align 2
 define i32 @test_fcmp_without_fcsel(float %a, float %b) {
 ; CHECK-LABEL: test_fcmp_without_fcsel:
 ; CHECK:       ; %bb.0: ; %entry
@@ -169,15 +242,25 @@ entry:
 ;------------------------------------------------------------------------------
 
 ; * Basic CMP-CSEL instruction pair (integer register comparison)
-; CHECK: .globl _test_basic_cmp_csel
-; CHECK-NEXT: .p2align 6
 define i32 @test_basic_cmp_csel(i32 %a, i32 %b, i32 %c, i32 %d) {
-; CHECK-LABEL: test_basic_cmp_csel:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    cmp w0, w1
-; CHECK-NEXT:    csel w0, w2, w3, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_basic_cmp_csel:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    cmp w0, w1
+; ENABLED-NEXT:    csel w0, w2, w3, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_basic_cmp_csel:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    cmp w0, w1
+; DISABLED-NEXT:    csel w0, w2, w3, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_basic_cmp_csel:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    cmp w0, w1
+; DEFAULT-NEXT:    csel w0, w2, w3, eq
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = icmp eq i32 %a, %b
   %sel = select i1 %cmp, i32 %c, i32 %d
@@ -185,15 +268,25 @@ entry:
 }
 
 ; * CMP-CSEL instruction pair with small immediate (<=15, qualifies for optimization)
-; CHECK: .globl _test_cmp_small_imm_csel
-; CHECK-NEXT: .p2align 6
 define i32 @test_cmp_small_imm_csel(i32 %a, i32 %b, i32 %c) {
-; CHECK-LABEL: test_cmp_small_imm_csel:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    cmp w0, #7
-; CHECK-NEXT:    csel w0, w1, w2, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_cmp_small_imm_csel:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    cmp w0, #7
+; ENABLED-NEXT:    csel w0, w1, w2, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_cmp_small_imm_csel:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    cmp w0, #7
+; DISABLED-NEXT:    csel w0, w1, w2, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_cmp_small_imm_csel:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    cmp w0, #7
+; DEFAULT-NEXT:    csel w0, w1, w2, eq
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = icmp eq i32 %a, 7
   %sel = select i1 %cmp, i32 %b, i32 %c
@@ -201,8 +294,6 @@ entry:
 }
 
 ; * CMP-CSEL with immediate > 15 - excluded from optimization
-; CHECK: .globl _test_cmp_large_imm_csel
-; CHECK-NEXT: .p2align 2
 define i32 @test_cmp_large_imm_csel(i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: test_cmp_large_imm_csel:
 ; CHECK:       ; %bb.0: ; %entry
@@ -216,15 +307,25 @@ entry:
 }
 
 ; * Basic CMN-CSEL instruction pair (ADDSWrr with WZR destination)
-; CHECK: .globl _test_basic_cmn_csel
-; CHECK-NEXT: .p2align 6
 define i32 @test_basic_cmn_csel(i32 %a, i32 %b, i32 %c, i32 %d) {
-; CHECK-LABEL: test_basic_cmn_csel:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    cmn w0, w1
-; CHECK-NEXT:    csel w0, w2, w3, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_basic_cmn_csel:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    cmn w0, w1
+; ENABLED-NEXT:    csel w0, w2, w3, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_basic_cmn_csel:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    cmn w0, w1
+; DISABLED-NEXT:    csel w0, w2, w3, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_basic_cmn_csel:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    cmn w0, w1
+; DEFAULT-NEXT:    csel w0, w2, w3, eq
+; DEFAULT-NEXT:    ret
 entry:
   %sum = add i32 %a, %b
   %cmp = icmp eq i32 %sum, 0
@@ -232,16 +333,52 @@ entry:
   ret i32 %sel
 }
 
+define i32 @test_subtarget_m4(i32 %a, i32 %b, i32 %c) "target-cpu"="apple-m4" {
+; ENABLED-LABEL: test_subtarget_m4:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    cmn w0, #7
+; ENABLED-NEXT:    csel w0, w1, w2, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_subtarget_m4:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    cmn w0, #7
+; DISABLED-NEXT:    csel w0, w1, w2, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_subtarget_m4:
+; DEFAULT:       .p2align 6, , 4
+; DEFAULT-NEXT:  ; %bb.0: ; %entry
+; DEFAULT-NEXT:    cmn w0, #7
+; DEFAULT-NEXT:    csel w0, w1, w2, eq
+; DEFAULT-NEXT:    ret
+entry:
+  %cmp = icmp eq i32 %a, -7
+  %sel = select i1 %cmp, i32 %b, i32 %c
+  ret i32 %sel
+}
+
 ; * CMN-CSEL instruction pair with small immediate (ADDSWri imm=7, qualifies)
-; CHECK: .globl _test_cmn_small_imm_csel
-; CHECK-NEXT: .p2align 6
 define i32 @test_cmn_small_imm_csel(i32 %a, i32 %b, i32 %c) {
-; CHECK-LABEL: test_cmn_small_imm_csel:
-; CHECK:       .p2align 6, , 4
-; CHECK-NEXT:  ; %bb.0: ; %entry
-; CHECK-NEXT:    cmn w0, #7
-; CHECK-NEXT:    csel w0, w1, w2, eq
-; CHECK-NEXT:    ret
+; ENABLED-LABEL: test_cmn_small_imm_csel:
+; ENABLED:       .p2align 6, , 4
+; ENABLED-NEXT:  ; %bb.0: ; %entry
+; ENABLED-NEXT:    cmn w0, #7
+; ENABLED-NEXT:    csel w0, w1, w2, eq
+; ENABLED-NEXT:    ret
+;
+; DISABLED-LABEL: test_cmn_small_imm_csel:
+; DISABLED:       ; %bb.0: ; %entry
+; DISABLED-NEXT:    cmn w0, #7
+; DISABLED-NEXT:    csel w0, w1, w2, eq
+; DISABLED-NEXT:    ret
+;
+; DEFAULT-LABEL: test_cmn_small_imm_csel:
+; DEFAULT:       ; %bb.0: ; %entry
+; DEFAULT-NEXT:    cmn w0, #7
+; DEFAULT-NEXT:    csel w0, w1, w2, eq
+; DEFAULT-NEXT:    ret
 entry:
   %cmp = icmp eq i32 %a, -7
   %sel = select i1 %cmp, i32 %b, i32 %c
@@ -249,8 +386,6 @@ entry:
 }
 
 ; * CMP without CSEL - no false positive
-; CHECK: .globl _test_cmp_without_csel
-; CHECK-NEXT: .p2align 2
 define i32 @test_cmp_without_csel(i32 %a, i32 %b) {
 ; CHECK-LABEL: test_cmp_without_csel:
 ; CHECK:       ; %bb.0: ; %entry

>From de38fffe6434290d96651011750d8398b3b371cd Mon Sep 17 00:00:00 2001
From: Jon Roelofs <jonathan_roelofs at apple.com>
Date: Tue, 18 Aug 2026 16:05:56 -0700
Subject: [PATCH 2/2] remove stray blank line

---
 llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
index e3bb52f014b69..fd254002f50fc 100644
--- a/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
+++ b/llvm/lib/Target/AArch64/AArch64CodeLayoutOpt.cpp
@@ -177,7 +177,6 @@ bool AArch64CodeLayoutOpt::runOnMachineFunction(MachineFunction &MF) {
   if (EnableCodeAlignment.getNumOccurrences()) {
     if (EnableCodeAlignment.isSet(CodeLayoutOpt::CmpCsel))
       CLO |= CodeLayoutOpt::CmpCsel;
-
     if (EnableCodeAlignment.isSet(CodeLayoutOpt::FcmpFcsel))
       CLO |= CodeLayoutOpt::FcmpFcsel;
   } else {



More information about the llvm-commits mailing list