1; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK,CHECK-I686 2; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-linux-gnux32 -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK,CHECK-X32 3; RUN: llc < %s -mcpu=generic -mtriple=x86_64-pc-linux-gnux32 -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false -fast-isel -verify-machineinstrs | FileCheck %s -check-prefixes=CHECK,CHECK-X32 4 5@ptr = external global i32* 6@dst = external global i32 7@src = external global i32 8 9define void @test0() nounwind { 10entry: 11 store i32* @dst, i32** @ptr 12 %tmp.s = load i32, i32* @src 13 store i32 %tmp.s, i32* @dst 14 ret void 15 16; CHECK-LABEL: test0: 17; CHECK-I686: calll .L0$pb 18; CHECK-I686-NEXT: .L0$pb: 19; CHECK-I686-NEXT: popl 20; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L0$pb), 21; CHECK-I686: movl dst@GOT(%eax), 22; CHECK-I686: movl ptr@GOT(%eax), 23; CHECK-I686: movl src@GOT(%eax), 24; CHECK-I686: ret 25; CHECK-X32-DAG: movl dst@GOTPCREL(%rip), 26; CHECK-X32-DAG: movl ptr@GOTPCREL(%rip), 27; CHECK-X32-DAG: movl src@GOTPCREL(%rip), 28; CHECK-X32: retq 29} 30 31@ptr2 = global i32* null 32@dst2 = global i32 0 33@src2 = global i32 0 34 35define void @test1() nounwind { 36entry: 37 store i32* @dst2, i32** @ptr2 38 %tmp.s = load i32, i32* @src2 39 store i32 %tmp.s, i32* @dst2 40 ret void 41 42; CHECK-LABEL: test1: 43; CHECK-I686: calll .L1$pb 44; CHECK-I686-NEXT: .L1$pb: 45; CHECK-I686-NEXT: popl 46; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L1$pb), %eax 47; CHECK-I686: movl dst2@GOT(%eax), 48; CHECK-I686: movl ptr2@GOT(%eax), 49; CHECK-I686: movl src2@GOT(%eax), 50; CHECK-I686: ret 51; CHECK-X32-DAG: movl dst2@GOTPCREL(%rip), 52; CHECK-X32-DAG: movl ptr2@GOTPCREL(%rip), 53; CHECK-X32-DAG: movl src2@GOTPCREL(%rip), 54; CHECK-X32: retq 55 56} 57 58declare i8* @malloc(i32) 59 60define void @test2() nounwind { 61entry: 62 %ptr = call i8* @malloc(i32 40) 63 ret void 64; CHECK-LABEL: test2: 65; CHECK-I686: pushl %ebx 66; CHECK-I686-NEXT: subl $8, %esp 67; CHECK-I686-NEXT: calll .L2$pb 68; CHECK-I686-NEXT: .L2$pb: 69; CHECK-I686-NEXT: popl %ebx 70; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L2$pb), %ebx 71; CHECK-I686: movl $40, (%esp) 72; CHECK-I686: calll malloc@PLT 73; CHECK-I686: addl $8, %esp 74; CHECK-I686: popl %ebx 75; CHECK-I686: ret 76; CHECK-X32: pushq %rax 77; CHECK-X32: movl $40, %edi 78; CHECK-X32: callq malloc@PLT 79; CHECK-X32: popq %rax 80; CHECK-X32: retq 81 82} 83 84@pfoo = external global void(...)* 85 86define void @test3() nounwind { 87entry: 88 %tmp = call void(...)*(...) @afoo() 89 store void(...)* %tmp, void(...)** @pfoo 90 %tmp1 = load void(...)*, void(...)** @pfoo 91 call void(...) %tmp1() 92 ret void 93; CHECK-LABEL: test3: 94; CHECK-I686: calll .L3$pb 95; CHECK-I686-NEXT: .L3$pb: 96; CHECK-I686: popl 97; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L3$pb), %[[REG3:e..]] 98; CHECK-I686: calll afoo@PLT 99; CHECK-I686: movl pfoo@GOT(%[[REG3]]), 100; CHECK-I686: calll * 101; CHECK-X32: callq afoo@PLT 102; CHECK-X32: movl pfoo@GOTPCREL(%rip), 103; CHECK-X32: callq * 104} 105 106declare void(...)* @afoo(...) 107 108define void @test4() nounwind { 109entry: 110 call void(...) @foo() 111 ret void 112; CHECK-LABEL: test4: 113; CHECK-I686: calll .L4$pb 114; CHECK-I686: popl %ebx 115; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L4$pb), %ebx 116; CHECK-I686: calll foo@PLT 117; CHECK-X32: callq foo@PLT 118 119} 120 121declare void @foo(...) 122 123 124@ptr6 = internal global i32* null 125@dst6 = internal global i32 0 126@src6 = internal global i32 0 127 128define void @test5() nounwind { 129entry: 130 store i32* @dst6, i32** @ptr6 131 %tmp.s = load i32, i32* @src6 132 store i32 %tmp.s, i32* @dst6 133 ret void 134 135; CHECK-LABEL: test5: 136; CHECK-I686: calll .L5$pb 137; CHECK-I686-NEXT: .L5$pb: 138; CHECK-I686-NEXT: popl %eax 139; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L5$pb), %eax 140; CHECK-I686: leal dst6@GOTOFF(%eax), %ecx 141; CHECK-I686: movl %ecx, ptr6@GOTOFF(%eax) 142; CHECK-I686: movl src6@GOTOFF(%eax), %ecx 143; CHECK-I686: movl %ecx, dst6@GOTOFF(%eax) 144; CHECK-I686: ret 145; CHECK-X32: leal dst6(%rip), %eax 146; CHECK-X32: movl %eax, ptr6(%rip) 147; CHECK-X32: movl src6(%rip), %eax 148; CHECK-X32: movl %eax, dst6(%rip) 149; CHECK-X32: retq 150} 151 152 153;; Test constant pool references. 154define double @test6(i32 %a.u) nounwind { 155entry: 156 %tmp = icmp eq i32 %a.u,0 157 %retval = select i1 %tmp, double 4.561230e+02, double 1.234560e+02 158 ret double %retval 159 160; CHECK: .LCPI6_0: 161 162; CHECK-LABEL: test6: 163; CHECK-I686: calll .L6$pb 164; CHECK-I686: .L6$pb: 165; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L6$pb), 166; CHECK-I686: fldl .LCPI6_0@GOTOFF( 167; CHECK-X32: .LCPI6_0(%rip), 168} 169 170 171;; Test jump table references. 172define void @test7(i32 %n.u) nounwind { 173entry: 174 switch i32 %n.u, label %bb12 [i32 1, label %bb i32 2, label %bb6 i32 4, label %bb7 i32 5, label %bb8 i32 6, label %bb10 i32 7, label %bb1 i32 8, label %bb3 i32 9, label %bb4 i32 10, label %bb9 i32 11, label %bb2 i32 12, label %bb5 i32 13, label %bb11 ] 175bb: 176 tail call void(...) @foo1() 177 ret void 178bb1: 179 tail call void(...) @foo2() 180 ret void 181bb2: 182 tail call void(...) @foo6() 183 ret void 184bb3: 185 tail call void(...) @foo3() 186 ret void 187bb4: 188 tail call void(...) @foo4() 189 ret void 190bb5: 191 tail call void(...) @foo5() 192 ret void 193bb6: 194 tail call void(...) @foo1() 195 ret void 196bb7: 197 tail call void(...) @foo2() 198 ret void 199bb8: 200 tail call void(...) @foo6() 201 ret void 202bb9: 203 tail call void(...) @foo3() 204 ret void 205bb10: 206 tail call void(...) @foo4() 207 ret void 208bb11: 209 tail call void(...) @foo5() 210 ret void 211bb12: 212 tail call void(...) @foo6() 213 ret void 214 215; CHECK-LABEL: test7: 216; CHECK-I686: calll .L7$pb 217; CHECK-I686: .L7$pb: 218; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L7$pb), 219; CHECK-I686: .LJTI7_0@GOTOFF( 220; CHECK-I686: jmpl * 221; CHECK-X32: leal .LJTI7_0(%rip), %eax 222; CHECK-X32: addl (%eax,%edi,4), %eax 223; CHECK-X32: jmpq *%rax 224 225; CHECK: .p2align 2 226; CHECK-NEXT: .LJTI7_0: 227; CHECK-I686: .long .LBB7_2@GOTOFF 228; CHECK-I686: .long .LBB7_8@GOTOFF 229; CHECK-I686: .long .LBB7_4@GOTOFF 230; CHECK-I686: .long .LBB7_6@GOTOFF 231; CHECK-I686: .long .LBB7_5@GOTOFF 232; CHECK-I686: .long .LBB7_8@GOTOFF 233; CHECK-I686: .long .LBB7_7@GOTOFF 234; CHECK-X32: .long .LBB7_3-.LJTI7_0 235; CHECK-X32: .long .LBB7_3-.LJTI7_0 236; CHECK-X32: .long .LBB7_12-.LJTI7_0 237; CHECK-X32: .long .LBB7_8-.LJTI7_0 238; CHECK-X32: .long .LBB7_12-.LJTI7_0 239; CHECK-X32: .long .LBB7_10-.LJTI7_0 240; CHECK-X32: .long .LBB7_8-.LJTI7_0 241; CHECK-X32: .long .LBB7_9-.LJTI7_0 242; CHECK-X32: .long .LBB7_10-.LJTI7_0 243; CHECK-X32: .long .LBB7_9-.LJTI7_0 244; CHECK-X32: .long .LBB7_12-.LJTI7_0 245; CHECK-X32: .long .LBB7_14-.LJTI7_0 246; CHECK-X32: .long .LBB7_14-.LJTI7_0 247} 248 249declare void @foo1(...) 250declare void @foo2(...) 251declare void @foo6(...) 252declare void @foo3(...) 253declare void @foo4(...) 254declare void @foo5(...) 255 256;; Check TLS references 257@tlsptrgd = thread_local global i32* null 258@tlsdstgd = thread_local global i32 0 259@tlssrcgd = thread_local global i32 0 260@tlsptrld = thread_local(localdynamic) global i32* null 261@tlsdstld = thread_local(localdynamic) global i32 0 262@tlssrcld = thread_local(localdynamic) global i32 0 263@tlsptrie = thread_local(initialexec) global i32* null 264@tlsdstie = thread_local(initialexec) global i32 0 265@tlssrcie = thread_local(initialexec) global i32 0 266@tlsptrle = thread_local(localexec) global i32* null 267@tlsdstle = thread_local(localexec) global i32 0 268@tlssrcle = thread_local(localexec) global i32 0 269 270define void @test8() nounwind { 271entry: 272 store i32* @tlsdstgd, i32** @tlsptrgd 273 %tmp.s = load i32, i32* @tlssrcgd 274 store i32 %tmp.s, i32* @tlsdstgd 275 ret void 276 277; CHECK-LABEL: test8: 278; CHECK-I686: calll .L8$pb 279; CHECK-I686-NEXT: .L8$pb: 280; CHECK-I686-NEXT: popl 281; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L8$pb), %ebx 282; CHECK-I686-DAG: leal tlsdstgd@TLSGD(,%ebx), %eax 283; CHECK-I686-DAG: calll ___tls_get_addr@PLT 284; CHECK-I686-DAG: leal tlsptrgd@TLSGD(,%ebx), %eax 285; CHECK-I686-DAG: calll ___tls_get_addr@PLT 286; CHECK-I686-DAG: leal tlssrcgd@TLSGD(,%ebx), %eax 287; CHECK-I686-DAG: calll ___tls_get_addr@PLT 288; CHECK-X32-DAG: leaq tlsdstgd@TLSGD(%rip), %rdi 289; CHECK-X32-DAG: callq __tls_get_addr@PLT 290; CHECK-X32-DAG: leaq tlsptrgd@TLSGD(%rip), %rdi 291; CHECK-X32-DAG: callq __tls_get_addr@PLT 292; CHECK-X32-DAG: leaq tlssrcgd@TLSGD(%rip), %rdi 293; CHECK-X32-DAG: callq __tls_get_addr@PLT 294; CHECK-I686: ret 295; CHECK-X32: retq 296} 297 298define void @test9() nounwind { 299entry: 300 store i32* @tlsdstld, i32** @tlsptrld 301 %tmp.s = load i32, i32* @tlssrcld 302 store i32 %tmp.s, i32* @tlsdstld 303 ret void 304 305; CHECK-LABEL: test9: 306; CHECK-I686: calll .L9$pb 307; CHECK-I686-NEXT: .L9$pb: 308; CHECK-I686-NEXT: popl 309; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L9$pb), %ebx 310; CHECK-I686: leal tlsdstld@TLSLDM(%ebx), %eax 311; CHECK-X32: leaq tlsdstld@TLSLD(%rip), %rdi 312; CHECK-I686: calll ___tls_get_addr@PLT 313; CHECK-X32: callq __tls_get_addr@PLT 314; CHECK: leal tlsdstld@DTPOFF( 315; CHECK: movl {{%.*}}, tlsptrld@DTPOFF( 316; CHECK: movl tlssrcld@DTPOFF( 317; CHECK: movl {{%.*}}, tlsdstld@DTPOFF( 318; CHECK-I686: ret 319; CHECK-X32: retq 320} 321 322define void @test10() nounwind { 323entry: 324 store i32* @tlsdstie, i32** @tlsptrie 325 %tmp.s = load i32, i32* @tlssrcie 326 store i32 %tmp.s, i32* @tlsdstie 327 ret void 328 329; CHECK-LABEL: test10: 330; CHECK-I686: calll .L10$pb 331; CHECK-I686-NEXT: .L10$pb: 332; CHECK-I686-NEXT: popl 333; CHECK-I686: addl $_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L10$pb), 334; CHECK-I686-DAG: movl tlsdstie@GOTNTPOFF( 335; CHECK-I686-DAG: movl %gs:0, 336; CHECK-X32-DAG: movl tlsdstie@GOTTPOFF(%rip), 337; CHECK-X32-DAG: movl %fs:0, 338; CHECK: addl 339; CHECK-I686: movl tlsptrie@GOTNTPOFF( 340; CHECK-X32: movl tlsptrie@GOTTPOFF(%rip), 341; CHECK-I686: movl {{%.*}}, %gs:( 342; CHECK-X32: movl {{%.*}}, %fs:( 343; CHECK-I686: movl tlssrcie@GOTNTPOFF( 344; CHECK-X32: movl tlssrcie@GOTTPOFF(%rip), 345; CHECK-I686: movl %gs:( 346; CHECK-X32: movl %fs:( 347; CHECK-I686: movl {{%.*}}, %gs:( 348; CHECK-X32: movl {{%.*}}, %fs:( 349; CHECK-I686: ret 350; CHECK-X32: retq 351} 352 353define void @test11() nounwind { 354entry: 355 store i32* @tlsdstle, i32** @tlsptrle 356 %tmp.s = load i32, i32* @tlssrcle 357 store i32 %tmp.s, i32* @tlsdstle 358 ret void 359 360; CHECK-LABEL: test11: 361; CHECK-I686: movl %gs:0, 362; CHECK-X32: movl %fs:0, 363; CHECK-I686: leal tlsdstle@NTPOFF( 364; CHECK-X32: leal tlsdstle@TPOFF( 365; CHECK-I686: movl {{%.*}}, %gs:tlsptrle@NTPOFF 366; CHECK-X32: movl {{%.*}}, %fs:tlsptrle@TPOFF 367; CHECK-I686: movl %gs:tlssrcle@NTPOFF, 368; CHECK-X32: movl %fs:tlssrcle@TPOFF, 369; CHECK-I686: movl {{%.*}}, %gs:tlsdstle@NTPOFF 370; CHECK-X32: movl {{%.*}}, %fs:tlsdstle@TPOFF 371; CHECK-I686: ret 372; CHECK-X32: retq 373} 374