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