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 ; RUN: llc < %s -march=x86 -mtriple=x86-pc-windows-gnu | FileCheck -check-prefix=MINGW32 %s 6 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-pc-windows-gnu | FileCheck -check-prefix=X64_WIN %s 7 8 @i1 = thread_local global i32 15 9 @i2 = external thread_local global i32 10 @i3 = internal thread_local global i32 15 11 @i4 = hidden thread_local global i32 15 12 @i5 = external hidden thread_local global i32 13 @s1 = thread_local global i16 15 14 @b1 = thread_local global i8 0 15 @b2 = thread_local(localexec) global i8 0 16 17 define i32 @f1() { 18 ; X32_LINUX-LABEL: f1: 19 ; X32_LINUX: movl %gs:i1@NTPOFF, %eax 20 ; X32_LINUX-NEXT: ret 21 ; X64_LINUX-LABEL: f1: 22 ; X64_LINUX: movl %fs:i1@TPOFF, %eax 23 ; X64_LINUX-NEXT: ret 24 ; X32_WIN-LABEL: f1: 25 ; X32_WIN: movl __tls_index, %eax 26 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 27 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 28 ; X32_WIN-NEXT: movl _i1@SECREL32(%eax), %eax 29 ; X32_WIN-NEXT: ret 30 ; X64_WIN-LABEL: f1: 31 ; X64_WIN: movl _tls_index(%rip), %eax 32 ; X64_WIN-NEXT: movq %gs:88, %rcx 33 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 34 ; X64_WIN-NEXT: movl i1@SECREL32(%rax), %eax 35 ; X64_WIN-NEXT: ret 36 ; MINGW32-LABEL: _f1: 37 ; MINGW32: movl __tls_index, %eax 38 ; MINGW32-NEXT: movl %fs:44, %ecx 39 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 40 ; MINGW32-NEXT: movl _i1@SECREL32(%eax), %eax 41 ; MINGW32-NEXT: retl 42 43 entry: 44 %tmp1 = load i32, i32* @i1 45 ret i32 %tmp1 46 } 47 48 define i32* @f2() { 49 ; X32_LINUX-LABEL: f2: 50 ; X32_LINUX: movl %gs:0, %eax 51 ; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax 52 ; X32_LINUX-NEXT: ret 53 ; X64_LINUX-LABEL: f2: 54 ; X64_LINUX: movq %fs:0, %rax 55 ; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax 56 ; X64_LINUX-NEXT: ret 57 ; X32_WIN-LABEL: f2: 58 ; X32_WIN: movl __tls_index, %eax 59 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 60 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 61 ; X32_WIN-NEXT: leal _i1@SECREL32(%eax), %eax 62 ; X32_WIN-NEXT: ret 63 ; X64_WIN-LABEL: f2: 64 ; X64_WIN: movl _tls_index(%rip), %eax 65 ; X64_WIN-NEXT: movq %gs:88, %rcx 66 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 67 ; X64_WIN-NEXT: leaq i1@SECREL32(%rax), %rax 68 ; X64_WIN-NEXT: ret 69 ; MINGW32-LABEL: _f2: 70 ; MINGW32: movl __tls_index, %eax 71 ; MINGW32-NEXT: movl %fs:44, %ecx 72 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 73 ; MINGW32-NEXT: leal _i1@SECREL32(%eax), %eax 74 ; MINGW32-NEXT: retl 75 76 entry: 77 ret i32* @i1 78 } 79 80 define i32 @f3() nounwind { 81 ; X32_LINUX-LABEL: f3: 82 ; X32_LINUX: movl i2@INDNTPOFF, %eax 83 ; X32_LINUX-NEXT: movl %gs:(%eax), %eax 84 ; X32_LINUX-NEXT: ret 85 ; X64_LINUX-LABEL: f3: 86 ; X64_LINUX: movq i2@GOTTPOFF(%rip), %rax 87 ; X64_LINUX-NEXT: movl %fs:(%rax), %eax 88 ; X64_LINUX-NEXT: ret 89 ; X32_WIN-LABEL: f3: 90 ; X32_WIN: movl __tls_index, %eax 91 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 92 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 93 ; X32_WIN-NEXT: movl _i2@SECREL32(%eax), %eax 94 ; X32_WIN-NEXT: ret 95 ; X64_WIN-LABEL: f3: 96 ; X64_WIN: movl _tls_index(%rip), %eax 97 ; X64_WIN-NEXT: movq %gs:88, %rcx 98 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 99 ; X64_WIN-NEXT: movl i2@SECREL32(%rax), %eax 100 ; X64_WIN-NEXT: ret 101 ; MINGW32-LABEL: _f3: 102 ; MINGW32: movl __tls_index, %eax 103 ; MINGW32-NEXT: movl %fs:44, %ecx 104 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 105 ; MINGW32-NEXT: movl _i2@SECREL32(%eax), %eax 106 ; MINGW32-NEXT: retl 107 108 entry: 109 %tmp1 = load i32, i32* @i2 110 ret i32 %tmp1 111 } 112 113 define i32* @f4() { 114 ; X32_LINUX-LABEL: f4: 115 ; X32_LINUX: movl %gs:0, %eax 116 ; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax 117 ; X32_LINUX-NEXT: ret 118 ; X64_LINUX-LABEL: f4: 119 ; X64_LINUX: movq %fs:0, %rax 120 ; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax 121 ; X64_LINUX-NEXT: ret 122 ; X32_WIN-LABEL: f4: 123 ; X32_WIN: movl __tls_index, %eax 124 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 125 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 126 ; X32_WIN-NEXT: leal _i2@SECREL32(%eax), %eax 127 ; X32_WIN-NEXT: ret 128 ; X64_WIN-LABEL: f4: 129 ; X64_WIN: movl _tls_index(%rip), %eax 130 ; X64_WIN-NEXT: movq %gs:88, %rcx 131 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 132 ; X64_WIN-NEXT: leaq i2@SECREL32(%rax), %rax 133 ; X64_WIN-NEXT: ret 134 ; MINGW32-LABEL: _f4: 135 ; MINGW32: movl __tls_index, %eax 136 ; MINGW32-NEXT: movl %fs:44, %ecx 137 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 138 ; MINGW32-NEXT: leal _i2@SECREL32(%eax), %eax 139 ; MINGW32-NEXT: retl 140 141 entry: 142 ret i32* @i2 143 } 144 145 define i32 @f5() nounwind { 146 ; X32_LINUX-LABEL: f5: 147 ; X32_LINUX: movl %gs:i3@NTPOFF, %eax 148 ; X32_LINUX-NEXT: ret 149 ; X64_LINUX-LABEL: f5: 150 ; X64_LINUX: movl %fs:i3@TPOFF, %eax 151 ; X64_LINUX-NEXT: ret 152 ; X32_WIN-LABEL: f5: 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: movl _i3@SECREL32(%eax), %eax 157 ; X32_WIN-NEXT: ret 158 ; X64_WIN-LABEL: f5: 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: movl i3@SECREL32(%rax), %eax 163 ; X64_WIN-NEXT: ret 164 ; MINGW32-LABEL: _f5: 165 ; MINGW32: movl __tls_index, %eax 166 ; MINGW32-NEXT: movl %fs:44, %ecx 167 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 168 ; MINGW32-NEXT: movl _i3@SECREL32(%eax), %eax 169 ; MINGW32-NEXT: retl 170 171 entry: 172 %tmp1 = load i32, i32* @i3 173 ret i32 %tmp1 174 } 175 176 define i32* @f6() { 177 ; X32_LINUX-LABEL: f6: 178 ; X32_LINUX: movl %gs:0, %eax 179 ; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax 180 ; X32_LINUX-NEXT: ret 181 ; X64_LINUX-LABEL: f6: 182 ; X64_LINUX: movq %fs:0, %rax 183 ; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax 184 ; X64_LINUX-NEXT: ret 185 ; X32_WIN-LABEL: f6: 186 ; X32_WIN: movl __tls_index, %eax 187 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 188 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 189 ; X32_WIN-NEXT: leal _i3@SECREL32(%eax), %eax 190 ; X32_WIN-NEXT: ret 191 ; X64_WIN-LABEL: f6: 192 ; X64_WIN: movl _tls_index(%rip), %eax 193 ; X64_WIN-NEXT: movq %gs:88, %rcx 194 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 195 ; X64_WIN-NEXT: leaq i3@SECREL32(%rax), %rax 196 ; X64_WIN-NEXT: ret 197 ; MINGW32-LABEL: _f6: 198 ; MINGW32: movl __tls_index, %eax 199 ; MINGW32-NEXT: movl %fs:44, %ecx 200 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 201 ; MINGW32-NEXT: leal _i3@SECREL32(%eax), %eax 202 ; MINGW32-NEXT: retl 203 204 entry: 205 ret i32* @i3 206 } 207 208 define i32 @f7() { 209 ; X32_LINUX-LABEL: f7: 210 ; X32_LINUX: movl %gs:i4@NTPOFF, %eax 211 ; X32_LINUX-NEXT: ret 212 ; X64_LINUX-LABEL: f7: 213 ; X64_LINUX: movl %fs:i4@TPOFF, %eax 214 ; X64_LINUX-NEXT: ret 215 ; MINGW32-LABEL: _f7: 216 ; MINGW32: movl __tls_index, %eax 217 ; MINGW32-NEXT: movl %fs:44, %ecx 218 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 219 ; MINGW32-NEXT: movl _i4@SECREL32(%eax), %eax 220 ; MINGW32-NEXT: retl 221 222 entry: 223 %tmp1 = load i32, i32* @i4 224 ret i32 %tmp1 225 } 226 227 define i32* @f8() { 228 ; X32_LINUX-LABEL: f8: 229 ; X32_LINUX: movl %gs:0, %eax 230 ; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax 231 ; X32_LINUX-NEXT: ret 232 ; X64_LINUX-LABEL: f8: 233 ; X64_LINUX: movq %fs:0, %rax 234 ; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax 235 ; X64_LINUX-NEXT: ret 236 ; MINGW32-LABEL: _f8: 237 ; MINGW32: movl __tls_index, %eax 238 ; MINGW32-NEXT: movl %fs:44, %ecx 239 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 240 ; MINGW32-NEXT: leal _i4@SECREL32(%eax), %eax 241 ; MINGW32-NEXT: retl 242 243 entry: 244 ret i32* @i4 245 } 246 247 define i32 @f9() { 248 ; X32_LINUX-LABEL: f9: 249 ; X32_LINUX: movl %gs:i5@NTPOFF, %eax 250 ; X32_LINUX-NEXT: ret 251 ; X64_LINUX-LABEL: f9: 252 ; X64_LINUX: movl %fs:i5@TPOFF, %eax 253 ; X64_LINUX-NEXT: ret 254 ; MINGW32-LABEL: _f9: 255 ; MINGW32: movl __tls_index, %eax 256 ; MINGW32-NEXT: movl %fs:44, %ecx 257 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 258 ; MINGW32-NEXT: movl _i5@SECREL32(%eax), %eax 259 ; MINGW32-NEXT: retl 260 261 entry: 262 %tmp1 = load i32, i32* @i5 263 ret i32 %tmp1 264 } 265 266 define i32* @f10() { 267 ; X32_LINUX-LABEL: f10: 268 ; X32_LINUX: movl %gs:0, %eax 269 ; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax 270 ; X32_LINUX-NEXT: ret 271 ; X64_LINUX-LABEL: f10: 272 ; X64_LINUX: movq %fs:0, %rax 273 ; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax 274 ; X64_LINUX-NEXT: ret 275 ; MINGW32-LABEL: _f10: 276 ; MINGW32: movl __tls_index, %eax 277 ; MINGW32-NEXT: movl %fs:44, %ecx 278 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 279 ; MINGW32-NEXT: leal _i5@SECREL32(%eax), %eax 280 ; MINGW32-NEXT: retl 281 282 entry: 283 ret i32* @i5 284 } 285 286 define i16 @f11() { 287 ; X32_LINUX-LABEL: f11: 288 ; X32_LINUX: movzwl %gs:s1@NTPOFF, %eax 289 ; X32_LINUX: ret 290 ; X64_LINUX-LABEL: f11: 291 ; X64_LINUX: movzwl %fs:s1@TPOFF, %eax 292 ; X64_LINUX: ret 293 ; X32_WIN-LABEL: f11: 294 ; X32_WIN: movl __tls_index, %eax 295 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 296 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 297 ; X32_WIN-NEXT: movzwl _s1@SECREL32(%eax), %eax 298 ; X32_WIN: ret 299 ; X64_WIN-LABEL: f11: 300 ; X64_WIN: movl _tls_index(%rip), %eax 301 ; X64_WIN-NEXT: movq %gs:88, %rcx 302 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 303 ; X64_WIN-NEXT: movzwl s1@SECREL32(%rax), %eax 304 ; X64_WIN: ret 305 ; MINGW32-LABEL: _f11: 306 ; MINGW32: movl __tls_index, %eax 307 ; MINGW32-NEXT: movl %fs:44, %ecx 308 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 309 ; MINGW32-NEXT: movzwl _s1@SECREL32(%eax), %eax 310 ; MINGW32: retl 311 312 entry: 313 %tmp1 = load i16, i16* @s1 314 ret i16 %tmp1 315 } 316 317 define i32 @f12() { 318 ; X32_LINUX-LABEL: f12: 319 ; X32_LINUX: movswl %gs:s1@NTPOFF, %eax 320 ; X32_LINUX-NEXT: ret 321 ; X64_LINUX-LABEL: f12: 322 ; X64_LINUX: movswl %fs:s1@TPOFF, %eax 323 ; X64_LINUX-NEXT: ret 324 ; X32_WIN-LABEL: f12: 325 ; X32_WIN: movl __tls_index, %eax 326 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 327 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 328 ; X32_WIN-NEXT: movswl _s1@SECREL32(%eax), %eax 329 ; X32_WIN-NEXT: ret 330 ; X64_WIN-LABEL: f12: 331 ; X64_WIN: movl _tls_index(%rip), %eax 332 ; X64_WIN-NEXT: movq %gs:88, %rcx 333 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 334 ; X64_WIN-NEXT: movswl s1@SECREL32(%rax), %eax 335 ; X64_WIN-NEXT: ret 336 ; MINGW32-LABEL: _f12: 337 ; MINGW32: movl __tls_index, %eax 338 ; MINGW32-NEXT: movl %fs:44, %ecx 339 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 340 ; MINGW32-NEXT: movswl _s1@SECREL32(%eax), %eax 341 ; MINGW32-NEXT: retl 342 343 344 entry: 345 %tmp1 = load i16, i16* @s1 346 %tmp2 = sext i16 %tmp1 to i32 347 ret i32 %tmp2 348 } 349 350 define i8 @f13() { 351 ; X32_LINUX-LABEL: f13: 352 ; X32_LINUX: movb %gs:b1@NTPOFF, %al 353 ; X32_LINUX-NEXT: ret 354 ; X64_LINUX-LABEL: f13: 355 ; X64_LINUX: movb %fs:b1@TPOFF, %al 356 ; X64_LINUX-NEXT: ret 357 ; X32_WIN-LABEL: f13: 358 ; X32_WIN: movl __tls_index, %eax 359 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 360 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 361 ; X32_WIN-NEXT: movb _b1@SECREL32(%eax), %al 362 ; X32_WIN-NEXT: ret 363 ; X64_WIN-LABEL: f13: 364 ; X64_WIN: movl _tls_index(%rip), %eax 365 ; X64_WIN-NEXT: movq %gs:88, %rcx 366 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 367 ; X64_WIN-NEXT: movb b1@SECREL32(%rax), %al 368 ; X64_WIN-NEXT: ret 369 ; MINGW32-LABEL: _f13: 370 ; MINGW32: movl __tls_index, %eax 371 ; MINGW32-NEXT: movl %fs:44, %ecx 372 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 373 ; MINGW32-NEXT: movb _b1@SECREL32(%eax), %al 374 ; MINGW32-NEXT: retl 375 376 entry: 377 %tmp1 = load i8, i8* @b1 378 ret i8 %tmp1 379 } 380 381 define i32 @f14() { 382 ; X32_LINUX-LABEL: f14: 383 ; X32_LINUX: movsbl %gs:b1@NTPOFF, %eax 384 ; X32_LINUX-NEXT: ret 385 ; X64_LINUX-LABEL: f14: 386 ; X64_LINUX: movsbl %fs:b1@TPOFF, %eax 387 ; X64_LINUX-NEXT: ret 388 ; X32_WIN-LABEL: f14: 389 ; X32_WIN: movl __tls_index, %eax 390 ; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 391 ; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 392 ; X32_WIN-NEXT: movsbl _b1@SECREL32(%eax), %eax 393 ; X32_WIN-NEXT: ret 394 ; X64_WIN-LABEL: f14: 395 ; X64_WIN: movl _tls_index(%rip), %eax 396 ; X64_WIN-NEXT: movq %gs:88, %rcx 397 ; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 398 ; X64_WIN-NEXT: movsbl b1@SECREL32(%rax), %eax 399 ; X64_WIN-NEXT: ret 400 ; MINGW32-LABEL: _f14: 401 ; MINGW32: movl __tls_index, %eax 402 ; MINGW32-NEXT: movl %fs:44, %ecx 403 ; MINGW32-NEXT: movl (%ecx,%eax,4), %eax 404 ; MINGW32-NEXT: movsbl _b1@SECREL32(%eax), %eax 405 ; MINGW32-NEXT: retl 406 407 entry: 408 %tmp1 = load i8, i8* @b1 409 %tmp2 = sext i8 %tmp1 to i32 410 ret i32 %tmp2 411 } 412 413 define i8* @f15() { 414 ; X32_LINUX-LABEL: f15: 415 ; X32_LINUX: movl %gs:0, %eax 416 ; X32_LINUX-NEXT: leal b2@NTPOFF(%eax), %eax 417 ; X32_LINUX-NEXT: ret 418 ; X64_LINUX-LABEL: f15: 419 ; X64_LINUX: movq %fs:0, %rax 420 ; X64_LINUX-NEXT: leaq b2@TPOFF(%rax), %rax 421 ; X64_LINUX-NEXT: ret 422 ; X32_WIN-LABEL: f15: 423 ; X32_WIN: movl %fs:__tls_array, %eax 424 ; X32_WIN-NEXT: movl (%eax), %eax 425 ; X32_WIN-NEXT: leal _b2@SECREL32(%eax), %eax 426 ; X32_WIN-NEXT: ret 427 ; X64_WIN-LABEL: f15: 428 ; X64_WIN: movq %gs:88, %rax 429 ; X64_WIN-NEXT: movq (%rax), %rax 430 ; X64_WIN-NEXT: leaq b2@SECREL32(%rax), %rax 431 ; X64_WIN-NEXT: ret 432 ; MINGW32-LABEL: f15: 433 ; MINGW32: movl %fs:44, %eax 434 ; MINGW32-NEXT: movl (%eax), %eax 435 ; MINGW32-NEXT: leal _b2@SECREL32(%eax), %eax 436 ; MINGW32-NEXT: ret 437 entry: 438 ret i8* @b2 439 } 440 441