summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-03-18 23:44:37 +0000
committerManman Ren <manman.ren@gmail.com>2016-03-18 23:44:37 +0000
commita3a019cf90d55ad46c04c0f9ffa9c7fc2c19f36d (patch)
treee6813d206028ba977df194b5e56c3986c24d9a07 /llvm
parent4865d89653f36cc16daffdbdec37629b88bb2d54 (diff)
downloadbcm5719-llvm-a3a019cf90d55ad46c04c0f9ffa9c7fc2c19f36d.tar.gz
bcm5719-llvm-a3a019cf90d55ad46c04c0f9ffa9c7fc2c19f36d.zip
[CXX_FAST_TLS] Fix issues in ARM.
We need to be careful on which registers can be explicitly handled via copies. Prologue, Epilogue use physical registers and if one belongs to the set of CSRsViaCopy, it will no longer be CSRed, since PEI overwrites it after the explicit copies. llvm-svn: 263857
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/ARM/ARMCallingConv.td5
-rw-r--r--llvm/test/CodeGen/ARM/cxx-tlscc.ll20
2 files changed, 19 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td
index 847ef87c1b2..0ca9007cf13 100644
--- a/llvm/lib/Target/ARM/ARMCallingConv.td
+++ b/llvm/lib/Target/ARM/ARMCallingConv.td
@@ -235,10 +235,11 @@ def CSR_iOS_CXX_TLS : CalleeSavedRegs<(add CSR_iOS, (sequence "R%u", 12, 1),
(sequence "D%u", 31, 0))>;
// CSRs that are handled by prologue, epilogue.
-def CSR_iOS_CXX_TLS_PE : CalleeSavedRegs<(add LR)>;
+def CSR_iOS_CXX_TLS_PE : CalleeSavedRegs<(add LR, R12, R11, R7, R5, R4)>;
// CSRs that are handled explicitly via copies.
-def CSR_iOS_CXX_TLS_ViaCopy : CalleeSavedRegs<(sub CSR_iOS_CXX_TLS, LR)>;
+def CSR_iOS_CXX_TLS_ViaCopy : CalleeSavedRegs<(sub CSR_iOS_CXX_TLS,
+ CSR_iOS_CXX_TLS_PE)>;
// The "interrupt" attribute is used to generate code that is acceptable in
// exception-handlers of various kinds. It makes us use a different return
diff --git a/llvm/test/CodeGen/ARM/cxx-tlscc.ll b/llvm/test/CodeGen/ARM/cxx-tlscc.ll
index 4005db3a435..48cce4f01be 100644
--- a/llvm/test/CodeGen/ARM/cxx-tlscc.ll
+++ b/llvm/test/CodeGen/ARM/cxx-tlscc.ll
@@ -6,6 +6,8 @@
; RUN: llc < %s -mtriple=armv7k-apple-watchos2.0 -O0 | FileCheck --check-prefix=CHECK-O0 --check-prefix=WATCH-O0 %s
; RUN: llc < %s -mtriple=armv7-apple-ios8.0 -O0 | FileCheck --check-prefix=CHECK-O0 --check-prefix=IOS-O0 %s
+; RUN: llc < %s -mtriple=thumbv7-apple-ios8.0 | FileCheck --check-prefix=THUMB %s
+
%struct.S = type { i8 }
@sg = internal thread_local global %struct.S zeroinitializer, align 1
@@ -20,6 +22,17 @@ declare %struct.S* @_ZN1SC1Ev(%struct.S* returned)
declare %struct.S* @_ZN1SD1Ev(%struct.S* returned)
declare i32 @_tlv_atexit(void (i8*)*, i8*, i8*)
+; Make sure Epilog does not overwrite an explicitly-handled CSR in CXX_FAST_TLS.
+; THUMB-LABEL: _ZTW2sg
+; THUMB: push {{.*}}lr
+; THUMB: blx
+; THUMB: bne [[TH_end:.?LBB0_[0-9]+]]
+; THUMB: blx
+; THUMB: tlv_atexit
+; THUMB: [[TH_end]]:
+; THUMB: blx
+; THUMB: r4
+; THUMB: pop {{.*}}r4
define cxx_fast_tlscc nonnull %struct.S* @_ZTW2sg() nounwind {
%.b.i = load i1, i1* @__tls_guard, align 1
br i1 %.b.i, label %__tls_init.exit, label %init.i
@@ -35,9 +48,8 @@ __tls_init.exit:
}
; CHECK-LABEL: _ZTW2sg
-; CHECK: push {lr}
-; CHECK-NOT: push {r1, r2, r3, r4, r7, lr}
-; CHECK-NOT: push {r9, r12}
+; CHECK: push {r4, r5, r7, lr}
+; CHECK: push {r11, r12}
; CHECK-NOT: vpush {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
; CHECK-NOT: vpush {d0, d1, d2, d3, d4, d5, d6, d7}
; CHECK: blx
@@ -50,7 +62,7 @@ __tls_init.exit:
; CHECK-NOT: vpop {d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31}
; CHECK-NOT: pop {r9, r12}
; CHECK-NOT: pop {r1, r2, r3, r4, r7, pc}
-; CHECK: pop {lr}
+; CHECK: pop {r4, r5, r7, pc}
; CHECK-O0-LABEL: _ZTW2sg
; WATCH-O0: push {r1, r2, r3, r6, r7, lr}
OpenPOWER on IntegriCloud