From: Brian Gesiak Date: Wed, 30 Aug 2017 20:03:54 +0000 (+0000) Subject: [ARM] Use Swift error registers on non-Darwin targets X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d795908c5ee3401776e8bdae024a35031245ad9;p=llvm [ARM] Use Swift error registers on non-Darwin targets Summary: Remove a check for `ARMSubtarget::isTargetDarwin` when determining whether to use Swift error registers, so that Swift errors work properly on non-Darwin ARM32 targets (specifically Android). Before this patch, generated code would save and restores ARM register r8 at the entry and returns of a function that throws. As r8 is used as a virtual return value for the object being thrown, this gets overwritten by the restore, and calling code is unable to catch the error. In turn this caused Swift code that used `do`/`try`/`catch` to work improperly on Android ARM32 targets. Addresses Swift bug report https://bugs.swift.org/browse/SR-5438. Patch by John Holdsworth. Reviewers: manmanren, rjmccall, aschwaighofer Reviewed By: aschwaighofer Subscribers: srhines, aschwaighofer, aemerson, javed.absar, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D35835 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@312164 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/lib/Target/ARM/ARMBaseRegisterInfo.cpp index 370c0a7f5c5..ee55cd6f9ea 100644 --- a/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -92,7 +92,7 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { } } - if (STI.isTargetDarwin() && STI.getTargetLowering()->supportSwiftError() && + if (STI.getTargetLowering()->supportSwiftError() && F->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) return CSR_iOS_SwiftError_SaveList; @@ -120,7 +120,7 @@ ARMBaseRegisterInfo::getCallPreservedMask(const MachineFunction &MF, // This is academic because all GHC calls are (supposed to be) tail calls return CSR_NoRegs_RegMask; - if (STI.isTargetDarwin() && STI.getTargetLowering()->supportSwiftError() && + if (STI.getTargetLowering()->supportSwiftError() && MF.getFunction()->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) return CSR_iOS_SwiftError_RegMask; diff --git a/test/CodeGen/ARM/swifterror.ll b/test/CodeGen/ARM/swifterror.ll index 15a831a3785..01957d61f9d 100644 --- a/test/CodeGen/ARM/swifterror.ll +++ b/test/CodeGen/ARM/swifterror.ll @@ -1,5 +1,6 @@ ; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-APPLE --check-prefix=CHECK-ARMV7 %s ; RUN: llc -verify-machineinstrs -O0 < %s -mtriple=armv7-apple-ios | FileCheck --check-prefix=CHECK-O0 %s +; RUN: llc -verify-machineinstrs < %s -mtriple=armv7-linux-androideabi | FileCheck --check-prefix=CHECK-ANDROID %s declare i8* @malloc(i64) declare void @free(i8*) @@ -503,6 +504,51 @@ declare swiftcc void @params_in_reg2(i32, i32, i32, i32, i8* swiftself, %swift_e ; CHECK-ARMV7-DAG: mov r2, r6 ; CHECK-ARMV7-DAG: mov r3, r11 ; CHECK-ARMV7: pop {r4, r5, r6, r7, r10, r11, pc} + +; CHECK-ANDROID-LABEL: params_and_return_in_reg +; CHECK-ANDROID: push {r4, r5, r6, r7, r10, r11, lr} +; CHECK-ANDROID: sub sp, sp, #12 +; CHECK-ANDROID: mov r5, r8 +; CHECK-ANDROID: str r10, [sp, #4] @ 4-byte Spill +; CHECK-ANDROID: mov r6, r3 +; CHECK-ANDROID: mov r7, r2 +; CHECK-ANDROID: mov r4, r1 +; CHECK-ANDROID: mov r11, r0 +; CHECK-ANDROID: mov r0, #1 +; CHECK-ANDROID: mov r1, #2 +; CHECK-ANDROID: mov r2, #3 +; CHECK-ANDROID: mov r3, #4 +; CHECK-ANDROID: mov r10, #0 +; CHECK-ANDROID: mov r8, #0 +; CHECK-ANDROID: bl params_in_reg2 +; CHECK-ANDROID: ldr r10, [sp, #4] @ 4-byte Reload +; CHECK-ANDROID: mov r0, r11 +; CHECK-ANDROID: str r8, [sp] @ 4-byte Spill +; CHECK-ANDROID: mov r1, r4 +; CHECK-ANDROID: mov r2, r7 +; CHECK-ANDROID: mov r3, r6 +; CHECK-ANDROID: mov r8, r5 +; CHECK-ANDROID: bl params_and_return_in_reg2 +; CHECK-ANDROID: mov r11, r8 +; CHECK-ANDROID: ldr r8, [sp] @ 4-byte Reload +; CHECK-ANDROID: mov r4, r0 +; CHECK-ANDROID: mov r6, r1 +; CHECK-ANDROID: mov r7, r2 +; CHECK-ANDROID: mov r5, r3 +; CHECK-ANDROID: mov r0, #1 +; CHECK-ANDROID: mov r1, #2 +; CHECK-ANDROID: mov r2, #3 +; CHECK-ANDROID: mov r3, #4 +; CHECK-ANDROID: mov r10, #0 +; CHECK-ANDROID: bl params_in_reg2 +; CHECK-ANDROID: mov r0, r4 +; CHECK-ANDROID: mov r1, r6 +; CHECK-ANDROID: mov r2, r7 +; CHECK-ANDROID: mov r3, r5 +; CHECK-ANDROID: mov r8, r11 +; CHECK-ANDROID: add sp, sp, #12 +; CHECK-ANDROID: pop {r4, r5, r6, r7, r10, r11, pc} + define swiftcc { i32, i32, i32, i32} @params_and_return_in_reg(i32, i32, i32, i32, i8* swiftself, %swift_error** nocapture swifterror %err) { %error_ptr_ref = alloca swifterror %swift_error*, align 8 store %swift_error* null, %swift_error** %error_ptr_ref @@ -522,6 +568,9 @@ declare void @acallee(i8*) ; CHECK-APPLE: tailcall_from_swifterror: ; CHECK-APPLE-NOT: b _acallee ; CHECK-APPLE: bl _acallee +; CHECK-ANDROID: tailcall_from_swifterror: +; CHECK-ANDROID-NOT: b acallee +; CHECK-ANDROID: bl acallee define swiftcc void @tailcall_from_swifterror(%swift_error** swifterror %error_ptr_ref) { entry: @@ -545,6 +594,11 @@ declare swiftcc void @foo2(%swift_error** swifterror) ; CHECK-APPLE: bl _foo2 ; CHECK-APPLE: mov r0, r8 +; CHECK-ANDROID-LABEL: testAssign +; CHECK-ANDROID: mov r8, #0 +; CHECK-ANDROID: bl foo2 +; CHECK-ANDROID: mov r0, r8 + define swiftcc %swift_error* @testAssign(i8* %error_ref) { entry: %error_ptr = alloca swifterror %swift_error*