1; RUN: llc < %s -mcpu=generic -mtriple=i686-pc-linux-gnu -relocation-model=pic -asm-verbose=false -post-RA-scheduler=false | FileCheck %s -check-prefix=LINUX
2
3@ptr = external global i32*
4@dst = external global i32
5@src = external global i32
6
7define void @test0() nounwind {
8entry:
9    store i32* @dst, i32** @ptr
10    %tmp.s = load i32* @src
11    store i32 %tmp.s, i32* @dst
12    ret void
13
14; LINUX-LABEL:    test0:
15; LINUX:	calll	.L0$pb
16; LINUX-NEXT: .L0$pb:
17; LINUX-NEXT:	popl
18; LINUX:	addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L0$pb),
19; LINUX:	movl	dst@GOT(%eax),
20; LINUX:	movl	ptr@GOT(%eax),
21; LINUX:	movl	src@GOT(%eax),
22; LINUX:	ret
23}
24
25@ptr2 = global i32* null
26@dst2 = global i32 0
27@src2 = global i32 0
28
29define void @test1() nounwind {
30entry:
31    store i32* @dst2, i32** @ptr2
32    %tmp.s = load i32* @src2
33    store i32 %tmp.s, i32* @dst2
34    ret void
35
36; LINUX-LABEL: test1:
37; LINUX:	calll	.L1$pb
38; LINUX-NEXT: .L1$pb:
39; LINUX-NEXT:	popl
40; LINUX:	addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L1$pb), %eax
41; LINUX:	movl	dst2@GOT(%eax),
42; LINUX:	movl	ptr2@GOT(%eax),
43; LINUX:	movl	src2@GOT(%eax),
44; LINUX:	ret
45
46}
47
48declare i8* @malloc(i32)
49
50define void @test2() nounwind {
51entry:
52    %ptr = call i8* @malloc(i32 40)
53    ret void
54; LINUX-LABEL: test2:
55; LINUX: 	pushl	%ebx
56; LINUX-NEXT: 	subl	$8, %esp
57; LINUX-NEXT: 	calll	.L2$pb
58; LINUX-NEXT: .L2$pb:
59; LINUX-NEXT: 	popl	%ebx
60; LINUX: 	addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L2$pb), %ebx
61; LINUX: 	movl	$40, (%esp)
62; LINUX: 	calll	malloc@PLT
63; LINUX: 	addl	$8, %esp
64; LINUX: 	popl	%ebx
65; LINUX: 	ret
66}
67
68@pfoo = external global void(...)*
69
70define void @test3() nounwind {
71entry:
72    %tmp = call void(...)*(...)* @afoo()
73    store void(...)* %tmp, void(...)** @pfoo
74    %tmp1 = load void(...)** @pfoo
75    call void(...)* %tmp1()
76    ret void
77; LINUX-LABEL: test3:
78; LINUX: 	calll	.L3$pb
79; LINUX-NEXT: .L3$pb:
80; LINUX: 	popl
81; LINUX: 	addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L3$pb), %[[REG3:e..]]
82; LINUX: 	calll	afoo@PLT
83; LINUX: 	movl	pfoo@GOT(%[[REG3]]),
84; LINUX: 	calll	*
85}
86
87declare void(...)* @afoo(...)
88
89define void @test4() nounwind {
90entry:
91    call void(...)* @foo()
92    ret void
93; LINUX-LABEL: test4:
94; LINUX: calll	.L4$pb
95; LINUX: popl	%ebx
96; LINUX: addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L4$pb), %ebx
97; LINUX: calll	foo@PLT
98}
99
100declare void @foo(...)
101
102
103@ptr6 = internal global i32* null
104@dst6 = internal global i32 0
105@src6 = internal global i32 0
106
107define void @test5() nounwind {
108entry:
109    store i32* @dst6, i32** @ptr6
110    %tmp.s = load i32* @src6
111    store i32 %tmp.s, i32* @dst6
112    ret void
113
114; LINUX-LABEL: test5:
115; LINUX: 	calll	.L5$pb
116; LINUX-NEXT: .L5$pb:
117; LINUX-NEXT: 	popl	%eax
118; LINUX: 	addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L5$pb), %eax
119; LINUX: 	leal	dst6@GOTOFF(%eax), %ecx
120; LINUX: 	movl	%ecx, ptr6@GOTOFF(%eax)
121; LINUX: 	movl	src6@GOTOFF(%eax), %ecx
122; LINUX: 	movl	%ecx, dst6@GOTOFF(%eax)
123; LINUX: 	ret
124}
125
126
127;; Test constant pool references.
128define double @test6(i32 %a.u) nounwind {
129entry:
130    %tmp = icmp eq i32 %a.u,0
131    %retval = select i1 %tmp, double 4.561230e+02, double 1.234560e+02
132    ret double %retval
133
134; LINUX: .LCPI6_0:
135
136; LINUX-LABEL: test6:
137; LINUX:    calll .L6$pb
138; LINUX: .L6$pb:
139; LINUX:    addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L6$pb),
140; LINUX:    fldl	.LCPI6_0@GOTOFF(
141}
142
143
144;; Test jump table references.
145define void @test7(i32 %n.u) nounwind {
146entry:
147    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 ]
148bb:
149    tail call void(...)* @foo1()
150    ret void
151bb1:
152    tail call void(...)* @foo2()
153    ret void
154bb2:
155    tail call void(...)* @foo6()
156    ret void
157bb3:
158    tail call void(...)* @foo3()
159    ret void
160bb4:
161    tail call void(...)* @foo4()
162    ret void
163bb5:
164    tail call void(...)* @foo5()
165    ret void
166bb6:
167    tail call void(...)* @foo1()
168    ret void
169bb7:
170    tail call void(...)* @foo2()
171    ret void
172bb8:
173    tail call void(...)* @foo6()
174    ret void
175bb9:
176    tail call void(...)* @foo3()
177    ret void
178bb10:
179    tail call void(...)* @foo4()
180    ret void
181bb11:
182    tail call void(...)* @foo5()
183    ret void
184bb12:
185    tail call void(...)* @foo6()
186    ret void
187
188; LINUX-LABEL: test7:
189; LINUX:   calll	.L7$pb
190; LINUX: .L7$pb:
191; LINUX:   addl	$_GLOBAL_OFFSET_TABLE_+(.L{{.*}}-.L7$pb),
192; LINUX:   .LJTI7_0@GOTOFF(
193; LINUX:   jmpl	*
194
195; LINUX: .align 4
196; LINUX-NEXT: .LJTI7_0:
197; LINUX:   .long	 .LBB7_2@GOTOFF
198; LINUX:   .long	 .LBB7_8@GOTOFF
199; LINUX:   .long	 .LBB7_14@GOTOFF
200; LINUX:   .long	 .LBB7_9@GOTOFF
201; LINUX:   .long	 .LBB7_10@GOTOFF
202}
203
204declare void @foo1(...)
205declare void @foo2(...)
206declare void @foo6(...)
207declare void @foo3(...)
208declare void @foo4(...)
209declare void @foo5(...)
210