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