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 6@i1 = thread_local global i32 15 7@i2 = external thread_local global i32 8@i3 = internal thread_local global i32 15 9@i4 = hidden thread_local global i32 15 10@i5 = external hidden thread_local global i32 11@s1 = thread_local global i16 15 12@b1 = thread_local global i8 0 13 14define i32 @f1() { 15; X32_LINUX-LABEL: f1: 16; X32_LINUX: movl %gs:i1@NTPOFF, %eax 17; X32_LINUX-NEXT: ret 18; X64_LINUX-LABEL: f1: 19; X64_LINUX: movl %fs:i1@TPOFF, %eax 20; X64_LINUX-NEXT: ret 21; X32_WIN-LABEL: f1: 22; X32_WIN: movl __tls_index, %eax 23; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 24; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 25; X32_WIN-NEXT: movl _i1@SECREL32(%eax), %eax 26; X32_WIN-NEXT: ret 27; X64_WIN-LABEL: f1: 28; X64_WIN: movl _tls_index(%rip), %eax 29; X64_WIN-NEXT: movq %gs:88, %rcx 30; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 31; X64_WIN-NEXT: movl i1@SECREL32(%rax), %eax 32; X64_WIN-NEXT: ret 33 34entry: 35 %tmp1 = load i32* @i1 36 ret i32 %tmp1 37} 38 39define i32* @f2() { 40; X32_LINUX-LABEL: f2: 41; X32_LINUX: movl %gs:0, %eax 42; X32_LINUX-NEXT: leal i1@NTPOFF(%eax), %eax 43; X32_LINUX-NEXT: ret 44; X64_LINUX-LABEL: f2: 45; X64_LINUX: movq %fs:0, %rax 46; X64_LINUX-NEXT: leaq i1@TPOFF(%rax), %rax 47; X64_LINUX-NEXT: ret 48; X32_WIN-LABEL: f2: 49; X32_WIN: movl __tls_index, %eax 50; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 51; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 52; X32_WIN-NEXT: leal _i1@SECREL32(%eax), %eax 53; X32_WIN-NEXT: ret 54; X64_WIN-LABEL: f2: 55; X64_WIN: movl _tls_index(%rip), %eax 56; X64_WIN-NEXT: movq %gs:88, %rcx 57; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 58; X64_WIN-NEXT: leaq i1@SECREL32(%rax), %rax 59; X64_WIN-NEXT: ret 60 61entry: 62 ret i32* @i1 63} 64 65define i32 @f3() nounwind { 66; X32_LINUX-LABEL: f3: 67; X32_LINUX: movl i2@INDNTPOFF, %eax 68; X32_LINUX-NEXT: movl %gs:(%eax), %eax 69; X32_LINUX-NEXT: ret 70; X64_LINUX-LABEL: f3: 71; X64_LINUX: movq i2@GOTTPOFF(%rip), %rax 72; X64_LINUX-NEXT: movl %fs:(%rax), %eax 73; X64_LINUX-NEXT: ret 74; X32_WIN-LABEL: f3: 75; X32_WIN: movl __tls_index, %eax 76; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 77; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 78; X32_WIN-NEXT: movl _i2@SECREL32(%eax), %eax 79; X32_WIN-NEXT: ret 80; X64_WIN-LABEL: f3: 81; X64_WIN: movl _tls_index(%rip), %eax 82; X64_WIN-NEXT: movq %gs:88, %rcx 83; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 84; X64_WIN-NEXT: movl i2@SECREL32(%rax), %eax 85; X64_WIN-NEXT: ret 86 87entry: 88 %tmp1 = load i32* @i2 89 ret i32 %tmp1 90} 91 92define i32* @f4() { 93; X32_LINUX-LABEL: f4: 94; X32_LINUX: movl %gs:0, %eax 95; X32_LINUX-NEXT: addl i2@INDNTPOFF, %eax 96; X32_LINUX-NEXT: ret 97; X64_LINUX-LABEL: f4: 98; X64_LINUX: movq %fs:0, %rax 99; X64_LINUX-NEXT: addq i2@GOTTPOFF(%rip), %rax 100; X64_LINUX-NEXT: ret 101; X32_WIN-LABEL: f4: 102; X32_WIN: movl __tls_index, %eax 103; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 104; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 105; X32_WIN-NEXT: leal _i2@SECREL32(%eax), %eax 106; X32_WIN-NEXT: ret 107; X64_WIN-LABEL: f4: 108; X64_WIN: movl _tls_index(%rip), %eax 109; X64_WIN-NEXT: movq %gs:88, %rcx 110; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 111; X64_WIN-NEXT: leaq i2@SECREL32(%rax), %rax 112; X64_WIN-NEXT: ret 113 114entry: 115 ret i32* @i2 116} 117 118define i32 @f5() nounwind { 119; X32_LINUX-LABEL: f5: 120; X32_LINUX: movl %gs:i3@NTPOFF, %eax 121; X32_LINUX-NEXT: ret 122; X64_LINUX-LABEL: f5: 123; X64_LINUX: movl %fs:i3@TPOFF, %eax 124; X64_LINUX-NEXT: ret 125; X32_WIN-LABEL: f5: 126; X32_WIN: movl __tls_index, %eax 127; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 128; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 129; X32_WIN-NEXT: movl _i3@SECREL32(%eax), %eax 130; X32_WIN-NEXT: ret 131; X64_WIN-LABEL: f5: 132; X64_WIN: movl _tls_index(%rip), %eax 133; X64_WIN-NEXT: movq %gs:88, %rcx 134; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 135; X64_WIN-NEXT: movl i3@SECREL32(%rax), %eax 136; X64_WIN-NEXT: ret 137 138entry: 139 %tmp1 = load i32* @i3 140 ret i32 %tmp1 141} 142 143define i32* @f6() { 144; X32_LINUX-LABEL: f6: 145; X32_LINUX: movl %gs:0, %eax 146; X32_LINUX-NEXT: leal i3@NTPOFF(%eax), %eax 147; X32_LINUX-NEXT: ret 148; X64_LINUX-LABEL: f6: 149; X64_LINUX: movq %fs:0, %rax 150; X64_LINUX-NEXT: leaq i3@TPOFF(%rax), %rax 151; X64_LINUX-NEXT: ret 152; X32_WIN-LABEL: f6: 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: leal _i3@SECREL32(%eax), %eax 157; X32_WIN-NEXT: ret 158; X64_WIN-LABEL: f6: 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: leaq i3@SECREL32(%rax), %rax 163; X64_WIN-NEXT: ret 164 165entry: 166 ret i32* @i3 167} 168 169define i32 @f7() { 170; X32_LINUX-LABEL: f7: 171; X32_LINUX: movl %gs:i4@NTPOFF, %eax 172; X32_LINUX-NEXT: ret 173; X64_LINUX-LABEL: f7: 174; X64_LINUX: movl %fs:i4@TPOFF, %eax 175; X64_LINUX-NEXT: ret 176 177entry: 178 %tmp1 = load i32* @i4 179 ret i32 %tmp1 180} 181 182define i32* @f8() { 183; X32_LINUX-LABEL: f8: 184; X32_LINUX: movl %gs:0, %eax 185; X32_LINUX-NEXT: leal i4@NTPOFF(%eax), %eax 186; X32_LINUX-NEXT: ret 187; X64_LINUX-LABEL: f8: 188; X64_LINUX: movq %fs:0, %rax 189; X64_LINUX-NEXT: leaq i4@TPOFF(%rax), %rax 190; X64_LINUX-NEXT: ret 191 192entry: 193 ret i32* @i4 194} 195 196define i32 @f9() { 197; X32_LINUX-LABEL: f9: 198; X32_LINUX: movl %gs:i5@NTPOFF, %eax 199; X32_LINUX-NEXT: ret 200; X64_LINUX-LABEL: f9: 201; X64_LINUX: movl %fs:i5@TPOFF, %eax 202; X64_LINUX-NEXT: ret 203 204entry: 205 %tmp1 = load i32* @i5 206 ret i32 %tmp1 207} 208 209define i32* @f10() { 210; X32_LINUX-LABEL: f10: 211; X32_LINUX: movl %gs:0, %eax 212; X32_LINUX-NEXT: leal i5@NTPOFF(%eax), %eax 213; X32_LINUX-NEXT: ret 214; X64_LINUX-LABEL: f10: 215; X64_LINUX: movq %fs:0, %rax 216; X64_LINUX-NEXT: leaq i5@TPOFF(%rax), %rax 217; X64_LINUX-NEXT: ret 218 219entry: 220 ret i32* @i5 221} 222 223define i16 @f11() { 224; X32_LINUX-LABEL: f11: 225; X32_LINUX: movzwl %gs:s1@NTPOFF, %eax 226; X32_LINUX: ret 227; X64_LINUX-LABEL: f11: 228; X64_LINUX: movzwl %fs:s1@TPOFF, %eax 229; X64_LINUX: ret 230; X32_WIN-LABEL: f11: 231; X32_WIN: movl __tls_index, %eax 232; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 233; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 234; X32_WIN-NEXT: movzwl _s1@SECREL32(%eax), %eax 235; X32_WIN: ret 236; X64_WIN-LABEL: f11: 237; X64_WIN: movl _tls_index(%rip), %eax 238; X64_WIN-NEXT: movq %gs:88, %rcx 239; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 240; X64_WIN-NEXT: movzwl s1@SECREL32(%rax), %eax 241; X64_WIN: ret 242 243entry: 244 %tmp1 = load i16* @s1 245 ret i16 %tmp1 246} 247 248define i32 @f12() { 249; X32_LINUX-LABEL: f12: 250; X32_LINUX: movswl %gs:s1@NTPOFF, %eax 251; X32_LINUX-NEXT: ret 252; X64_LINUX-LABEL: f12: 253; X64_LINUX: movswl %fs:s1@TPOFF, %eax 254; X64_LINUX-NEXT: ret 255; X32_WIN-LABEL: f12: 256; X32_WIN: movl __tls_index, %eax 257; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 258; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 259; X32_WIN-NEXT: movswl _s1@SECREL32(%eax), %eax 260; X32_WIN-NEXT: ret 261; X64_WIN-LABEL: f12: 262; X64_WIN: movl _tls_index(%rip), %eax 263; X64_WIN-NEXT: movq %gs:88, %rcx 264; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 265; X64_WIN-NEXT: movswl s1@SECREL32(%rax), %eax 266; X64_WIN-NEXT: ret 267 268entry: 269 %tmp1 = load i16* @s1 270 %tmp2 = sext i16 %tmp1 to i32 271 ret i32 %tmp2 272} 273 274define i8 @f13() { 275; X32_LINUX-LABEL: f13: 276; X32_LINUX: movb %gs:b1@NTPOFF, %al 277; X32_LINUX-NEXT: ret 278; X64_LINUX-LABEL: f13: 279; X64_LINUX: movb %fs:b1@TPOFF, %al 280; X64_LINUX-NEXT: ret 281; X32_WIN-LABEL: f13: 282; X32_WIN: movl __tls_index, %eax 283; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 284; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 285; X32_WIN-NEXT: movb _b1@SECREL32(%eax), %al 286; X32_WIN-NEXT: ret 287; X64_WIN-LABEL: f13: 288; X64_WIN: movl _tls_index(%rip), %eax 289; X64_WIN-NEXT: movq %gs:88, %rcx 290; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 291; X64_WIN-NEXT: movb b1@SECREL32(%rax), %al 292; X64_WIN-NEXT: ret 293 294entry: 295 %tmp1 = load i8* @b1 296 ret i8 %tmp1 297} 298 299define i32 @f14() { 300; X32_LINUX-LABEL: f14: 301; X32_LINUX: movsbl %gs:b1@NTPOFF, %eax 302; X32_LINUX-NEXT: ret 303; X64_LINUX-LABEL: f14: 304; X64_LINUX: movsbl %fs:b1@TPOFF, %eax 305; X64_LINUX-NEXT: ret 306; X32_WIN-LABEL: f14: 307; X32_WIN: movl __tls_index, %eax 308; X32_WIN-NEXT: movl %fs:__tls_array, %ecx 309; X32_WIN-NEXT: movl (%ecx,%eax,4), %eax 310; X32_WIN-NEXT: movsbl _b1@SECREL32(%eax), %eax 311; X32_WIN-NEXT: ret 312; X64_WIN-LABEL: f14: 313; X64_WIN: movl _tls_index(%rip), %eax 314; X64_WIN-NEXT: movq %gs:88, %rcx 315; X64_WIN-NEXT: movq (%rcx,%rax,8), %rax 316; X64_WIN-NEXT: movsbl b1@SECREL32(%rax), %eax 317; X64_WIN-NEXT: ret 318 319entry: 320 %tmp1 = load i8* @b1 321 %tmp2 = sext i8 %tmp1 to i32 322 ret i32 %tmp2 323} 324 325