From: Petr Hosek Date: Wed, 13 Feb 2019 17:28:47 +0000 (+0000) Subject: [AArch64] Support reserving arbitrary general purpose registers X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a876ea7b72775027b690027eecb14b74932c274b;p=llvm [AArch64] Support reserving arbitrary general purpose registers This is a follow up to D48580 and D48581 which allows reserving arbitrary general purpose registers with the exception of registers with special purpose (X8, X16-X18, X29, X30) and registers used by LLVM (X0, X19). This change also generalizes some of the existing logic to rely entirely on values generated from tablegen. Differential Revision: https://reviews.llvm.org/D56305 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353957 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/AArch64/AArch64.td b/lib/Target/AArch64/AArch64.td index 7ba64ffe5f9..766d365bbb5 100644 --- a/lib/Target/AArch64/AArch64.td +++ b/lib/Target/AArch64/AArch64.td @@ -126,7 +126,7 @@ def FeatureStrictAlign : SubtargetFeature<"strict-align", "Disallow all unaligned memory " "access">; -foreach i = {1-7,18,20} in +foreach i = {1-7,9-15,18,20-28} in def FeatureReserveX#i : SubtargetFeature<"reserve-x"#i, "ReserveXRegister["#i#"]", "true", "Reserve X"#i#", making it unavailable " "as a GPR">; diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index df39b182d34..020fd9ff023 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -5211,50 +5211,20 @@ SDValue AArch64TargetLowering::LowerSPONENTRY(SDValue Op, return DAG.getFrameIndex(FI, VT); } +#define GET_REGISTER_MATCHER +#include "AArch64GenAsmMatcher.inc" + // FIXME? Maybe this could be a TableGen attribute on some registers and // this table could be generated automatically from RegInfo. unsigned AArch64TargetLowering::getRegisterByName(const char* RegName, EVT VT, SelectionDAG &DAG) const { - unsigned Reg = StringSwitch(RegName) - .Case("sp", AArch64::SP) - .Case("x1", AArch64::X1) - .Case("w1", AArch64::W1) - .Case("x2", AArch64::X2) - .Case("w2", AArch64::W2) - .Case("x3", AArch64::X3) - .Case("w3", AArch64::W3) - .Case("x4", AArch64::X4) - .Case("w4", AArch64::W4) - .Case("x5", AArch64::X5) - .Case("w5", AArch64::W5) - .Case("x6", AArch64::X6) - .Case("w6", AArch64::W6) - .Case("x7", AArch64::X7) - .Case("w7", AArch64::W7) - .Case("x18", AArch64::X18) - .Case("w18", AArch64::W18) - .Case("x20", AArch64::X20) - .Case("w20", AArch64::W20) - .Default(0); - if (((Reg == AArch64::X1 || Reg == AArch64::W1) && - !Subtarget->isXRegisterReserved(1)) || - ((Reg == AArch64::X2 || Reg == AArch64::W2) && - !Subtarget->isXRegisterReserved(2)) || - ((Reg == AArch64::X3 || Reg == AArch64::W3) && - !Subtarget->isXRegisterReserved(3)) || - ((Reg == AArch64::X4 || Reg == AArch64::W4) && - !Subtarget->isXRegisterReserved(4)) || - ((Reg == AArch64::X5 || Reg == AArch64::W5) && - !Subtarget->isXRegisterReserved(5)) || - ((Reg == AArch64::X6 || Reg == AArch64::W6) && - !Subtarget->isXRegisterReserved(6)) || - ((Reg == AArch64::X7 || Reg == AArch64::W7) && - !Subtarget->isXRegisterReserved(7)) || - ((Reg == AArch64::X18 || Reg == AArch64::W18) && - !Subtarget->isXRegisterReserved(18)) || - ((Reg == AArch64::X20 || Reg == AArch64::W20) && - !Subtarget->isXRegisterReserved(20))) - Reg = 0; + unsigned Reg = MatchRegisterName(RegName); + if (AArch64::X1 <= Reg && Reg <= AArch64::X28) { + const MCRegisterInfo *MRI = Subtarget->getRegisterInfo(); + unsigned DwarfRegNum = MRI->getDwarfRegNum(Reg, false); + if (!Subtarget->isXRegisterReserved(DwarfRegNum)) + Reg = 0; + } if (Reg) return Reg; report_fatal_error(Twine("Invalid register name \"" diff --git a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp index 0165a7c26de..08cf6859f05 100644 --- a/lib/Target/AArch64/AArch64RegisterBankInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterBankInfo.cpp @@ -242,11 +242,13 @@ const RegisterBank &AArch64RegisterBankInfo::getRegBankFromRegClass( case AArch64::GPR32RegClassID: case AArch64::GPR32spRegClassID: case AArch64::GPR32sponlyRegClassID: + case AArch64::GPR32argRegClassID: case AArch64::GPR32allRegClassID: case AArch64::GPR64commonRegClassID: case AArch64::GPR64RegClassID: case AArch64::GPR64spRegClassID: case AArch64::GPR64sponlyRegClassID: + case AArch64::GPR64argRegClassID: case AArch64::GPR64allRegClassID: case AArch64::GPR64noipRegClassID: case AArch64::GPR64common_and_GPR64noipRegClassID: diff --git a/lib/Target/AArch64/AArch64RegisterInfo.cpp b/lib/Target/AArch64/AArch64RegisterInfo.cpp index 0d423a8893a..54d43431620 100644 --- a/lib/Target/AArch64/AArch64RegisterInfo.cpp +++ b/lib/Target/AArch64/AArch64RegisterInfo.cpp @@ -216,11 +216,8 @@ bool AArch64RegisterInfo::isReservedReg(const MachineFunction &MF, } bool AArch64RegisterInfo::isAnyArgRegReserved(const MachineFunction &MF) const { - // FIXME: Get the list of argument registers from TableGen. - static const MCPhysReg GPRArgRegs[] = { AArch64::X0, AArch64::X1, AArch64::X2, - AArch64::X3, AArch64::X4, AArch64::X5, - AArch64::X6, AArch64::X7 }; - return std::any_of(std::begin(GPRArgRegs), std::end(GPRArgRegs), + return std::any_of(std::begin(*AArch64::GPR64argRegClass.MC), + std::end(*AArch64::GPR64argRegClass.MC), [this, &MF](MCPhysReg r){return isReservedReg(MF, r);}); } diff --git a/lib/Target/AArch64/AArch64RegisterInfo.td b/lib/Target/AArch64/AArch64RegisterInfo.td index 32039d2caf0..61fc0795c24 100644 --- a/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/lib/Target/AArch64/AArch64RegisterInfo.td @@ -187,6 +187,10 @@ def GPR64z : RegisterOperand { let GIZeroRegister = XZR; } +// GPR argument registers. +def GPR32arg : RegisterClass<"AArch64", [i32], 32, (sequence "W%u", 0, 7)>; +def GPR64arg : RegisterClass<"AArch64", [i64], 64, (sequence "X%u", 0, 7)>; + // GPR register classes which include WZR/XZR AND SP/WSP. This is not a // constraint used by any instructions, it is used as a common super-class. def GPR32all : RegisterClass<"AArch64", [i32], 32, (add GPR32common, WZR, WSP)>; diff --git a/test/CodeGen/AArch64/arm64-platform-reg.ll b/test/CodeGen/AArch64/arm64-platform-reg.ll index 73fe36d7611..42448fcce56 100644 --- a/test/CodeGen/AArch64/arm64-platform-reg.ll +++ b/test/CodeGen/AArch64/arm64-platform-reg.ll @@ -1,7 +1,5 @@ ; RUN: llc -mtriple=arm64-apple-ios -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=arm64-freebsd-gnu -mattr=+reserve-x18 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 -; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X20 -; RUN: llc -mtriple=aarch64-fuchsia -mattr=+reserve-x18,+reserve-x20 -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 --check-prefix=CHECK-RESERVE-X20 ; RUN: llc -mtriple=arm64-linux-gnu -o - %s | FileCheck %s ; RUN: llc -mtriple=aarch64-linux-android -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 ; RUN: llc -mtriple=aarch64-fuchsia -o - %s | FileCheck %s --check-prefix=CHECK-RESERVE --check-prefix=CHECK-RESERVE-X18 @@ -15,6 +13,22 @@ ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x5 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X5 ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x6 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X6 ; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x7 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X7 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x9 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X9 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x10 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X10 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x11 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X11 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x12 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X12 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x13 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X13 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x14 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X14 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x15 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X15 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x20 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X20 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x21 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X21 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x22 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X22 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x23 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X23 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x24 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X24 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x25 -o - %s | FileCheck %s --check-prefixes=CHECK-RESERVE,CHECK-RESERVE-X25 +; 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 ; Test multiple of reserve-x# options together. ; RUN: llc -mtriple=arm64-linux-gnu \ @@ -36,8 +50,23 @@ ; RUN: -mattr=+reserve-x5 \ ; RUN: -mattr=+reserve-x6 \ ; RUN: -mattr=+reserve-x7 \ +; RUN: -mattr=+reserve-x9 \ +; RUN: -mattr=+reserve-x10 \ +; RUN: -mattr=+reserve-x11 \ +; RUN: -mattr=+reserve-x12 \ +; RUN: -mattr=+reserve-x13 \ +; RUN: -mattr=+reserve-x14 \ +; RUN: -mattr=+reserve-x15 \ ; RUN: -mattr=+reserve-x18 \ ; RUN: -mattr=+reserve-x20 \ +; RUN: -mattr=+reserve-x21 \ +; RUN: -mattr=+reserve-x22 \ +; RUN: -mattr=+reserve-x23 \ +; RUN: -mattr=+reserve-x24 \ +; RUN: -mattr=+reserve-x25 \ +; RUN: -mattr=+reserve-x26 \ +; RUN: -mattr=+reserve-x27 \ +; RUN: -mattr=+reserve-x28 \ ; RUN: -o - %s | FileCheck %s \ ; RUN: --check-prefix=CHECK-RESERVE \ ; RUN: --check-prefix=CHECK-RESERVE-X1 \ @@ -47,8 +76,23 @@ ; RUN: --check-prefix=CHECK-RESERVE-X5 \ ; RUN: --check-prefix=CHECK-RESERVE-X6 \ ; RUN: --check-prefix=CHECK-RESERVE-X7 \ +; RUN: --check-prefix=CHECK-RESERVE-X9 \ +; RUN: --check-prefix=CHECK-RESERVE-X10 \ +; RUN: --check-prefix=CHECK-RESERVE-X11 \ +; RUN: --check-prefix=CHECK-RESERVE-X12 \ +; RUN: --check-prefix=CHECK-RESERVE-X13 \ +; RUN: --check-prefix=CHECK-RESERVE-X14 \ +; RUN: --check-prefix=CHECK-RESERVE-X15 \ ; RUN: --check-prefix=CHECK-RESERVE-X18 \ -; RUN: --check-prefix=CHECK-RESERVE-X20 +; RUN: --check-prefix=CHECK-RESERVE-X20 \ +; RUN: --check-prefix=CHECK-RESERVE-X21 \ +; RUN: --check-prefix=CHECK-RESERVE-X22 \ +; RUN: --check-prefix=CHECK-RESERVE-X23 \ +; RUN: --check-prefix=CHECK-RESERVE-X24 \ +; RUN: --check-prefix=CHECK-RESERVE-X25 \ +; RUN: --check-prefix=CHECK-RESERVE-X26 \ +; RUN: --check-prefix=CHECK-RESERVE-X27 \ +; RUN: --check-prefix=CHECK-RESERVE-X28 ; 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. @@ -73,8 +117,23 @@ define void @keep_live() { ; CHECK-RESERVE-X5-NOT: ldr x5, ; CHECK-RESERVE-X6-NOT: ldr x6, ; CHECK-RESERVE-X7-NOT: ldr x7, +; CHECK-RESERVE-X9-NOT: ldr x9, +; CHECK-RESERVE-X10-NOT: ldr x10, +; CHECK-RESERVE-X11-NOT: ldr x11, +; CHECK-RESERVE-X12-NOT: ldr x12, +; CHECK-RESERVE-X13-NOT: ldr x13, +; CHECK-RESERVE-X14-NOT: ldr x14, +; CHECK-RESERVE-X15-NOT: ldr x15, ; CHECK-RESERVE-X18-NOT: ldr x18 ; CHECK-RESERVE-X20-NOT: ldr x20 +; CHECK-RESERVE-X21-NOT: ldr x21 +; CHECK-RESERVE-X22-NOT: ldr x22 +; CHECK-RESERVE-X23-NOT: ldr x23 +; CHECK-RESERVE-X24-NOT: ldr x24 +; CHECK-RESERVE-X25-NOT: ldr x25 +; CHECK-RESERVE-X26-NOT: ldr x26 +; CHECK-RESERVE-X27-NOT: ldr x27 +; CHECK-RESERVE-X28-NOT: ldr x28 ; CHECK-RESERVE: Spill ; CHECK-RESERVE-NOT: ldr fp ; CHECK-RESERVE-X1-NOT: ldr x1, @@ -84,8 +143,23 @@ define void @keep_live() { ; CHECK-RESERVE-X5-NOT: ldr x5, ; CHECK-RESERVE-X6-NOT: ldr x6, ; CHECK-RESERVE-X7-NOT: ldr x7, +; CHECK-RESERVE-X9-NOT: ldr x9, +; CHECK-RESERVE-X10-NOT: ldr x10, +; CHECK-RESERVE-X11-NOT: ldr x11, +; CHECK-RESERVE-X12-NOT: ldr x12, +; CHECK-RESERVE-X13-NOT: ldr x13, +; CHECK-RESERVE-X14-NOT: ldr x14, +; CHECK-RESERVE-X15-NOT: ldr x15, ; CHECK-RESERVE-X18-NOT: ldr x18 ; CHECK-RESERVE-X20-NOT: ldr x20 +; CHECK-RESERVE-X21-NOT: ldr x21 +; CHECK-RESERVE-X22-NOT: ldr x22 +; CHECK-RESERVE-X23-NOT: ldr x23 +; CHECK-RESERVE-X24-NOT: ldr x24 +; CHECK-RESERVE-X25-NOT: ldr x25 +; CHECK-RESERVE-X26-NOT: ldr x26 +; CHECK-RESERVE-X27-NOT: ldr x27 +; CHECK-RESERVE-X28-NOT: ldr x28 ; CHECK-RESERVE: ret ret void } diff --git a/test/CodeGen/AArch64/arm64-reserve-call-saved-reg.ll b/test/CodeGen/AArch64/arm64-reserve-call-saved-reg.ll index 050e3033fcb..ce9d2c7171d 100644 --- a/test/CodeGen/AArch64/arm64-reserve-call-saved-reg.ll +++ b/test/CodeGen/AArch64/arm64-reserve-call-saved-reg.ll @@ -1,13 +1,34 @@ -; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 \ -; RUN: -o - %s | FileCheck %s +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x9 -mattr=+call-saved-x9 -o - %s | FileCheck %s --check-prefixes=CHECK-X9 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x9 -mattr=+call-saved-x9 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X9 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x9 -mattr=+call-saved-x9 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X9 -; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 \ -; RUN: -global-isel \ -; RUN: -o - %s | FileCheck %s +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x10 -mattr=+call-saved-x10 -o - %s | FileCheck %s --check-prefixes=CHECK-X10 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x10 -mattr=+call-saved-x10 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X10 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x10 -mattr=+call-saved-x10 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X10 -; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 \ -; RUN: -fast-isel \ -; RUN: -o - %s | FileCheck %s +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x11 -mattr=+call-saved-x11 -o - %s | FileCheck %s --check-prefixes=CHECK-X11 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x11 -mattr=+call-saved-x11 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X11 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x11 -mattr=+call-saved-x11 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X11 + +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x12 -mattr=+call-saved-x12 -o - %s | FileCheck %s --check-prefixes=CHECK-X12 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x12 -mattr=+call-saved-x12 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X12 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x12 -mattr=+call-saved-x12 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X12 + +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x13 -mattr=+call-saved-x13 -o - %s | FileCheck %s --check-prefixes=CHECK-X13 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x13 -mattr=+call-saved-x13 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X13 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x13 -mattr=+call-saved-x13 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X13 + +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x14 -mattr=+call-saved-x14 -o - %s | FileCheck %s --check-prefixes=CHECK-X14 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x14 -mattr=+call-saved-x14 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X14 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x14 -mattr=+call-saved-x14 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X14 + +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x15 -mattr=+call-saved-x15 -o - %s | FileCheck %s --check-prefixes=CHECK-X15 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x15 -mattr=+call-saved-x15 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X15 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x15 -mattr=+call-saved-x15 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X15 + +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 -o - %s | FileCheck %s --check-prefixes=CHECK-X18 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 -global-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X18 +; RUN: llc -mtriple=arm64-linux-gnu -mattr=+reserve-x18 -mattr=+call-saved-x18 -fast-isel -o - %s | FileCheck %s --check-prefixes=CHECK-X18 ; Used to exhaust the supply of GPRs. @var = global [30 x i64] zeroinitializer @@ -15,14 +36,42 @@ ; If a register is specified to be both reserved and callee-saved, then it ; should not be allocated and should not be spilled onto the stack. define void @foo() { -; CHECK-NOT: str x18, [sp +; CHECK-X9-NOT: str x9, [sp +; CHECK-X10-NOT: str x10, [sp +; CHECK-X11-NOT: str x11, [sp +; CHECK-X12-NOT: str x12, [sp +; CHECK-X13-NOT: str x13, [sp +; CHECK-X14-NOT: str x14, [sp +; CHECK-X15-NOT: str x15, [sp +; CHECK-X18-NOT: str x18, [sp %val = load volatile [30 x i64], [30 x i64]* @var store volatile [30 x i64] %val, [30 x i64]* @var -; CHECK-NOT: ldr x18 -; CHECK-NOT: str x18 +; CHECK-X9-NOT: ldr x9 +; CHECK-X10-NOT: ldr x10 +; CHECK-X11-NOT: ldr x11 +; CHECK-X12-NOT: ldr x12 +; CHECK-X13-NOT: ldr x13 +; CHECK-X14-NOT: ldr x14 +; CHECK-X15-NOT: ldr x15 +; CHECK-X18-NOT: ldr x18 +; CHECK-X9-NOT: str x9 +; CHECK-X10-NOT: str x10 +; CHECK-X11-NOT: str x11 +; CHECK-X12-NOT: str x12 +; CHECK-X13-NOT: str x13 +; CHECK-X14-NOT: str x14 +; CHECK-X15-NOT: str x15 +; CHECK-X18-NOT: str x18 -; CHECK-NOT: ldr x18, [sp +; CHECK-X9-NOT: ldr x9, [sp +; CHECK-X10-NOT: ldr x10, [sp +; CHECK-X11-NOT: ldr x11, [sp +; CHECK-X12-NOT: ldr x12, [sp +; CHECK-X13-NOT: ldr x13, [sp +; CHECK-X14-NOT: ldr x14, [sp +; CHECK-X15-NOT: ldr x15, [sp +; CHECK-X18-NOT: ldr x18, [sp ret void }