Add AArch64 as an experimental target.
[oota-llvm.git] / test / CodeGen / AArch64 / tls-dynamics.ll
1 ; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -verify-machineinstrs < %s | FileCheck %s
2 ; RUN: llc -mtriple=aarch64-none-linux-gnu -relocation-model=pic -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s
3
4 @general_dynamic_var = external thread_local global i32
5
6 define i32 @test_generaldynamic() {
7 ; CHECK: test_generaldynamic:
8
9   %val = load i32* @general_dynamic_var
10   ret i32 %val
11
12 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
13 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var
14 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var]
15 ; CHECK: .tlsdesccall general_dynamic_var
16 ; CHECK-NEXT: blr [[CALLEE]]
17
18 ; CHECK: mrs x[[TP:[0-9]+]], tpidr_el0
19 ; CHECK: ldr w0, [x[[TP]], x0]
20
21 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE
22 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
23 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
24 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
25
26 }
27
28 define i32* @test_generaldynamic_addr() {
29 ; CHECK: test_generaldynamic_addr:
30
31   ret i32* @general_dynamic_var
32
33 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:general_dynamic_var
34 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var
35 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:general_dynamic_var]
36 ; CHECK: .tlsdesccall general_dynamic_var
37 ; CHECK-NEXT: blr [[CALLEE]]
38
39 ; CHECK: mrs [[TP:x[0-9]+]], tpidr_el0
40 ; CHECK: add x0, [[TP]], x0
41
42 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE
43 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
44 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
45 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
46
47 }
48
49 @local_dynamic_var = external thread_local(localdynamic) global i32
50
51 define i32 @test_localdynamic() {
52 ; CHECK: test_localdynamic:
53
54   %val = load i32* @local_dynamic_var
55   ret i32 %val
56
57 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
58 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_
59 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_]
60 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_
61 ; CHECK-NEXT: blr [[CALLEE]]
62
63 ; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var
64 ; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var
65
66 ; CHECK: ldr w0, [x0, [[DTP_OFFSET]]]
67
68 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE
69 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
70 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
71 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
72
73 }
74
75 define i32* @test_localdynamic_addr() {
76 ; CHECK: test_localdynamic_addr:
77
78   ret i32* @local_dynamic_var
79
80 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
81 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_
82 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_]
83 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_
84 ; CHECK-NEXT: blr [[CALLEE]]
85
86 ; CHECK: movz [[DTP_OFFSET:x[0-9]+]], #:dtprel_g1:local_dynamic_var
87 ; CHECK: movk [[DTP_OFFSET]], #:dtprel_g0_nc:local_dynamic_var
88
89 ; CHECK: add x0, x0, [[DTP_OFFSET]]
90
91 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADR_PAGE
92 ; CHECK-RELOC: R_AARCH64_TLSDESC_ADD_LO12_NC
93 ; CHECK-RELOC: R_AARCH64_TLSDESC_LD64_LO12_NC
94 ; CHECK-RELOC: R_AARCH64_TLSDESC_CALL
95
96 }
97
98 ; The entire point of the local-dynamic access model is to have a single call to
99 ; the expensive resolver. Make sure we achieve that goal.
100
101 @local_dynamic_var2 = external thread_local(localdynamic) global i32
102
103 define i32 @test_localdynamic_deduplicate() {
104 ; CHECK: test_localdynamic_deduplicate:
105
106   %val = load i32* @local_dynamic_var
107   %val2 = load i32* @local_dynamic_var2
108
109   %sum = add i32 %val, %val2
110   ret i32 %sum
111
112 ; CHECK: adrp x[[TLSDESC_HI:[0-9]+]], :tlsdesc:_TLS_MODULE_BASE_
113 ; CHECK: add x0, x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_
114 ; CHECK: ldr [[CALLEE:x[0-9]+]], [x[[TLSDESC_HI]], #:tlsdesc_lo12:_TLS_MODULE_BASE_]
115 ; CHECK: .tlsdesccall _TLS_MODULE_BASE_
116 ; CHECK-NEXT: blr [[CALLEE]]
117
118 ; CHECK-NOT: _TLS_MODULE_BASE_
119
120 ; CHECK: ret
121 }