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 16define 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 42entry: 43 %tmp1 = load i32, i32* @i1 44 ret i32 %tmp1 45} 46 47define 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 75entry: 76 ret i32* @i1 77} 78 79define 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 107entry: 108 %tmp1 = load i32, i32* @i2 109 ret i32 %tmp1 110} 111 112define 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 140entry: 141 ret i32* @i2 142} 143 144define 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 170entry: 171 %tmp1 = load i32, i32* @i3 172 ret i32 %tmp1 173} 174 175define 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 203entry: 204 ret i32* @i3 205} 206 207define 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 221entry: 222 %tmp1 = load i32, i32* @i4 223 ret i32 %tmp1 224} 225 226define 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 242entry: 243 ret i32* @i4 244} 245 246define 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 260entry: 261 %tmp1 = load i32, i32* @i5 262 ret i32 %tmp1 263} 264 265define 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 281entry: 282 ret i32* @i5 283} 284 285define 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 311entry: 312 %tmp1 = load i16, i16* @s1 313 ret i16 %tmp1 314} 315 316define 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 343entry: 344 %tmp1 = load i16, i16* @s1 345 %tmp2 = sext i16 %tmp1 to i32 346 ret i32 %tmp2 347} 348 349define 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 375entry: 376 %tmp1 = load i8, i8* @b1 377 ret i8 %tmp1 378} 379 380define 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 406entry: 407 %tmp1 = load i8, i8* @b1 408 %tmp2 = sext i8 %tmp1 to i32 409 ret i32 %tmp2 410} 411 412