Home | History | Annotate | Download | only in AArch64
      1 ; RUN: llc -emulated-tls -mtriple=aarch64-linux-android \
      2 ; RUN:     -relocation-model=pic -disable-fp-elim < %s | FileCheck -check-prefix=ARM64 %s
      3 
      4 ; Copied from X86/emutls.ll
      5 
      6 ; Use my_emutls_get_address like __emutls_get_address.
      7 @my_emutls_v_xyz = external global i8*, align 4
      8 declare i8* @my_emutls_get_address(i8*)
      9 
     10 define i32 @my_get_xyz() {
     11 ; ARM64-LABEL: my_get_xyz:
     12 ; ARM64:        adrp x0, :got:my_emutls_v_xyz
     13 ; ARM64-NEXT:   ldr x0, [x0, :got_lo12:my_emutls_v_xyz]
     14 ; ARM64-NEXT:   bl my_emutls_get_address
     15 ; ARM64-NEXT:   ldr  w0, [x0]
     16 ; ARM64-NEXT:   ldp x29, x30, [sp]
     17 
     18 entry:
     19   %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*))
     20   %0 = bitcast i8* %call to i32*
     21   %1 = load i32, i32* %0, align 4
     22   ret i32 %1
     23 }
     24 
     25 @i1 = thread_local global i32 15
     26 @i2 = external thread_local global i32
     27 @i3 = internal thread_local global i32 15
     28 @i4 = hidden thread_local global i32 15
     29 @i5 = external hidden thread_local global i32
     30 @s1 = thread_local global i16 15
     31 @b1 = thread_local global i8 0
     32 
     33 define i32 @f1() {
     34 ; ARM64-LABEL: f1:
     35 ; ARM64:        adrp x0, :got:__emutls_v.i1
     36 ; ARM64-NEXT:   ldr x0, [x0, :got_lo12:__emutls_v.i1]
     37 ; ARM64-NEXT:   bl __emutls_get_address
     38 ; ARM64-NEXT:   ldr  w0, [x0]
     39 ; ARM64-NEXT:   ldp x29, x30, [sp]
     40 
     41 entry:
     42   %tmp1 = load i32, i32* @i1
     43   ret i32 %tmp1
     44 }
     45 
     46 define i32* @f2() {
     47 ; ARM64-LABEL: f2:
     48 ; ARM64:        adrp x0, :got:__emutls_v.i1
     49 ; ARM64-NEXT:   ldr x0, [x0, :got_lo12:__emutls_v.i1]
     50 ; ARM64-NEXT:   bl __emutls_get_address
     51 ; ARM64-NEXT:   ldp x29, x30, [sp]
     52 
     53 entry:
     54   ret i32* @i1
     55 }
     56 
     57 define i32 @f5() nounwind {
     58 ; ARM64-LABEL: f5:
     59 ; ARM64:        adrp x0, __emutls_v.i3
     60 ; ARM64:        add x0, x0, :lo12:__emutls_v.i3
     61 ; ARM64:        bl __emutls_get_address
     62 ; ARM64-NEXT:   ldr w0, [x0]
     63 
     64 entry:
     65   %tmp1 = load i32, i32* @i3
     66   ret i32 %tmp1
     67 }
     68 
     69 define i32* @f6() {
     70 ; ARM64-LABEL: f6:
     71 ; ARM64:        adrp x0, __emutls_v.i3
     72 ; ARM64:        add x0, x0, :lo12:__emutls_v.i3
     73 ; ARM64-NEXT:   bl __emutls_get_address
     74 ; ARM64-NEXT:   ldp x29, x30, [sp]
     75 
     76 entry:
     77   ret i32* @i3
     78 }
     79 
     80 ; Simple test of comdat __thread variables.
     81 ; template <class T> struct A { static __thread T x; };
     82 ; template <class T> T __thread A<T>::x;
     83 ; int getIntX() { return A<int>::x++; }
     84 ; float getFloatX() { return A<float>::x++; }
     85 
     86 $_ZN1AIiE1xE = comdat any
     87 $_ZN1AIfE1xE = comdat any
     88 @_ZN1AIiE1xE = linkonce_odr thread_local global i32 0, comdat, align 4
     89 @_ZN1AIfE1xE = linkonce_odr thread_local global float 0.000000e+00, comdat, align 4
     90 
     91 define i32 @_Z7getIntXv() {
     92 ; ARM64-LABEL: _Z7getIntXv:
     93 ; ARM64:        adrp x0, :got:__emutls_v._ZN1AIiE1xE
     94 ; ARM64:        ldr x0, [x0, :got_lo12:__emutls_v._ZN1AIiE1xE]
     95 ; ARM64-NEXT:   bl __emutls_get_address
     96 ; ARM64-NEXT:   ldr {{.*}}, [x0]
     97 ; ARM64:        add
     98 ; ARM64:        str {{.*}}, [x0]
     99 
    100 entry:
    101   %0 = load i32, i32* @_ZN1AIiE1xE, align 4
    102   %inc = add nsw i32 %0, 1
    103   store i32 %inc, i32* @_ZN1AIiE1xE, align 4
    104   ret i32 %0
    105 }
    106 
    107 define float @_Z9getFloatXv() {
    108 ; ARM64-LABEL: _Z9getFloatXv:
    109 ; ARM64:        adrp x0, :got:__emutls_v._ZN1AIfE1xE
    110 ; ARM64:        ldr x0, [x0, :got_lo12:__emutls_v._ZN1AIfE1xE]
    111 ; ARM64-NEXT:   bl __emutls_get_address
    112 ; ARM64-NEXT:   ldr {{.*}}, [x0]
    113 ; ARM64:        fadd s{{.*}}, s
    114 ; ARM64:        str s{{.*}}, [x0]
    115 
    116 entry:
    117   %0 = load float, float* @_ZN1AIfE1xE, align 4
    118   %inc = fadd float %0, 1.000000e+00
    119   store float %inc, float* @_ZN1AIfE1xE, align 4
    120   ret float %0
    121 }
    122 
    123 
    124 ;;;;;;;;;;;;;; 64-bit __emutls_v. and __emutls_t.
    125 
    126 ; ARM64:      .data{{$}}
    127 ; ARM64:      .globl __emutls_v.i1
    128 ; ARM64-LABEL: __emutls_v.i1:
    129 ; ARM64-NEXT: .xword 4
    130 ; ARM64-NEXT: .xword 4
    131 ; ARM64-NEXT: .xword 0
    132 ; ARM64-NEXT: .xword __emutls_t.i1
    133 
    134 ; ARM64:      .section .rodata,
    135 ; ARM64-LABEL: __emutls_t.i1:
    136 ; ARM64-NEXT: .word 15
    137 
    138 ; ARM64-NOT:   __emutls_v.i2
    139 
    140 ; ARM64:      .data{{$}}
    141 ; ARM64-NOT:  .globl
    142 ; ARM64-LABEL: __emutls_v.i3:
    143 ; ARM64-NEXT: .xword 4
    144 ; ARM64-NEXT: .xword 4
    145 ; ARM64-NEXT: .xword 0
    146 ; ARM64-NEXT: .xword __emutls_t.i3
    147 
    148 ; ARM64:      .section .rodata,
    149 ; ARM64-LABEL: __emutls_t.i3:
    150 ; ARM64-NEXT: .word 15
    151 
    152 ; ARM64:      .hidden __emutls_v.i4
    153 ; ARM64:      .data{{$}}
    154 ; ARM64:      .globl __emutls_v.i4
    155 ; ARM64-LABEL: __emutls_v.i4:
    156 ; ARM64-NEXT: .xword 4
    157 ; ARM64-NEXT: .xword 4
    158 ; ARM64-NEXT: .xword 0
    159 ; ARM64-NEXT: .xword __emutls_t.i4
    160 
    161 ; ARM64:      .section .rodata,
    162 ; ARM64-LABEL: __emutls_t.i4:
    163 ; ARM64-NEXT: .word 15
    164 
    165 ; ARM64-NOT:   __emutls_v.i5:
    166 ; ARM64:      .hidden __emutls_v.i5
    167 ; ARM64-NOT:   __emutls_v.i5:
    168 
    169 ; ARM64:      .data{{$}}
    170 ; ARM64:      .globl __emutls_v.s1
    171 ; ARM64-LABEL: __emutls_v.s1:
    172 ; ARM64-NEXT: .xword 2
    173 ; ARM64-NEXT: .xword 2
    174 ; ARM64-NEXT: .xword 0
    175 ; ARM64-NEXT: .xword __emutls_t.s1
    176 
    177 ; ARM64:      .section .rodata,
    178 ; ARM64-LABEL: __emutls_t.s1:
    179 ; ARM64-NEXT: .hword 15
    180 
    181 ; ARM64:      .data{{$}}
    182 ; ARM64-LABEL: __emutls_v.b1:
    183 ; ARM64-NEXT: .xword 1
    184 ; ARM64-NEXT: .xword 1
    185 ; ARM64-NEXT: .xword 0
    186 ; ARM64-NEXT: .xword 0
    187 
    188 ; ARM64-NOT:   __emutls_t.b1
    189 
    190 ; ARM64:      .section .data.__emutls_v._ZN1AIiE1xE,{{.*}},__emutls_v._ZN1AIiE1xE,comdat
    191 ; ARM64:      .weak __emutls_v._ZN1AIiE1xE
    192 ; ARM64:      .p2align 3
    193 ; ARM64-LABEL: __emutls_v._ZN1AIiE1xE:
    194 ; ARM64-NEXT: .xword 4
    195 ; ARM64-NEXT: .xword 4
    196 ; ARM64-NEXT: .xword 0
    197 ; ARM64-NEXT: .xword 0
    198 
    199 ; ARM64:      .section .data.__emutls_v._ZN1AIfE1xE,{{.*}},__emutls_v._ZN1AIfE1xE,comdat
    200 ; ARM64:      .weak __emutls_v._ZN1AIfE1xE
    201 ; ARM64:      .p2align 3
    202 ; ARM64-LABEL: __emutls_v._ZN1AIfE1xE:
    203 ; ARM64-NEXT: .xword 4
    204 ; ARM64-NEXT: .xword 4
    205 ; ARM64-NEXT: .xword 0
    206 ; ARM64-NEXT: .xword __emutls_t._ZN1AIfE1xE
    207 
    208 ; ARM64:      .section .rodata.__emutls_t._ZN1AIfE1xE,{{.*}},__emutls_t._ZN1AIfE1xE,comdat
    209 ; ARM64:      .weak __emutls_t._ZN1AIfE1xE
    210 ; ARM64:      .p2align 2
    211 ; ARM64-LABEL: __emutls_t._ZN1AIfE1xE:
    212 ; ARM64-NEXT: .word 0
    213 ; ARM64-NEXT: .size
    214