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