Index: lib/Target/AArch64/AArch64CallingConvention.td =================================================================== --- lib/Target/AArch64/AArch64CallingConvention.td +++ lib/Target/AArch64/AArch64CallingConvention.td @@ -45,6 +45,9 @@ // supported there. CCIfNest>, + // Pass SwiftSelf in a callee saved register. + CCIfSwiftSelf>>, + CCIfConsecutiveRegs>, // Handle i1, i8, i16, i32, i64, f32, f64 and v2f64 by passing in registers, @@ -126,8 +129,8 @@ // slot is 64-bit. CCIfByVal>, - // A SwiftSelf is passed in X9. - CCIfSwiftSelf>>, + // Pass SwiftSelf in a callee saved register. + CCIfSwiftSelf>>, CCIfConsecutiveRegs>, Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -697,13 +697,11 @@ } static unsigned getPrologueDeath(MachineFunction &MF, unsigned Reg) { - if (Reg != AArch64::LR) - return getKillRegState(true); - - // LR maybe referred to later by an @llvm.returnaddress intrinsic. - bool LRLiveIn = MF.getRegInfo().isLiveIn(AArch64::LR); - bool LRKill = !(LRLiveIn && MF.getFrameInfo()->isReturnAddressTaken()); - return getKillRegState(LRKill); + // Do not set a kill flag on values that are also marked as live-in. This + // happens with the @llvm-returnaddress intrinsic and with arguments passed in + // callee saved registers. + bool IsLiveIn = MF.getRegInfo().isLiveIn(Reg); + return getKillRegState(!IsLiveIn); } struct RegPairInfo { Index: test/CodeGen/AArch64/swiftself.ll =================================================================== --- test/CodeGen/AArch64/swiftself.ll +++ test/CodeGen/AArch64/swiftself.ll @@ -1,29 +1,36 @@ -; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-apple-ios | FileCheck --check-prefix=CHECK-APPLE %s -; RUN: llc -O0 -verify-machineinstrs < %s -mtriple=aarch64-apple-ios | FileCheck --check-prefix=CHECK-O0 %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s +; RUN: llc -O0 -verify-machineinstrs -mtriple=aarch64-apple-ios -o - %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mtriple=aarch64-unknown-linux-gnu -o - %s | FileCheck %s -; Parameter with swiftself should be allocated to x9. -define void @check_swiftself(i32* swiftself %addr0) { -; CHECK-APPLE-LABEL: check_swiftself: -; CHECK-O0-LABEL: check_swiftself: +; Parameter with swiftself should be allocated to x19. +; CHECK-LABEL: swiftself_param: +; CHECK: mov x0, x19 +; CHECK-NEXT: ret +define i32 *@swiftself_param(i32* swiftself %addr0) { + ret i32 *%addr0 +} - %val0 = load volatile i32, i32* %addr0 -; CHECK-APPLE: ldr w{{.*}}, [x9] -; CHECK-O0: ldr w{{.*}}, [x9] - ret void +; x19 should be saved by the callee even if used for swiftself +; CHECK-LABEL: swiftself_clobber: +; CHECK: {{stp|str}} {{.*}}x19{{.*}}sp +; ... +; CHECK: {{ldp|ldr}} {{.*}}x19{{.*}}sp +; CHECK: ret +define i32 *@swiftself_clobber(i32* swiftself %addr0) { + call void asm sideeffect "", "~{x19}"() + ret i32 *%addr0 } @var8_3 = global i8 0 declare void @take_swiftself(i8* swiftself %addr0) -define void @simple_args() { -; CHECK-APPLE-LABEL: simple_args: -; CHECK-O0-LABEL: simple_args: - - call void @take_swiftself(i8* @var8_3) -; CHECK-APPLE: add x9, -; CHECK-APPLE: bl {{_?}}take_swiftself -; CHECK-O0: add x9, -; CHECK-O0: bl {{_?}}take_swiftself - +; CHECK-LABEL: simple_args: +; CHECK: {{stp|str}} {{.*}}x19{{.*}}sp +; CHECK: mov x19, x0 +; CHECK: bl {{_?}}take_swiftself +; CHECK: {{ldp|ldr}} {{.*}}x19{{.*}}sp +; CHECK: ret +define void @simple_args(i8* %arg) { + call void @take_swiftself(i8* %arg) ret void }