1; RUN: llc -emulated-tls -mtriple=arm-linux-android \ 2; RUN: -relocation-model=pic < %s | FileCheck -check-prefix=ARM32 %s 3 4; Copied from X86/emutls.ll 5 6; Use my_emutls_get_address like __emutls_get_address. 7@my_emutls_v_xyz = external global i8*, align 4 8declare i8* @my_emutls_get_address(i8*) 9 10define i32 @my_get_xyz() { 11; ARM32-LABEL: my_get_xyz: 12; ARM32: ldr r0, 13; ARM32: ldr r0, [pc, r0] 14; ARM32-NEXT: bl my_emutls_get_address(PLT) 15; ARM32-NEXT: ldr r0, [r0] 16 17entry: 18 %call = call i8* @my_emutls_get_address(i8* bitcast (i8** @my_emutls_v_xyz to i8*)) 19 %0 = bitcast i8* %call to i32* 20 %1 = load i32, i32* %0, align 4 21 ret i32 %1 22} 23 24@i1 = thread_local global i32 15 25@i2 = external thread_local global i32 26@i3 = internal thread_local global i32 15 27@i4 = hidden thread_local global i32 15 28@i5 = external hidden thread_local global i32 29@s1 = thread_local global i16 15 30@b1 = thread_local global i8 0 31 32define i32 @f1() { 33; ARM32-LABEL: f1: 34; ARM32: ldr r0, 35; ARM32: ldr r0, [pc, r0] 36; ARM32-NEXT: bl __emutls_get_address(PLT) 37; ARM32-NEXT: ldr r0, [r0] 38 39entry: 40 %tmp1 = load i32, i32* @i1 41 ret i32 %tmp1 42} 43 44define i32* @f2() { 45; ARM32-LABEL: f2: 46; ARM32: ldr r0, 47; ARM32: ldr r0, [pc, r0] 48; ARM32-NEXT: bl __emutls_get_address(PLT) 49; ARM32-NEXT: pop 50 51entry: 52 ret i32* @i1 53} 54 55define i32 @f3() nounwind { 56; ARM32-LABEL: f3: 57; ARM32: ldr r0, 58; ARM32: ldr r0, [pc, r0] 59; ARM32-NEXT: bl __emutls_get_address(PLT) 60; ARM32-NEXT: ldr r0, [r0] 61 62entry: 63 %tmp1 = load i32, i32* @i2 64 ret i32 %tmp1 65} 66 67define i32* @f4() { 68; ARM32-LABEL: f4: 69; ARM32: ldr r0, 70; ARM32: ldr r0, [pc, r0] 71; ARM32-NEXT: bl __emutls_get_address(PLT) 72; ARM32-NEXT: pop 73 74entry: 75 ret i32* @i2 76} 77 78define i32 @f5() nounwind { 79; ARM32-LABEL: f5: 80; ARM32: ldr r0, 81; ARM32: ldr r0, [pc, r0] 82; ARM32-NEXT: bl __emutls_get_address(PLT) 83; ARM32-NEXT: ldr r0, [r0] 84 85entry: 86 %tmp1 = load i32, i32* @i3 87 ret i32 %tmp1 88} 89 90define i32* @f6() { 91; ARM32-LABEL: f6: 92; ARM32: ldr r0, 93; ARM32: ldr r0, [pc, r0] 94; ARM32-NEXT: bl __emutls_get_address(PLT) 95; ARM32-NEXT: pop 96 97entry: 98 ret i32* @i3 99} 100 101define i32 @f7() { 102; ARM32-LABEL: f7: 103; ARM32: ldr r0, 104; ARM32: ldr r0, [pc, r0] 105; ARM32-NEXT: bl __emutls_get_address(PLT) 106; ARM32-NEXT: ldr r0, [r0] 107 108entry: 109 %tmp1 = load i32, i32* @i4 110 ret i32 %tmp1 111} 112 113define i32* @f8() { 114; ARM32-LABEL: f8: 115; ARM32: ldr r0, 116; ARM32: ldr r0, [pc, r0] 117; ARM32-NEXT: bl __emutls_get_address(PLT) 118; ARM32-NEXT: pop 119 120entry: 121 ret i32* @i4 122} 123 124define i32 @f9() { 125; ARM32-LABEL: f9: 126; ARM32: ldr r0, 127; ARM32: ldr r0, [pc, r0] 128; ARM32-NEXT: bl __emutls_get_address(PLT) 129; ARM32-NEXT: ldr r0, [r0] 130 131entry: 132 %tmp1 = load i32, i32* @i5 133 ret i32 %tmp1 134} 135 136define i32* @f10() { 137; ARM32-LABEL: f10: 138; ARM32: ldr r0, 139; ARM32: ldr r0, [pc, r0] 140; ARM32-NEXT: bl __emutls_get_address(PLT) 141; ARM32-NEXT: pop 142 143entry: 144 ret i32* @i5 145} 146 147define i16 @f11() { 148; ARM32-LABEL: f11: 149; ARM32: ldr r0, 150; ARM32: ldr r0, [pc, r0] 151; ARM32-NEXT: bl __emutls_get_address(PLT) 152; ARM32-NEXT: ldrh r0, [r0] 153 154entry: 155 %tmp1 = load i16, i16* @s1 156 ret i16 %tmp1 157} 158 159define i32 @f12() { 160; ARM32-LABEL: f12: 161; ARM32: ldr r0, 162; ARM32: ldr r0, [pc, r0] 163; ARM32-NEXT: bl __emutls_get_address(PLT) 164; ARM32-NEXT: ldrsh r0, [r0] 165 166entry: 167 %tmp1 = load i16, i16* @s1 168 %tmp2 = sext i16 %tmp1 to i32 169 ret i32 %tmp2 170} 171 172define i8 @f13() { 173; ARM32-LABEL: f13: 174; ARM32: ldr r0, 175; ARM32: ldr r0, [pc, r0] 176; ARM32-NEXT: bl __emutls_get_address(PLT) 177; ARM32-NEXT: ldrb r0, [r0] 178; ARM32-NEXT: pop 179 180entry: 181 %tmp1 = load i8, i8* @b1 182 ret i8 %tmp1 183} 184 185define i32 @f14() { 186; ARM32-LABEL: f14: 187; ARM32: ldr r0, 188; ARM32: ldr r0, [pc, r0] 189; ARM32-NEXT: bl __emutls_get_address(PLT) 190; ARM32-NEXT: ldrsb r0, [r0] 191; ARM32-NEXT: pop 192 193entry: 194 %tmp1 = load i8, i8* @b1 195 %tmp2 = sext i8 %tmp1 to i32 196 ret i32 %tmp2 197} 198 199;;;;;;;;;;;;;; 32-bit __emutls_v. and __emutls_t. 200 201; ARM32 .section .data.rel.local, 202; ARM32-LABEL: __emutls_v.i1: 203; ARM32-NEXT: .long 4 204; ARM32-NEXT: .long 4 205; ARM32-NEXT: .long 0 206; ARM32-NEXT: .long __emutls_t.i1 207 208; ARM32 .section .rodata, 209; ARM32-LABEL: __emutls_t.i1: 210; ARM32-NEXT: .long 15 211 212; ARM32-NOT: __emutls_v.i2 213 214; ARM32 .section .data.rel.local, 215; ARM32-LABEL: __emutls_v.i3: 216; ARM32-NEXT: .long 4 217; ARM32-NEXT: .long 4 218; ARM32-NEXT: .long 0 219; ARM32-NEXT: .long __emutls_t.i3 220 221; ARM32 .section .rodata, 222; ARM32-LABEL: __emutls_t.i3: 223; ARM32-NEXT: .long 15 224 225; ARM32 .section .data.rel.local, 226; ARM32-LABEL: __emutls_v.i4: 227; ARM32-NEXT: .long 4 228; ARM32-NEXT: .long 4 229; ARM32-NEXT: .long 0 230; ARM32-NEXT: .long __emutls_t.i4 231 232; ARM32 .section .rodata, 233; ARM32-LABEL: __emutls_t.i4: 234; ARM32-NEXT: .long 15 235 236; ARM32-NOT: __emutls_v.i5: 237; ARM32 .hidden __emutls_v.i5 238; ARM32-NOT: __emutls_v.i5: 239 240; ARM32 .section .data.rel.local, 241; ARM32-LABEL: __emutls_v.s1: 242; ARM32-NEXT: .long 2 243; ARM32-NEXT: .long 2 244; ARM32-NEXT: .long 0 245; ARM32-NEXT: .long __emutls_t.s1 246 247; ARM32 .section .rodata, 248; ARM32-LABEL: __emutls_t.s1: 249; ARM32-NEXT: .short 15 250 251; ARM32 .section .data.rel.local, 252; ARM32-LABEL: __emutls_v.b1: 253; ARM32-NEXT: .long 1 254; ARM32-NEXT: .long 1 255; ARM32-NEXT: .long 0 256; ARM32-NEXT: .long 0 257 258; ARM32-NOT: __emutls_t.b1 259