ARM: support TLS accesses on Darwin platforms
[oota-llvm.git] / test / CodeGen / ARM / darwin-tls.ll
1 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - -fast-isel %s | FileCheck %s --check-prefix=T2-MOVT-PIC
2 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=T2-LIT-PIC
3 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=T2-MOVT-STATIC
4 ; RUN: llc -mtriple=thumbv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=T2-LIT-STATIC
5 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s | FileCheck %s --check-prefix=ARM-MOVT-PIC
6 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt | FileCheck %s --check-prefix=ARM-LIT-PIC
7 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -relocation-model=static | FileCheck %s --check-prefix=ARM-MOVT-STATIC
8 ; RUN: llc -mtriple=armv7s-apple-ios7.0 -o - %s -mattr=+no-movt -relocation-model=static | FileCheck %s --check-prefix=ARM-LIT-STATIC
9
10
11 @local_tls_var = thread_local global i32 0
12 @external_tls_var = external thread_local global i32
13
14 define i32 @test_local_tls() {
15 ; T2-MOVT-PIC-LABEL: test_local_tls:
16 ; T2-MOVT-PIC: movw r0, :lower16:(_local_tls_var-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
17 ; T2-MOVT-PIC: movt r0, :upper16:(_local_tls_var-([[PCREL_LOC]]+4))
18 ; T2-MOVT-PIC: [[PCREL_LOC]]:
19 ; T2-MOVT-PIC-NEXT: add r0, pc
20 ; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
21 ; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
22 ; T2-MOVT-PIC: ldr r0, [r0]
23
24 ; T2-LIT-PIC-LABEL: test_local_tls:
25 ; T2-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
26 ; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
27 ; T2-LIT-PIC-NEXT: add r0, pc
28 ; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
29 ; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
30 ; T2-LIT-PIC: ldr r0, [r0]
31 ; T2-LIT-PIC: [[LOCAL_VAR_ADDR]]:
32 ; T2-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+4)
33
34 ; T2-MOVT-STATIC-LABEL: test_local_tls:
35 ; T2-MOVT-STATIC: movw r0, :lower16:_local_tls_var
36 ; T2-MOVT-STATIC: movt r0, :upper16:_local_tls_var
37 ; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
38 ; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
39 ; T2-MOVT-STATIC: ldr r0, [r0]
40
41 ; T2-LIT-STATIC-LABEL: test_local_tls:
42 ; T2-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
43 ; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
44 ; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
45 ; T2-LIT-STATIC: ldr r0, [r0]
46 ; T2-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
47 ; T2-LIT-STATIC-NEXT: .long _local_tls_var
48
49 ; ARM-MOVT-PIC-LABEL: test_local_tls:
50 ; ARM-MOVT-PIC: movw [[VARPC1:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC1:LPC[0-9]+_[0-9]+]]+8))
51 ; ARM-MOVT-PIC: movt [[VARPC1]], :upper16:(_local_tls_var-([[PCREL_LOC1]]+8))
52 ; ARM-MOVT-PIC: [[PCREL_LOC1]]:
53 ; ARM-MOVT-PIC: add r0, pc, [[VARPC1]]
54 ; ARM-MOVT-PIC: movw [[VARPC2:r[0-9]+]], :lower16:(_local_tls_var-([[PCREL_LOC2:LPC[0-9]+_[0-9]+]]+8))
55 ; ARM-MOVT-PIC: movt [[VARPC2]], :upper16:(_local_tls_var-([[PCREL_LOC2]]+8))
56 ; ARM-MOVT-PIC: [[PCREL_LOC2]]:
57 ; ARM-MOVT-PIC-NEXT: ldr [[TLV_GET_ADDR:r[0-9]+]], [pc, [[VARPC2]]]
58 ; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
59 ; ARM-MOVT-PIC: ldr r0, [r0]
60
61 ; ARM-LIT-PIC-LABEL: test_local_tls:
62 ; ARM-LIT-PIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
63 ; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
64 ; ARM-LIT-PIC-NEXT: add r0, pc
65 ; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
66 ; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
67 ; ARM-LIT-PIC: ldr r0, [r0]
68 ; ARM-LIT-PIC: [[LOCAL_VAR_ADDR]]:
69 ; ARM-LIT-PIC-NEXT: .long _local_tls_var-([[PCREL_LOC]]+8)
70
71 ; ARM-MOVT-STATIC-LABEL: test_local_tls:
72 ; ARM-MOVT-STATIC: movw r0, :lower16:_local_tls_var
73 ; ARM-MOVT-STATIC: movt r0, :upper16:_local_tls_var
74 ; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
75 ; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
76 ; ARM-MOVT-STATIC: ldr r0, [r0]
77
78 ; ARM-LIT-STATIC-LABEL: test_local_tls:
79 ; ARM-LIT-STATIC: ldr r0, [[LOCAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
80 ; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
81 ; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
82 ; ARM-LIT-STATIC: ldr r0, [r0]
83 ; ARM-LIT-STATIC: [[LOCAL_VAR_ADDR]]:
84 ; ARM-LIT-STATIC-NEXT: .long _local_tls_var
85
86
87   %val = load i32, i32* @local_tls_var, align 4
88   ret i32 %val
89 }
90
91 define i32 @test_external_tls() {
92 ; T2-MOVT-PIC-LABEL: test_external_tls:
93 ; T2-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+4))
94 ; T2-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4))
95 ; T2-MOVT-PIC: [[PCREL_LOC]]:
96 ; T2-MOVT-PIC-NEXT: add r[[EXTGOT]], pc
97 ; T2-MOVT-PIC: ldr r0, [r[[EXTGOT]]]
98 ; T2-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
99 ; T2-MOVT-PIC: blx [[TLV_GET_ADDR]]
100 ; T2-MOVT-PIC: ldr r0, [r0]
101
102 ; T2-LIT-PIC-LABEL: test_external_tls:
103 ; T2-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
104 ; T2-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
105 ; T2-LIT-PIC-NEXT: add r[[EXTGOT]], pc
106 ; T2-LIT-PIC: ldr r0, [r[[EXTGOT]]]
107 ; T2-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
108 ; T2-LIT-PIC: blx [[TLV_GET_ADDR]]
109 ; T2-LIT-PIC: ldr r0, [r0]
110 ; T2-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
111 ; T2-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+4)
112
113 ; T2-MOVT-STATIC-LABEL: test_external_tls:
114 ; T2-MOVT-STATIC: movw r0, :lower16:_external_tls_var
115 ; T2-MOVT-STATIC: movt r0, :upper16:_external_tls_var
116 ; T2-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
117 ; T2-MOVT-STATIC: blx [[TLV_GET_ADDR]]
118 ; T2-MOVT-STATIC: ldr r0, [r0]
119
120 ; T2-LIT-STATIC-LABEL: test_external_tls:
121 ; T2-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
122 ; T2-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
123 ; T2-LIT-STATIC: blx [[TLV_GET_ADDR]]
124 ; T2-LIT-STATIC: ldr r0, [r0]
125 ; T2-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
126 ; T2-LIT-STATIC-NEXT: .long _external_tls_var
127
128 ; ARM-MOVT-PIC-LABEL: test_external_tls:
129 ; ARM-MOVT-PIC: movw r[[EXTGOT:[0-9]+]], :lower16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC:LPC[0-9]+_[0-9]+]]+8))
130 ; ARM-MOVT-PIC: movt r[[EXTGOT]], :upper16:(L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8))
131 ; ARM-MOVT-PIC: [[PCREL_LOC]]:
132 ; ARM-MOVT-PIC-NEXT: ldr r0, [pc, r[[EXTGOT]]]
133 ; ARM-MOVT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
134 ; ARM-MOVT-PIC: blx [[TLV_GET_ADDR]]
135 ; ARM-MOVT-PIC: ldr r0, [r0]
136
137 ; ARM-LIT-PIC-LABEL: test_external_tls:
138 ; ARM-LIT-PIC: ldr r[[EXTGOT:[0-9]+]], [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
139 ; ARM-LIT-PIC: [[PCREL_LOC:LPC[0-9]+_[0-9]+]]:
140 ; ARM-LIT-PIC-NEXT: add r[[EXTGOT]], pc
141 ; ARM-LIT-PIC: ldr r0, [r[[EXTGOT]]]
142 ; ARM-LIT-PIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
143 ; ARM-LIT-PIC: blx [[TLV_GET_ADDR]]
144 ; ARM-LIT-PIC: ldr r0, [r0]
145 ; ARM-LIT-PIC: [[EXTERNAL_VAR_ADDR]]:
146 ; ARM-LIT-PIC-NEXT: .long L_external_tls_var$non_lazy_ptr-([[PCREL_LOC]]+8)
147
148 ; ARM-MOVT-STATIC-LABEL: test_external_tls:
149 ; ARM-MOVT-STATIC: movw r0, :lower16:_external_tls_var
150 ; ARM-MOVT-STATIC: movt r0, :upper16:_external_tls_var
151 ; ARM-MOVT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
152 ; ARM-MOVT-STATIC: blx [[TLV_GET_ADDR]]
153 ; ARM-MOVT-STATIC: ldr r0, [r0]
154
155 ; ARM-LIT-STATIC-LABEL: test_external_tls:
156 ; ARM-LIT-STATIC: ldr r0, [[EXTERNAL_VAR_ADDR:LCPI[0-9]+_[0-9]+]]
157 ; ARM-LIT-STATIC: ldr [[TLV_GET_ADDR:r[0-9]+]], [r0]
158 ; ARM-LIT-STATIC: blx [[TLV_GET_ADDR]]
159 ; ARM-LIT-STATIC: ldr r0, [r0]
160 ; ARM-LIT-STATIC: [[EXTERNAL_VAR_ADDR]]:
161 ; ARM-LIT-STATIC-NEXT: .long _external_tls_var
162
163   %val = load i32, i32* @external_tls_var, align 4
164   ret i32 %val
165 }