]> granicus.if.org Git - llvm/commitdiff
[ARM] Use Swift error registers on non-Darwin targets
authorBrian Gesiak <modocache@gmail.com>
Wed, 30 Aug 2017 20:03:54 +0000 (20:03 +0000)
committerBrian Gesiak <modocache@gmail.com>
Wed, 30 Aug 2017 20:03:54 +0000 (20:03 +0000)
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

lib/Target/ARM/ARMBaseRegisterInfo.cpp
test/CodeGen/ARM/swifterror.ll

index 370c0a7f5c537748e34a13569db10e192b8cd7b3..ee55cd6f9ea8d8bb48a0d597143992ba650414f2 100644 (file)
@@ -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;
 
index 15a831a3785133d3d7f189bfcb3eb8644d4ecb3e..01957d61f9d6b2d03a3a9b40267e4caec1edd1fa 100644 (file)
@@ -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*