1; RUN: llc < %s -emulated-tls -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X86 %s 2; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=X64 %s 3; RUN: llc < %s -emulated-tls -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s 4; RUN: llc < %s -emulated-tls -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s 5 6; RUN: llc < %s -mtriple=i386-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s 7; RUN: llc < %s -mtriple=x86_64-linux-gnu -relocation-model=pic | FileCheck -check-prefix=NoEMU %s 8; RUN: llc < %s -mtriple=i386-linux-android -relocation-model=pic | FileCheck -check-prefix=X86 %s 9; RUN: llc < %s -mtriple=x86_64-linux-android -relocation-model=pic | FileCheck -check-prefix=X64 %s 10 11; NoEMU-NOT: __emutls 12 13; Use my_emutls_get_address like __emutls_get_address. 14@my_emutls_v_xyz = external global i8*, align 4 15declare i8* @my_emutls_get_address(i8*) 16 17define i32 @my_get_xyz() { 18; X86-LABEL: my_get_xyz: 19; X86: movl my_emutls_v_xyz@GOT(%ebx), %eax 20; X86-NEXT: movl %eax, (%esp) 21; X86-NEXT: calll my_emutls_get_address@PLT 22; X64-LABEL: my_get_xyz: 23; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi 24; X64-NEXT: callq my_emutls_get_address@PLT 25; X64-NEXT: movl (%rax), %eax 26 27entry: 28 %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) 29 %0 = bitcast i8* %call to i32* 30 %1 = load i32, i32* %0, align 4 31 ret i32 %1 32} 33 34@i = thread_local global i32 15 35@j = internal thread_local global i32 42 36@k = internal thread_local global i32 0, align 8 37 38define i32 @f1() { 39entry: 40 %tmp1 = load i32, i32* @i 41 ret i32 %tmp1 42} 43 44; X86-LABEL: f1: 45; X86: movl __emutls_v.i@GOT(%ebx), %eax 46; X86-NEXT: movl %eax, (%esp) 47; X86-NEXT: calll __emutls_get_address@PLT 48; X64-LABEL: f1: 49; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi 50; X64-NEXT: callq __emutls_get_address@PLT 51; X64-NEXT: movl (%rax), %eax 52 53@i2 = external thread_local global i32 54 55define i32* @f2() { 56entry: 57 ret i32* @i 58} 59 60; X86-LABEL: f2: 61; X64-LABEL: f2: 62 63 64define i32 @f3() { 65entry: 66 %tmp1 = load i32, i32* @i ; <i32> [#uses=1] 67 ret i32 %tmp1 68} 69 70; X86-LABEL: f3: 71; X64-LABEL: f3: 72 73 74define i32* @f4() nounwind { 75entry: 76 ret i32* @i 77} 78 79; X86-LABEL: f4: 80; X64-LABEL: f4: 81 82 83define i32 @f5() nounwind { 84entry: 85 %0 = load i32, i32* @j, align 4 86 %1 = load i32, i32* @k, align 4 87 %add = add nsw i32 %0, %1 88 ret i32 %add 89} 90 91; X86-LABEL: f5: 92; X86: leal __emutls_v.j@GOTOFF(%ebx), %eax 93; X86-NEXT: movl %eax, (%esp) 94; X86-NEXT: calll __emutls_get_address@PLT 95; X86-NEXT: movl (%eax), %esi 96; X86-NEXT: leal __emutls_v.k@GOTOFF(%ebx), %eax 97; X86-NEXT: movl %eax, (%esp) 98; X86-NEXT: calll __emutls_get_address@PLT 99; X86-NEXT: addl (%eax), %esi 100; X86-NEXT: movl %esi, %eax 101 102; X64-LABEL: f5: 103; X64: leaq __emutls_v.j(%rip), %rdi 104; X64-NEXT: callq __emutls_get_address@PLT 105; X64-NEXT: movl (%rax), %ebx 106; X64-NEXT: leaq __emutls_v.k(%rip), %rdi 107; X64-NEXT: callq __emutls_get_address@PLT 108; X64-NEXT: addl (%rax), %ebx 109; X64-NEXT: movl %ebx, %eax 110 111;;;;; 32-bit targets 112 113; X86: .data{{$}} 114; X86: .globl __emutls_v.i 115; X86-LABEL: __emutls_v.i: 116; X86-NEXT: .long 4 117; X86-NEXT: .long 4 118; X86-NEXT: .long 0 119; X86-NEXT: .long __emutls_t.i 120 121; X86: .section .rodata, 122; X86-LABEL: __emutls_t.i: 123; X86-NEXT: .long 15 124 125; X86: .data{{$}} 126; X86-NOT: .globl 127; X86-LABEL: __emutls_v.j: 128; X86-NEXT: .long 4 129; X86-NEXT: .long 4 130; X86-NEXT: .long 0 131; X86-NEXT: .long __emutls_t.j 132 133; X86: .section .rodata, 134; X86-LABEL: __emutls_t.j: 135; X86-NEXT: .long 42 136 137; X86: .data{{$}} 138; X86-NOT: .globl 139; X86-LABEL: __emutls_v.k: 140; X86-NEXT: .long 4 141; X86-NEXT: .long 8 142; X86-NEXT: .long 0 143; X86-NEXT: .long 0 144 145; X86-NOT: __emutls_t.k: 146 147;;;;; 64-bit targets 148 149; X64: .data{{$}} 150; X64: .globl __emutls_v.i 151; X64-LABEL: __emutls_v.i: 152; X64-NEXT: .quad 4 153; X64-NEXT: .quad 4 154; X64-NEXT: .quad 0 155; X64-NEXT: .quad __emutls_t.i 156 157; X64: .section .rodata, 158; X64-LABEL: __emutls_t.i: 159; X64-NEXT: .long 15 160 161; X64: .data{{$}} 162; X64-NOT: .globl 163; X64-LABEL: __emutls_v.j: 164; X64-NEXT: .quad 4 165; X64-NEXT: .quad 4 166; X64-NEXT: .quad 0 167; X64-NEXT: .quad __emutls_t.j 168 169; X64: .section .rodata, 170; X64-LABEL: __emutls_t.j: 171; X64-NEXT: .long 42 172 173; X64: .data{{$}} 174; X64-NOT: .globl 175; X64-LABEL: __emutls_v.k: 176; X64-NEXT: .quad 4 177; X64-NEXT: .quad 8 178; X64-NEXT: .quad 0 179; X64-NEXT: .quad 0 180 181; X64-NOT: __emutls_t.k: 182