• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -verify-machineinstrs < %s -mcpu=pwr8 \
2; RUN:   -mattr=+altivec -mattr=-vsx | FileCheck %s
3; RUN: llc -verify-machineinstrs < %s -mattr=+altivec \
4; RUN:   -mattr=-vsx | FileCheck %s
5; RUN: llc -verify-machineinstrs < %s -mcpu=pwr9 \
6; RUN:   -mattr=-direct-move -mattr=+altivec | FileCheck %s
7
8; Currently VSX support is disabled for this test because we generate lxsdx
9; instead of lfd, and stxsdx instead of stfd.  That is a poor choice when we
10; have reg+imm addressing, and is on the list of things to be fixed.
11; The second run step is to ensure that -march=ppc64le is adequate to select
12; the same feature set as with -mcpu=pwr8 since that is the baseline for ppc64le.
13
14target datalayout = "e-m:e-i64:64-n32:64"
15target triple = "powerpc64le-unknown-linux-gnu"
16
17;
18; Verify use of registers for float/vector aggregate return.
19;
20
21define [8 x float] @return_float([8 x float] %x) {
22entry:
23  ret [8 x float] %x
24}
25; CHECK-LABEL: @return_float
26; CHECK: %entry
27; CHECK-NEXT: blr
28
29define [8 x double] @return_double([8 x double] %x) {
30entry:
31  ret [8 x double] %x
32}
33; CHECK-LABEL: @return_double
34; CHECK: %entry
35; CHECK-NEXT: blr
36
37define [4 x ppc_fp128] @return_ppcf128([4 x ppc_fp128] %x) {
38entry:
39  ret [4 x ppc_fp128] %x
40}
41; CHECK-LABEL: @return_ppcf128
42; CHECK: %entry
43; CHECK-NEXT: blr
44
45define [8 x <4 x i32>] @return_v4i32([8 x <4 x i32>] %x) {
46entry:
47  ret [8 x <4 x i32>] %x
48}
49; CHECK-LABEL: @return_v4i32
50; CHECK: %entry
51; CHECK-NEXT: blr
52
53
54;
55; Verify amount of space taken up by aggregates in the parameter save area.
56;
57
58define i64 @callee_float([7 x float] %a, [7 x float] %b, i64 %c) {
59entry:
60  ret i64 %c
61}
62; CHECK-LABEL: @callee_float
63; CHECK: ld 3, 96(1)
64; CHECK: blr
65
66define void @caller_float(i64 %x, [7 x float] %y) {
67entry:
68  tail call void @test_float([7 x float] %y, [7 x float] %y, i64 %x)
69  ret void
70}
71; CHECK-LABEL: @caller_float
72; CHECK: std 3, 96(1)
73; CHECK: bl test_float
74
75declare void @test_float([7 x float], [7 x float], i64)
76
77define i64 @callee_double(i64 %a, [7 x double] %b, i64 %c) {
78entry:
79  ret i64 %c
80}
81; CHECK-LABEL: @callee_double
82; CHECK: ld 3, 96(1)
83; CHECK: blr
84
85define void @caller_double(i64 %x, [7 x double] %y) {
86entry:
87  tail call void @test_double(i64 %x, [7 x double] %y, i64 %x)
88  ret void
89}
90; CHECK-LABEL: @caller_double
91; CHECK: std 3, 96(1)
92; CHECK: bl test_double
93
94declare void @test_double(i64, [7 x double], i64)
95
96define i64 @callee_ppcf128(i64 %a, [4 x ppc_fp128] %b, i64 %c) {
97entry:
98  ret i64 %c
99}
100; CHECK-LABEL: @callee_ppcf128
101; CHECK: ld 3, 104(1)
102; CHECK: blr
103
104define void @caller_ppcf128(i64 %x, [4 x ppc_fp128] %y) {
105entry:
106  tail call void @test_ppcf128(i64 %x, [4 x ppc_fp128] %y, i64 %x)
107  ret void
108}
109; CHECK-LABEL: @caller_ppcf128
110; CHECK: std 3, 104(1)
111; CHECK: bl test_ppcf128
112
113declare void @test_ppcf128(i64, [4 x ppc_fp128], i64)
114
115define i64 @callee_i64(i64 %a, [7 x i64] %b, i64 %c) {
116entry:
117  ret i64 %c
118}
119; CHECK-LABEL: @callee_i64
120; CHECK: ld 3, 96(1)
121; CHECK: blr
122
123define void @caller_i64(i64 %x, [7 x i64] %y) {
124entry:
125  tail call void @test_i64(i64 %x, [7 x i64] %y, i64 %x)
126  ret void
127}
128; CHECK-LABEL: @caller_i64
129; CHECK: std 3, 96(1)
130; CHECK: bl test_i64
131
132declare void @test_i64(i64, [7 x i64], i64)
133
134define i64 @callee_i128(i64 %a, [4 x i128] %b, i64 %c) {
135entry:
136  ret i64 %c
137}
138; CHECK-LABEL: @callee_i128
139; CHECK: ld 3, 112(1)
140; CHECK: blr
141
142define void @caller_i128(i64 %x, [4 x i128] %y) {
143entry:
144  tail call void @test_i128(i64 %x, [4 x i128] %y, i64 %x)
145  ret void
146}
147; CHECK-LABEL: @caller_i128
148; CHECK: std 3, 112(1)
149; CHECK: bl test_i128
150
151declare void @test_i128(i64, [4 x i128], i64)
152
153define i64 @callee_v4i32(i64 %a, [4 x <4 x i32>] %b, i64 %c) {
154entry:
155  ret i64 %c
156}
157; CHECK-LABEL: @callee_v4i32
158; CHECK: ld 3, 112(1)
159; CHECK: blr
160
161define void @caller_v4i32(i64 %x, [4 x <4 x i32>] %y) {
162entry:
163  tail call void @test_v4i32(i64 %x, [4 x <4 x i32>] %y, i64 %x)
164  ret void
165}
166; CHECK-LABEL: @caller_v4i32
167; CHECK: std 3, 112(1)
168; CHECK: bl test_v4i32
169
170declare void @test_v4i32(i64, [4 x <4 x i32>], i64)
171
172
173;
174; Verify handling of floating point arguments in GPRs
175;
176
177%struct.float8 = type { [8 x float] }
178%struct.float5 = type { [5 x float] }
179%struct.float2 = type { [2 x float] }
180
181@g8 = common global %struct.float8 zeroinitializer, align 4
182@g5 = common global %struct.float5 zeroinitializer, align 4
183@g2 = common global %struct.float2 zeroinitializer, align 4
184
185define float @callee0([7 x float] %a, [7 x float] %b) {
186entry:
187  %b.extract = extractvalue [7 x float] %b, 6
188  ret float %b.extract
189}
190; CHECK-LABEL: @callee0
191; CHECK: stw 10, [[OFF:.*]](1)
192; CHECK: lfs 1, [[OFF]](1)
193; CHECK: blr
194
195define void @caller0([7 x float] %a) {
196entry:
197  tail call void @test0([7 x float] %a, [7 x float] %a)
198  ret void
199}
200; CHECK-LABEL: @caller0
201; CHECK-DAG: fmr 8, 1
202; CHECK-DAG: fmr 9, 2
203; CHECK-DAG: fmr 10, 3
204; CHECK-DAG: fmr 11, 4
205; CHECK-DAG: fmr 12, 5
206; CHECK-DAG: fmr 13, 6
207; CHECK-DAG: stfs 7, [[OFF:[0-9]+]](1)
208; CHECK-DAG: lwz 10, [[OFF]](1)
209; CHECK: bl test0
210
211declare void @test0([7 x float], [7 x float])
212
213define float @callee1([8 x float] %a, [8 x float] %b) {
214entry:
215  %b.extract = extractvalue [8 x float] %b, 7
216  ret float %b.extract
217}
218; CHECK-LABEL: @callee1
219; CHECK: rldicl [[REG:[0-9]+]], 10, 32, 32
220; CHECK: stw [[REG]], [[OFF:.*]](1)
221; CHECK: lfs 1, [[OFF]](1)
222; CHECK: blr
223
224define void @caller1([8 x float] %a) {
225entry:
226  tail call void @test1([8 x float] %a, [8 x float] %a)
227  ret void
228}
229; CHECK-LABEL: @caller1
230; CHECK-DAG: fmr 9, 1
231; CHECK-DAG: fmr 10, 2
232; CHECK-DAG: fmr 11, 3
233; CHECK-DAG: fmr 12, 4
234; CHECK-DAG: fmr 13, 5
235; CHECK-DAG: stfs 5, [[OFF0:[0-9]+]](1)
236; CHECK-DAG: stfs 6, [[OFF1:[0-9]+]](1)
237; CHECK-DAG: stfs 7, [[OFF2:[0-9]+]](1)
238; CHECK-DAG: stfs 8, [[OFF3:[0-9]+]](1)
239; CHECK-DAG: lwz [[REG0:[0-9]+]], [[OFF0]](1)
240; CHECK-DAG: lwz [[REG1:[0-9]+]], [[OFF1]](1)
241; CHECK-DAG: lwz [[REG2:[0-9]+]], [[OFF2]](1)
242; CHECK-DAG: lwz [[REG3:[0-9]+]], [[OFF3]](1)
243; CHECK-DAG: sldi [[REG1]], [[REG1]], 32
244; CHECK-DAG: sldi [[REG3]], [[REG3]], 32
245; CHECK-DAG: or 9, [[REG0]], [[REG1]]
246; CHECK-DAG: or 10, [[REG2]], [[REG3]]
247; CHECK: bl test1
248
249declare void @test1([8 x float], [8 x float])
250
251define float @callee2([8 x float] %a, [5 x float] %b, [2 x float] %c) {
252entry:
253  %c.extract = extractvalue [2 x float] %c, 1
254  ret float %c.extract
255}
256; CHECK-LABEL: @callee2
257; CHECK: rldicl [[REG:[0-9]+]], 10, 32, 32
258; CHECK: stw [[REG]], [[OFF:.*]](1)
259; CHECK: lfs 1, [[OFF]](1)
260; CHECK: blr
261
262define void @caller2() {
263entry:
264  %0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
265  %1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
266  %2 = load [2 x float], [2 x float]* getelementptr inbounds (%struct.float2, %struct.float2* @g2, i64 0, i32 0), align 4
267  tail call void @test2([8 x float] %0, [5 x float] %1, [2 x float] %2)
268  ret void
269}
270; CHECK-LABEL: @caller2
271; CHECK: ld {{[0-9]+}}, .LC
272; CHECK-DAG: lfs 1, 0({{[0-9]+}})
273; CHECK-DAG: lfs 2, 4({{[0-9]+}})
274; CHECK-DAG: lfs 3, 8({{[0-9]+}})
275; CHECK-DAG: lfs 4, 12({{[0-9]+}})
276; CHECK-DAG: lfs 5, 16({{[0-9]+}})
277; CHECK-DAG: lfs 6, 20({{[0-9]+}})
278; CHECK-DAG: lfs 7, 24({{[0-9]+}})
279; CHECK-DAG: lfs 8, 28({{[0-9]+}})
280
281; CHECK-DAG: lfs 9, 0({{[0-9]+}})
282; CHECK-DAG: lfs 10, 4({{[0-9]+}})
283; CHECK-DAG: lfs 11, 8({{[0-9]+}})
284; CHECK-DAG: lfs 12, 12({{[0-9]+}})
285; CHECK-DAG: lfs 13, 16({{[0-9]+}})
286
287; CHECK-DAG: ld 10, 0({{[0-9]+}})
288; CHECK: bl test2
289
290declare void @test2([8 x float], [5 x float], [2 x float])
291
292define double @callee3([8 x float] %a, [5 x float] %b, double %c) {
293entry:
294  ret double %c
295}
296; CHECK-LABEL: @callee3
297; CHECK: std 10, [[OFF:.*]](1)
298; CHECK: lfd 1, [[OFF]](1)
299; CHECK: blr
300
301define void @caller3(double %d) {
302entry:
303  %0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
304  %1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
305  tail call void @test3([8 x float] %0, [5 x float] %1, double %d)
306  ret void
307}
308; CHECK-LABEL: @caller3
309; CHECK: stfd 1, [[OFF:.*]](1)
310; CHECK: ld 10, [[OFF]](1)
311; CHECK: bl test3
312
313declare void @test3([8 x float], [5 x float], double)
314
315define float @callee4([8 x float] %a, [5 x float] %b, float %c) {
316entry:
317  ret float %c
318}
319; CHECK-LABEL: @callee4
320; CHECK: stw 10, [[OFF:.*]](1)
321; CHECK: lfs 1, [[OFF]](1)
322; CHECK: blr
323
324define void @caller4(float %f) {
325entry:
326  %0 = load [8 x float], [8 x float]* getelementptr inbounds (%struct.float8, %struct.float8* @g8, i64 0, i32 0), align 4
327  %1 = load [5 x float], [5 x float]* getelementptr inbounds (%struct.float5, %struct.float5* @g5, i64 0, i32 0), align 4
328  tail call void @test4([8 x float] %0, [5 x float] %1, float %f)
329  ret void
330}
331; CHECK-LABEL: @caller4
332; CHECK: stfs 1, [[OFF:.*]](1)
333; CHECK: lwz 10, [[OFF]](1)
334; CHECK: bl test4
335
336declare void @test4([8 x float], [5 x float], float)
337
338