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 18define 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 44entry: 45 %tmp1 = load i32, i32* @i1 46 ret i32 %tmp1 47} 48 49define 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 77entry: 78 ret i32* @i1 79} 80 81define 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 109entry: 110 %tmp1 = load i32, i32* @i2 111 ret i32 %tmp1 112} 113 114define 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 142entry: 143 ret i32* @i2 144} 145 146define 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 172entry: 173 %tmp1 = load i32, i32* @i3 174 ret i32 %tmp1 175} 176 177define 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 205entry: 206 ret i32* @i3 207} 208 209define 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 223entry: 224 %tmp1 = load i32, i32* @i4 225 ret i32 %tmp1 226} 227 228define 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 244entry: 245 ret i32* @i4 246} 247 248define 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 262entry: 263 %tmp1 = load i32, i32* @i5 264 ret i32 %tmp1 265} 266 267define 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 283entry: 284 ret i32* @i5 285} 286 287define 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 313entry: 314 %tmp1 = load i16, i16* @s1 315 ret i16 %tmp1 316} 317 318define 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 345entry: 346 %tmp1 = load i16, i16* @s1 347 %tmp2 = sext i16 %tmp1 to i32 348 ret i32 %tmp2 349} 350 351define 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 377entry: 378 %tmp1 = load i8, i8* @b1 379 ret i8 %tmp1 380} 381 382define 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 408entry: 409 %tmp1 = load i8, i8* @b1 410 %tmp2 = sext i8 %tmp1 to i32 411 ret i32 %tmp2 412} 413 414define 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 438entry: 439 ret i8* @b2 440} 441 442 443define 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