Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -march=x86 -mtriple=i386-linux-gnu | FileCheck -check-prefix=X32_LINUX %s
      2 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-linux-gnu | FileCheck -check-prefix=X64_LINUX %s
      3 ; RUN: llc < %s -march=x86 -mtriple=x86-pc-win32 | FileCheck -check-prefix=X32_WIN %s
      4 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-pc-win32 | FileCheck -check-prefix=X64_WIN %s
      5 
      6 @i1 = thread_local global i32 15
      7 @i2 = external thread_local global i32
      8 @i3 = internal thread_local global i32 15
      9 @i4 = hidden thread_local global i32 15
     10 @i5 = external hidden thread_local global i32
     11 @s1 = thread_local global i16 15
     12 @b1 = thread_local global i8 0
     13 
     14 define i32 @f1() {
     15 ; X32_LINUX: f1:
     16 ; X32_LINUX:      movl %gs:i1@NTPOFF, %eax
     17 ; X32_LINUX-NEXT: ret
     18 ; X64_LINUX: f1:
     19 ; X64_LINUX:      movl %fs:i1@TPOFF, %eax
     20 ; X64_LINUX-NEXT: ret
     21 ; X32_WIN: f1:
     22 ; X32_WIN:      movl __tls_index, %eax
     23 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
     24 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
     25 ; X32_WIN-NEXT: movl _i1@SECREL(%eax), %eax
     26 ; X32_WIN-NEXT: ret
     27 ; X64_WIN: f1:
     28 ; X64_WIN:      movl _tls_index(%rip), %eax
     29 ; X64_WIN-NEXT: movq %gs:88, %rcx
     30 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
     31 ; X64_WIN-NEXT: movl i1@SECREL(%rax), %eax
     32 ; X64_WIN-NEXT: ret
     33 
     34 entry:
     35 	%tmp1 = load i32* @i1
     36 	ret i32 %tmp1
     37 }
     38 
     39 define i32* @f2() {
     40 ; X32_LINUX: f2:
     41 ; X32_LINUX:      movl %gs:0, %eax
     42 ; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax
     43 ; X32_LINUX-NEXT: ret
     44 ; X64_LINUX: f2:
     45 ; X64_LINUX:      movq %fs:0, %rax
     46 ; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax
     47 ; X64_LINUX-NEXT: ret
     48 ; X32_WIN: f2:
     49 ; X32_WIN:      movl __tls_index, %eax
     50 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
     51 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
     52 ; X32_WIN-NEXT: leal _i1@SECREL(%eax), %eax
     53 ; X32_WIN-NEXT: ret
     54 ; X64_WIN: f2:
     55 ; X64_WIN:      movl _tls_index(%rip), %eax
     56 ; X64_WIN-NEXT: movq %gs:88, %rcx
     57 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
     58 ; X64_WIN-NEXT: leaq i1@SECREL(%rax), %rax
     59 ; X64_WIN-NEXT: ret
     60 
     61 entry:
     62 	ret i32* @i1
     63 }
     64 
     65 define i32 @f3() nounwind {
     66 ; X32_LINUX: f3:
     67 ; X32_LINUX:      movl i2@INDNTPOFF, %eax
     68 ; X32_LINUX-NEXT: movl %gs:(%eax), %eax
     69 ; X32_LINUX-NEXT: ret
     70 ; X64_LINUX: f3:
     71 ; X64_LINUX:      movq i2@GOTTPOFF(%rip), %rax
     72 ; X64_LINUX-NEXT: movl %fs:(%rax), %eax
     73 ; X64_LINUX-NEXT: ret
     74 ; X32_WIN: f3:
     75 ; X32_WIN:      movl __tls_index, %eax
     76 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
     77 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
     78 ; X32_WIN-NEXT: movl _i2@SECREL(%eax), %eax
     79 ; X32_WIN-NEXT: ret
     80 ; X64_WIN: f3:
     81 ; X64_WIN:      movl _tls_index(%rip), %eax
     82 ; X64_WIN-NEXT: movq %gs:88, %rcx
     83 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
     84 ; X64_WIN-NEXT: movl i2@SECREL(%rax), %eax
     85 ; X64_WIN-NEXT: ret
     86 
     87 entry:
     88 	%tmp1 = load i32* @i2
     89 	ret i32 %tmp1
     90 }
     91 
     92 define i32* @f4() {
     93 ; X32_LINUX: f4:
     94 ; X32_LINUX:      movl %gs:0, %eax
     95 ; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax
     96 ; X32_LINUX-NEXT: ret
     97 ; X64_LINUX: f4:
     98 ; X64_LINUX:      movq %fs:0, %rax
     99 ; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax
    100 ; X64_LINUX-NEXT: ret
    101 ; X32_WIN: f4:
    102 ; X32_WIN:      movl __tls_index, %eax
    103 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    104 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    105 ; X32_WIN-NEXT: leal _i2@SECREL(%eax), %eax
    106 ; X32_WIN-NEXT: ret
    107 ; X64_WIN: f4:
    108 ; X64_WIN:      movl _tls_index(%rip), %eax
    109 ; X64_WIN-NEXT: movq %gs:88, %rcx
    110 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    111 ; X64_WIN-NEXT: leaq i2@SECREL(%rax), %rax
    112 ; X64_WIN-NEXT: ret
    113 
    114 entry:
    115 	ret i32* @i2
    116 }
    117 
    118 define i32 @f5() nounwind {
    119 ; X32_LINUX: f5:
    120 ; X32_LINUX:      movl %gs:i3@NTPOFF, %eax
    121 ; X32_LINUX-NEXT: ret
    122 ; X64_LINUX: f5:
    123 ; X64_LINUX:      movl %fs:i3@TPOFF, %eax
    124 ; X64_LINUX-NEXT: ret
    125 ; X32_WIN: f5:
    126 ; X32_WIN:      movl __tls_index, %eax
    127 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    128 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    129 ; X32_WIN-NEXT: movl _i3@SECREL(%eax), %eax
    130 ; X32_WIN-NEXT: ret
    131 ; X64_WIN: f5:
    132 ; X64_WIN:      movl _tls_index(%rip), %eax
    133 ; X64_WIN-NEXT: movq %gs:88, %rcx
    134 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    135 ; X64_WIN-NEXT: movl i3@SECREL(%rax), %eax
    136 ; X64_WIN-NEXT: ret
    137 
    138 entry:
    139 	%tmp1 = load i32* @i3
    140 	ret i32 %tmp1
    141 }
    142 
    143 define i32* @f6() {
    144 ; X32_LINUX: f6:
    145 ; X32_LINUX:      movl %gs:0, %eax
    146 ; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax
    147 ; X32_LINUX-NEXT: ret
    148 ; X64_LINUX: f6:
    149 ; X64_LINUX:      movq %fs:0, %rax
    150 ; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax
    151 ; X64_LINUX-NEXT: ret
    152 ; X32_WIN: f6:
    153 ; X32_WIN:      movl __tls_index, %eax
    154 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    155 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    156 ; X32_WIN-NEXT: leal _i3@SECREL(%eax), %eax
    157 ; X32_WIN-NEXT: ret
    158 ; X64_WIN: f6:
    159 ; X64_WIN:      movl _tls_index(%rip), %eax
    160 ; X64_WIN-NEXT: movq %gs:88, %rcx
    161 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    162 ; X64_WIN-NEXT: leaq i3@SECREL(%rax), %rax
    163 ; X64_WIN-NEXT: ret
    164 
    165 entry:
    166 	ret i32* @i3
    167 }
    168 
    169 define i32 @f7() {
    170 ; X32_LINUX: f7:
    171 ; X32_LINUX:      movl %gs:i4@NTPOFF, %eax
    172 ; X32_LINUX-NEXT: ret
    173 ; X64_LINUX: f7:
    174 ; X64_LINUX:      movl %fs:i4@TPOFF, %eax
    175 ; X64_LINUX-NEXT: ret
    176 
    177 entry:
    178 	%tmp1 = load i32* @i4
    179 	ret i32 %tmp1
    180 }
    181 
    182 define i32* @f8() {
    183 ; X32_LINUX: f8:
    184 ; X32_LINUX:      movl %gs:0, %eax
    185 ; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax
    186 ; X32_LINUX-NEXT: ret
    187 ; X64_LINUX: f8:
    188 ; X64_LINUX:      movq %fs:0, %rax
    189 ; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax
    190 ; X64_LINUX-NEXT: ret
    191 
    192 entry:
    193 	ret i32* @i4
    194 }
    195 
    196 define i32 @f9() {
    197 ; X32_LINUX: f9:
    198 ; X32_LINUX:      movl %gs:i5@NTPOFF, %eax
    199 ; X32_LINUX-NEXT: ret
    200 ; X64_LINUX: f9:
    201 ; X64_LINUX:      movl %fs:i5@TPOFF, %eax
    202 ; X64_LINUX-NEXT: ret
    203 
    204 entry:
    205 	%tmp1 = load i32* @i5
    206 	ret i32 %tmp1
    207 }
    208 
    209 define i32* @f10() {
    210 ; X32_LINUX: f10:
    211 ; X32_LINUX:      movl %gs:0, %eax
    212 ; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax
    213 ; X32_LINUX-NEXT: ret
    214 ; X64_LINUX: f10:
    215 ; X64_LINUX:      movq %fs:0, %rax
    216 ; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax
    217 ; X64_LINUX-NEXT: ret
    218 
    219 entry:
    220 	ret i32* @i5
    221 }
    222 
    223 define i16 @f11() {
    224 ; X32_LINUX: f11:
    225 ; X32_LINUX:      movzwl %gs:s1@NTPOFF, %eax
    226 ; Why is this kill line here, but no where else?
    227 ; X32_LINUX-NEXT: # kill
    228 ; X32_LINUX-NEXT: ret
    229 ; X64_LINUX: f11:
    230 ; X64_LINUX:      movzwl %fs:s1@TPOFF, %eax
    231 ; X64_LINUX-NEXT: # kill
    232 ; X64_LINUX-NEXT: ret
    233 ; X32_WIN: f11:
    234 ; X32_WIN:      movl __tls_index, %eax
    235 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    236 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    237 ; X32_WIN-NEXT: movzwl _s1@SECREL(%eax), %eax
    238 ; X32_WIN-NEXT: # kill
    239 ; X32_WIN-NEXT: ret
    240 ; X64_WIN: f11:
    241 ; X64_WIN:      movl _tls_index(%rip), %eax
    242 ; X64_WIN-NEXT: movq %gs:88, %rcx
    243 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    244 ; X64_WIN-NEXT: movzwl s1@SECREL(%rax), %eax
    245 ; X64_WIN-NEXT: # kill
    246 ; X64_WIN-NEXT: ret
    247 
    248 entry:
    249 	%tmp1 = load i16* @s1
    250 	ret i16 %tmp1
    251 }
    252 
    253 define i32 @f12() {
    254 ; X32_LINUX: f12:
    255 ; X32_LINUX:      movswl %gs:s1@NTPOFF, %eax
    256 ; X32_LINUX-NEXT: ret
    257 ; X64_LINUX: f12:
    258 ; X64_LINUX:      movswl %fs:s1@TPOFF, %eax
    259 ; X64_LINUX-NEXT: ret
    260 ; X32_WIN: f12:
    261 ; X32_WIN:      movl __tls_index, %eax
    262 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    263 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    264 ; X32_WIN-NEXT: movswl _s1@SECREL(%eax), %eax
    265 ; X32_WIN-NEXT: ret
    266 ; X64_WIN: f12:
    267 ; X64_WIN:      movl _tls_index(%rip), %eax
    268 ; X64_WIN-NEXT: movq %gs:88, %rcx
    269 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    270 ; X64_WIN-NEXT: movswl s1@SECREL(%rax), %eax
    271 ; X64_WIN-NEXT: ret
    272 
    273 entry:
    274 	%tmp1 = load i16* @s1
    275   %tmp2 = sext i16 %tmp1 to i32
    276 	ret i32 %tmp2
    277 }
    278 
    279 define i8 @f13() {
    280 ; X32_LINUX: f13:
    281 ; X32_LINUX:      movb %gs:b1@NTPOFF, %al
    282 ; X32_LINUX-NEXT: ret
    283 ; X64_LINUX: f13:
    284 ; X64_LINUX:      movb %fs:b1@TPOFF, %al
    285 ; X64_LINUX-NEXT: ret
    286 ; X32_WIN: f13:
    287 ; X32_WIN:      movl __tls_index, %eax
    288 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    289 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    290 ; X32_WIN-NEXT: movb _b1@SECREL(%eax), %al
    291 ; X32_WIN-NEXT: ret
    292 ; X64_WIN: f13:
    293 ; X64_WIN:      movl _tls_index(%rip), %eax
    294 ; X64_WIN-NEXT: movq %gs:88, %rcx
    295 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    296 ; X64_WIN-NEXT: movb b1@SECREL(%rax), %al
    297 ; X64_WIN-NEXT: ret
    298 
    299 entry:
    300 	%tmp1 = load i8* @b1
    301 	ret i8 %tmp1
    302 }
    303 
    304 define i32 @f14() {
    305 ; X32_LINUX: f14:
    306 ; X32_LINUX:      movsbl %gs:b1@NTPOFF, %eax
    307 ; X32_LINUX-NEXT: ret
    308 ; X64_LINUX: f14:
    309 ; X64_LINUX:      movsbl %fs:b1@TPOFF, %eax
    310 ; X64_LINUX-NEXT: ret
    311 ; X32_WIN: f14:
    312 ; X32_WIN:      movl __tls_index, %eax
    313 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx
    314 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax
    315 ; X32_WIN-NEXT: movsbl _b1@SECREL(%eax), %eax
    316 ; X32_WIN-NEXT: ret
    317 ; X64_WIN: f14:
    318 ; X64_WIN:      movl _tls_index(%rip), %eax
    319 ; X64_WIN-NEXT: movq %gs:88, %rcx
    320 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax
    321 ; X64_WIN-NEXT: movsbl b1@SECREL(%rax), %eax
    322 ; X64_WIN-NEXT: ret
    323 
    324 entry:
    325 	%tmp1 = load i8* @b1
    326   %tmp2 = sext i8 %tmp1 to i32
    327 	ret i32 %tmp2
    328 }
    329 
    330