Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X32 %s
      2 ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s
      3 ; RUN: llc < %s -emulated-tls -march=x86 -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X32 %s
      4 ; RUN: llc < %s -emulated-tls -march=x86-64 -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s
      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 ; X32-LABEL: my_get_xyz:
     12 ; X32:      movl my_emutls_v_xyz@GOT(%ebx), %eax
     13 ; X32-NEXT: movl %eax, (%esp)
     14 ; X32-NEXT: calll my_emutls_get_address@PLT
     15 ; X64-LABEL: my_get_xyz:
     16 ; X64:      movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi
     17 ; X64-NEXT: callq my_emutls_get_address@PLT
     18 ; X64-NEXT: movl (%rax), %eax
     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 @i = thread_local global i32 15
     28 @j = internal thread_local global i32 42
     29 @k = internal thread_local global i32 0, align 8
     30 
     31 define i32 @f1() {
     32 entry:
     33   %tmp1 = load i32, i32* @i
     34   ret i32 %tmp1
     35 }
     36 
     37 ; X32-LABEL: f1:
     38 ; X32:      movl __emutls_v.i@GOT(%ebx), %eax
     39 ; X32-NEXT: movl %eax, (%esp)
     40 ; X32-NEXT: calll __emutls_get_address@PLT
     41 ; X64-LABEL: f1:
     42 ; X64:      movq __emutls_v.i@GOTPCREL(%rip), %rdi
     43 ; X64-NEXT: callq __emutls_get_address@PLT
     44 ; X64-NEXT: movl (%rax), %eax
     45 
     46 @i2 = external thread_local global i32
     47 
     48 define i32* @f2() {
     49 entry:
     50   ret i32* @i
     51 }
     52 
     53 ; X32-LABEL: f2:
     54 ; X64-LABEL: f2:
     55 
     56 
     57 define i32 @f3() {
     58 entry:
     59   %tmp1 = load i32, i32* @i  ; <i32> [#uses=1]
     60   ret i32 %tmp1
     61 }
     62 
     63 ; X32-LABEL: f3:
     64 ; X64-LABEL: f3:
     65 
     66 
     67 define i32* @f4() nounwind {
     68 entry:
     69   ret i32* @i
     70 }
     71 
     72 ; X32-LABEL: f4:
     73 ; X64-LABEL: f4:
     74 
     75 
     76 define i32 @f5() nounwind {
     77 entry:
     78   %0 = load i32, i32* @j, align 4
     79   %1 = load i32, i32* @k, align 4
     80   %add = add nsw i32 %0, %1
     81   ret i32 %add
     82 }
     83 
     84 ; X32-LABEL: f5:
     85 ; X32:      leal __emutls_v.j@GOTOFF(%ebx), %eax
     86 ; X32-NEXT: movl %eax, (%esp)
     87 ; X32-NEXT: calll __emutls_get_address@PLT
     88 ; X32-NEXT: movl (%eax), %esi
     89 ; X32-NEXT: leal __emutls_v.k@GOTOFF(%ebx), %eax
     90 ; X32-NEXT: movl %eax, (%esp)
     91 ; X32-NEXT: calll __emutls_get_address@PLT
     92 ; X32-NEXT: addl (%eax), %esi
     93 ; X32-NEXT: movl %esi, %eax
     94 
     95 ; X64-LABEL: f5:
     96 ; X64:      leaq __emutls_v.j(%rip), %rdi
     97 ; X64-NEXT: callq __emutls_get_address@PLT
     98 ; X64-NEXT: movl (%rax), %ebx
     99 ; X64-NEXT: leaq __emutls_v.k(%rip), %rdi
    100 ; X64-NEXT: callq __emutls_get_address@PLT
    101 ; X64-NEXT: addl (%rax), %ebx
    102 ; X64-NEXT: movl %ebx, %eax
    103 
    104 ;;;;; 32-bit targets
    105 
    106 ; X32:      .data{{$}}
    107 ; X32:      .globl __emutls_v.i
    108 ; X32-LABEL: __emutls_v.i:
    109 ; X32-NEXT: .long 4
    110 ; X32-NEXT: .long 4
    111 ; X32-NEXT: .long 0
    112 ; X32-NEXT: .long __emutls_t.i
    113 
    114 ; X32:      .section .rodata,
    115 ; X32-LABEL: __emutls_t.i:
    116 ; X32-NEXT: .long 15
    117 
    118 ; X32:      .data{{$}}
    119 ; X32-NOT:  .globl
    120 ; X32-LABEL: __emutls_v.j:
    121 ; X32-NEXT: .long 4
    122 ; X32-NEXT: .long 4
    123 ; X32-NEXT: .long 0
    124 ; X32-NEXT: .long __emutls_t.j
    125 
    126 ; X32:      .section .rodata,
    127 ; X32-LABEL: __emutls_t.j:
    128 ; X32-NEXT: .long 42
    129 
    130 ; X32:      .data{{$}}
    131 ; X32-NOT:  .globl
    132 ; X32-LABEL: __emutls_v.k:
    133 ; X32-NEXT: .long 4
    134 ; X32-NEXT: .long 8
    135 ; X32-NEXT: .long 0
    136 ; X32-NEXT: .long 0
    137 
    138 ; X32-NOT:   __emutls_t.k:
    139 
    140 ;;;;; 64-bit targets
    141 
    142 ; X64:      .data{{$}}
    143 ; X64:      .globl __emutls_v.i
    144 ; X64-LABEL: __emutls_v.i:
    145 ; X64-NEXT: .quad 4
    146 ; X64-NEXT: .quad 4
    147 ; X64-NEXT: .quad 0
    148 ; X64-NEXT: .quad __emutls_t.i
    149 
    150 ; X64:      .section .rodata,
    151 ; X64-LABEL: __emutls_t.i:
    152 ; X64-NEXT: .long 15
    153 
    154 ; X64:      .data{{$}}
    155 ; X64-NOT:  .globl
    156 ; X64-LABEL: __emutls_v.j:
    157 ; X64-NEXT: .quad 4
    158 ; X64-NEXT: .quad 4
    159 ; X64-NEXT: .quad 0
    160 ; X64-NEXT: .quad __emutls_t.j
    161 
    162 ; X64:      .section .rodata,
    163 ; X64-LABEL: __emutls_t.j:
    164 ; X64-NEXT: .long 42
    165 
    166 ; X64:      .data{{$}}
    167 ; X64-NOT:  .globl
    168 ; X64-LABEL: __emutls_v.k:
    169 ; X64-NEXT: .quad 4
    170 ; X64-NEXT: .quad 8
    171 ; X64-NEXT: .quad 0
    172 ; X64-NEXT: .quad 0
    173 
    174 ; X64-NOT:   __emutls_t.k:
    175