1 ; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-gnu -relocation-model=pic -enable-pie \ 2 ; RUN: | FileCheck -check-prefix=X32 %s 3 ; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-gnu -relocation-model=pic -enable-pie \ 4 ; RUN: | FileCheck -check-prefix=X64 %s 5 ; RUN: llc < %s -emulated-tls -march=x86 -mcpu=generic -mtriple=i386-linux-android -relocation-model=pic -enable-pie \ 6 ; RUN: | FileCheck -check-prefix=X32 %s 7 ; RUN: llc < %s -emulated-tls -march=x86-64 -mcpu=generic -mtriple=x86_64-linux-android -relocation-model=pic -enable-pie \ 8 ; RUN: | FileCheck -check-prefix=X64 %s 9 10 ; Use my_emutls_get_address like __emutls_get_address. 11 @my_emutls_v_xyz = external global i8*, align 4 12 declare i8* @my_emutls_get_address(i8*) 13 14 define i32 @my_get_xyz() { 15 ; X32-LABEL: my_get_xyz: 16 ; X32: movl my_emutls_v_xyz@GOT(%ebx), %eax 17 ; X32-NEXT: movl %eax, (%esp) 18 ; X32-NEXT: calll my_emutls_get_address@PLT 19 ; X32-NEXT: movl (%eax), %eax 20 ; X32-NEXT: addl $8, %esp 21 ; X32-NEXT: popl %ebx 22 ; X32-NEXT: retl 23 ; X64-LABEL: my_get_xyz: 24 ; X64: movq my_emutls_v_xyz@GOTPCREL(%rip), %rdi 25 ; X64-NEXT: callq my_emutls_get_address@PLT 26 ; X64-NEXT: movl (%rax), %eax 27 ; X64-NEXT: popq %rcx 28 ; X64-NEXT: retq 29 30 entry: 31 %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) 32 %0 = bitcast i8* %call to i32* 33 %1 = load i32, i32* %0, align 4 34 ret i32 %1 35 } 36 37 @i = thread_local global i32 15 38 @i2 = external thread_local global i32 39 40 define i32 @f1() { 41 ; X32-LABEL: f1: 42 ; X32: movl __emutls_v.i@GOT(%ebx), %eax 43 ; X32-NEXT: movl %eax, (%esp) 44 ; X32-NEXT: calll __emutls_get_address@PLT 45 ; X32-NEXT: movl (%eax), %eax 46 ; X32-NEXT: addl $8, %esp 47 ; X32-NEXT: popl %ebx 48 ; X32-NEXT: retl 49 ; X64-LABEL: f1: 50 ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi 51 ; X64-NEXT: callq __emutls_get_address@PLT 52 ; X64-NEXT: movl (%rax), %eax 53 ; X64-NEXT: popq %rcx 54 ; X64-NEXT: retq 55 56 entry: 57 %tmp1 = load i32, i32* @i 58 ret i32 %tmp1 59 } 60 61 define i32* @f2() { 62 ; X32-LABEL: f2: 63 ; X32: movl __emutls_v.i@GOT(%ebx), %eax 64 ; X32-NEXT: movl %eax, (%esp) 65 ; X32-NEXT: calll __emutls_get_address@PLT 66 ; X64-LABEL: f2: 67 ; X64: movq __emutls_v.i@GOTPCREL(%rip), %rdi 68 ; X64-NEXT: callq __emutls_get_address@PLT 69 70 entry: 71 ret i32* @i 72 } 73 74 define i32 @f3() { 75 ; X32-LABEL: f3: 76 ; X32: movl __emutls_v.i2@GOT(%ebx), %eax 77 ; X32-NEXT: movl %eax, (%esp) 78 ; X32-NEXT: calll __emutls_get_address@PLT 79 ; X64-LABEL: f3: 80 ; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi 81 ; X64-NEXT: callq __emutls_get_address@PLT 82 83 entry: 84 %tmp1 = load i32, i32* @i2 85 ret i32 %tmp1 86 } 87 88 define i32* @f4() { 89 ; X32-LABEL: f4: 90 ; X32: movl __emutls_v.i2@GOT(%ebx), %eax 91 ; X32-NEXT: movl %eax, (%esp) 92 ; X32-NEXT: calll __emutls_get_address@PLT 93 ; X64-LABEL: f4: 94 ; X64: movq __emutls_v.i2@GOTPCREL(%rip), %rdi 95 ; X64-NEXT: callq __emutls_get_address@PLT 96 97 entry: 98 ret i32* @i2 99 } 100 101 ;;;;; 32-bit targets 102 103 ; X32: .data 104 ; X32-LABEL: __emutls_v.i: 105 ; X32-NEXT: .long 4 106 ; X32-NEXT: .long 4 107 ; X32-NEXT: .long 0 108 ; X32-NEXT: .long __emutls_t.i 109 110 ; X32: .section .rodata, 111 ; X32-LABEL: __emutls_t.i: 112 ; X32-NEXT: .long 15 113 114 ; X32-NOT: __emutls_v.i2 115 ; X32-NOT: __emutls_t.i2 116 117 ;;;;; 64-bit targets 118 119 ; X64: .data 120 ; X64-LABEL: __emutls_v.i: 121 ; X64-NEXT: .quad 4 122 ; X64-NEXT: .quad 4 123 ; X64-NEXT: .quad 0 124 ; X64-NEXT: .quad __emutls_t.i 125 126 ; X64: .section .rodata, 127 ; X64-LABEL: __emutls_t.i: 128 ; X64-NEXT: .long 15 129 130 ; X64-NOT: __emutls_v.i2 131 ; X64-NOT: __emutls_t.i2 132