[llvm] 9865171 - [AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. (#98073)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 10 15:16:55 PDT 2024


Author: Amara Emerson
Date: 2024-07-10T15:16:51-07:00
New Revision: 9865171e24961d9ae85d7183d5f52c44b82a9c58

URL: https://github.com/llvm/llvm-project/commit/9865171e24961d9ae85d7183d5f52c44b82a9c58
DIFF: https://github.com/llvm/llvm-project/commit/9865171e24961d9ae85d7183d5f52c44b82a9c58.diff

LOG: [AArch64] Add -mlr-for-calls-only to replace the now removed -ffixed-x30 flag. (#98073)

This re-introduces the effective behaviour that was reverted in
7ad481e76c9bee5b9895ebfa0fdb52f31cb7de77.

This time we're not using the same mechanism, exposing another
reservation feature
that prevents only regalloc from using the register, but not for other
required uses
like ABIs.

This also fixes a consequent issue with reserving LR, which is that
frame lowering
was only adding live-in flags for non-reserved regs. This would cause
issues later
since the outliner needs accurate flags to determine when LR needs to be
preserved.

rdar://131313095

Added: 
    clang/include/clang/Driver/aarch64-mlr-for-calls-only.c
    llvm/test/CodeGen/AArch64/lr-reserved-for-ra-live-in.ll

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Arch/AArch64.cpp
    llvm/lib/Target/AArch64/AArch64Features.td
    llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
    llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
    llvm/lib/Target/AArch64/AArch64Subtarget.h
    llvm/test/CodeGen/AArch64/arm64-platform-reg.ll
    llvm/test/CodeGen/AArch64/framelayout-sve.mir

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index cfb37b3c5b474..68a49b31f044f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4929,6 +4929,9 @@ foreach i = {1-31} in
   def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>,
     HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">;
 
+def mlr_for_calls_only : Flag<["-"], "mlr-for-calls-only">, Group<m_aarch64_Features_Group>,
+  HelpText<"Do not allocate the LR register for general purpose usage, only for calls. (AArch64 only)">;
+
 foreach i = {8-15,18} in
   def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>,
     HelpText<"Make the x"#i#" register call-saved (AArch64 only)">;

diff  --git a/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c b/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c
new file mode 100644
index 0000000000000..e71a4cdfe0e7f
--- /dev/null
+++ b/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c
@@ -0,0 +1,3 @@
+// RUN: %clang --target=aarch64-none-gnu -mlr-for-calls-only -### %s 2> %t
+// RUN: FileCheck --check-prefix=CHECK < %t %s
+// CHECK: "-target-feature" "+reserve-lr-for-ra"

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index ec248b80251ea..5fbf38cdda12b 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -398,6 +398,9 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
   if (Args.hasArg(options::OPT_ffixed_x28))
     Features.push_back("+reserve-x28");
 
+  if (Args.hasArg(options::OPT_mlr_for_calls_only))
+    Features.push_back("+reserve-lr-for-ra");
+
   if (Args.hasArg(options::OPT_fcall_saved_x8))
     Features.push_back("+call-saved-x8");
 

diff  --git a/llvm/lib/Target/AArch64/AArch64Features.td b/llvm/lib/Target/AArch64/AArch64Features.td
index 8754ea4974999..50ff25ff1ba0c 100644
--- a/llvm/lib/Target/AArch64/AArch64Features.td
+++ b/llvm/lib/Target/AArch64/AArch64Features.td
@@ -571,6 +571,10 @@ foreach i = {1-7,9-15,18,20-28} in
                                              "Reserve X"#i#", making it unavailable "
                                              "as a GPR">;
 
+def FeatureReserveLRForRA : SubtargetFeature<"reserve-lr-for-ra",
+                                             "ReserveLRForRA", "true",
+                                             "Reserve LR for call use only">;
+
 foreach i = {8-15,18} in
     def FeatureCallSavedX#i : SubtargetFeature<"call-saved-x"#i,
          "CustomCallSavedXRegs["#i#"]", "true", "Make X"#i#" callee saved.">;

diff  --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index 75e89e8222ae9..c11e1195903e5 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -3079,7 +3079,11 @@ bool AArch64FrameLowering::spillCalleeSavedRegisters(
 
   computeCalleeSaveRegisterPairs(MF, CSI, TRI, RegPairs, hasFP(MF));
 
-  const MachineRegisterInfo &MRI = MF.getRegInfo();
+  MachineRegisterInfo &MRI = MF.getRegInfo();
+  // Refresh the reserved regs in case there are any potential changes since the
+  // last freeze.
+  MRI.freezeReservedRegs();
+
   if (homogeneousPrologEpilog(MF)) {
     auto MIB = BuildMI(MBB, MI, DL, TII.get(AArch64::HOM_Prolog))
                    .setMIFlag(MachineInstr::FrameSetup);

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index cc50b59dd8d7e..1e069f4790c53 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -501,6 +501,17 @@ AArch64RegisterInfo::getReservedRegs(const MachineFunction &MF) const {
       markSuperRegs(Reserved, AArch64::GPR32commonRegClass.getRegister(i));
   }
 
+  if (MF.getSubtarget<AArch64Subtarget>().isLRReservedForRA()) {
+    // In order to prevent the register allocator from using LR, we need to
+    // mark it as reserved. However we don't want to keep it reserved throughout
+    // the pipeline since it prevents other infrastructure from reasoning about
+    // it's liveness. We use the NoVRegs property instead of IsSSA because
+    // IsSSA is removed before VirtRegRewriter runs.
+    if (!MF.getProperties().hasProperty(
+            MachineFunctionProperties::Property::NoVRegs))
+      markSuperRegs(Reserved, AArch64::LR);
+  }
+
   assert(checkAllSuperRegsMarked(Reserved));
   return Reserved;
 }

diff  --git a/llvm/lib/Target/AArch64/AArch64Subtarget.h b/llvm/lib/Target/AArch64/AArch64Subtarget.h
index 5faba09aa67bd..4b840b24ba134 100644
--- a/llvm/lib/Target/AArch64/AArch64Subtarget.h
+++ b/llvm/lib/Target/AArch64/AArch64Subtarget.h
@@ -209,6 +209,7 @@ class AArch64Subtarget final : public AArch64GenSubtargetInfo {
     AllReservedX |= ReserveXRegisterForRA;
     return AllReservedX.count();
   }
+  bool isLRReservedForRA() const { return ReserveLRForRA; }
   bool isXRegCustomCalleeSaved(size_t i) const {
     return CustomCallSavedXRegs[i];
   }

diff  --git a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll
index 3df2ef7aa59fc..eefc858db2752 100644
--- a/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-platform-reg.ll
@@ -34,6 +34,7 @@
 ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x26 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X26
 ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x27 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X27
 ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x28 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X28
+; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-lr-for-ra -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-LR-RA
 
 ; Test multiple of reserve-x# options together.
 ; RUN: llc -mtriple=arm64-linux-gnu \
@@ -72,6 +73,7 @@
 ; RUN: -mattr=+reserve-x26 \
 ; RUN: -mattr=+reserve-x27 \
 ; RUN: -mattr=+reserve-x28 \
+; RUN: -mattr=+reserve-lr-for-ra \
 ; RUN: -reserve-regs-for-regalloc=X8,X16,X17,X19 \
 ; RUN: -o - %s | FileCheck %s \
 ; RUN: --check-prefix=CHECK-RESERVE \
@@ -102,7 +104,8 @@
 ; RUN: --check-prefix=CHECK-RESERVE-X25 \
 ; RUN: --check-prefix=CHECK-RESERVE-X26 \
 ; RUN: --check-prefix=CHECK-RESERVE-X27 \
-; RUN: --check-prefix=CHECK-RESERVE-X28
+; RUN: --check-prefix=CHECK-RESERVE-X28 \
+; RUN: --check-prefix=CHECK-RESERVE-LR-RA
 
 ; x18 is reserved as a platform register on Darwin but not on other
 ; systems. Create loads of register pressure and make sure this is respected.
@@ -149,6 +152,7 @@ define void @keep_live() {
 ; CHECK-RESERVE-X26-NOT: ldr x26
 ; CHECK-RESERVE-X27-NOT: ldr x27
 ; CHECK-RESERVE-X28-NOT: ldr x28
+; CHECK-RESERVE-LR-RA-NOT: ldr x30
 ; CHECK-RESERVE: Spill
 ; CHECK-RESERVE-NOT: ldr fp
 ; CHECK-RESERVE-X1-NOT: ldr x1,
@@ -178,6 +182,7 @@ define void @keep_live() {
 ; CHECK-RESERVE-X26-NOT: ldr x26
 ; CHECK-RESERVE-X27-NOT: ldr x27
 ; CHECK-RESERVE-X28-NOT: ldr x28
+; CHECK-RESERVE-LR-RA-NOT: ldr x30
 ; CHECK-RESERVE: ret
   ret void
 }

diff  --git a/llvm/test/CodeGen/AArch64/framelayout-sve.mir b/llvm/test/CodeGen/AArch64/framelayout-sve.mir
index f7920e595e44b..17b1ad2197c46 100644
--- a/llvm/test/CodeGen/AArch64/framelayout-sve.mir
+++ b/llvm/test/CodeGen/AArch64/framelayout-sve.mir
@@ -57,7 +57,8 @@
 # CHECK:       stackSize: 32
 
 # CHECK:      bb.0.entry:
-# CHECK-NEXT: $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
+# CHECK:      liveins: $fp
+# CHECK:      early-clobber $sp = frame-setup STRXpre killed $[[SCRATCH:[a-z0-9]+]], $sp, -16
 # CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
 # CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $w29, -16
 # CHECK-NEXT: $sp = frame-setup SUBXri $sp, 16, 0

diff  --git a/llvm/test/CodeGen/AArch64/lr-reserved-for-ra-live-in.ll b/llvm/test/CodeGen/AArch64/lr-reserved-for-ra-live-in.ll
new file mode 100644
index 0000000000000..f394bc467af69
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/lr-reserved-for-ra-live-in.ll
@@ -0,0 +1,57 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -stop-after=prologepilog -simplify-mir -o - %s | FileCheck %s
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+target triple = "arm64e-apple-ios18.0"
+
+declare void @spam()
+; This test checks that the live-in flags for LR are correctly set when LR is reserved, but live for a call.
+define i32 @check_lr_liveness(ptr %arg) #1 {
+  ; CHECK-LABEL: name: check_lr_liveness
+  ; CHECK: bb.0.bb:
+  ; CHECK-NEXT:   successors: %bb.4(0x20000000), %bb.1(0x60000000)
+  ; CHECK-NEXT:   liveins: $x0, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   renamable $x8 = COPY $x0
+  ; CHECK-NEXT:   renamable $w0 = MOVi32imm -536870206
+  ; CHECK-NEXT:   CBNZX killed renamable $x8, %bb.1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.4:
+  ; CHECK-NEXT:   liveins: $w0, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   B %bb.3
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.1.bb:
+  ; CHECK-NEXT:   successors: %bb.3(0x2aaaaaab), %bb.2(0x55555555)
+  ; CHECK-NEXT:   liveins: $w0, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   CBNZW $wzr, %bb.3
+  ; CHECK-NEXT:   B %bb.2
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.2.bb1:
+  ; CHECK-NEXT:   liveins: $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   early-clobber $sp = frame-setup STPXpre killed $fp, killed $lr, $sp, -2 :: (store (s64) into %stack.1), (store (s64) into %stack.0)
+  ; CHECK-NEXT:   BL @spam, csr_darwin_aarch64_aapcs, implicit-def dead $lr, implicit $sp, implicit-def $sp
+  ; CHECK-NEXT:   renamable $w0 = COPY $wzr
+  ; CHECK-NEXT:   early-clobber $sp, $fp, $lr = frame-destroy LDPXpost $sp, 2 :: (load (s64) from %stack.1), (load (s64) from %stack.0)
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT: bb.3.bb2:
+  ; CHECK-NEXT:   liveins: $w0, $lr
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   RET_ReallyLR implicit $w0
+bb:
+  %icmp = icmp eq ptr %arg, null
+  %or = or i1 %icmp, false
+  br i1 %or, label %bb2, label %bb1
+
+bb1:                                              ; preds = %bb
+  call void @spam()
+  br label %bb2
+
+bb2:                                              ; preds = %bb1, %bb
+  %phi = phi i32 [ -536870206, %bb ], [ 0, %bb1 ]
+  ret i32 %phi
+}
+
+attributes #1 = { minsize nounwind "target-features"="+aes,+crc,+fp-armv8,+fullfp16,+lse,+neon,+ras,+rcpc,+rdm,+reserve-lr-for-ra,+sha2,+v8.1a,+v8.2a,+v8.3a,+v8a,+zcm,+zcz" }
+


        


More information about the llvm-commits mailing list