xref: /llvm-project/llvm/test/CodeGen/ARM/ha-alignstack-call.ll (revision ab3bb86d4487fa904a18b6350901b3a4e9470196)
1; RUN: llc --mtriple=armv7-eabihf %s -o - | FileCheck %s --enable-var-scope
2
3%struct.S0 = type { [4 x float] }
4%struct.S1 = type { [2 x float] }
5%struct.S2 = type { [4 x float] }
6%struct.D0 = type { [2 x double] }
7%struct.D1 = type { [2 x double] }
8%struct.D2 = type { [4 x double] }
9
10; pass in regs
11declare dso_local float @f0_0(double, double, double, double, double, double, %struct.S0) local_unnamed_addr #0
12define dso_local float @f0_0_call() local_unnamed_addr #0 {
13entry:
14  %call = tail call float @f0_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.S0 { [4 x float] [float 0x3FE3333340000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
15  ret float %call
16}
17; CHECK-LABEL: f0_0_call:
18; CHECK:       vldr s12, .L[[L:.*]]
19; CHECK:       b    f0_0
20; CHECK:      .L[[L]]:
21; CHECK-NEXT: .long 0x3f19999a
22
23; pass in memory, no split
24declare dso_local float @f0_1(double, double, double, double, double, double, float, %struct.S0) local_unnamed_addr #0
25define dso_local float @f0_1_call() local_unnamed_addr #0 {
26entry:
27  %call = tail call float @f0_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, float 0x3FE3333340000000, %struct.S0 { [4 x float] [float 0x3FE6666660000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
28  ret float %call
29}
30; CHECK-LABEL: f0_1_call:
31; CHECK:       movw r1, #13107
32; CHECK:       mov  r0, #0
33; CHECK:       movt r1, #16179
34; CHECK-DAG:   str  r1, [sp]
35; CHECK-DAG:   str  r0, [sp, #4]
36; CHECK-DAG:   str  r0, [sp, #8]
37; CHECK-DAG:   str  r0, [sp, #12]
38; CHECK:       bl   f0_1
39
40; pass memory, alignment 4
41declare dso_local float @f0_2(double, double, double, double, double, double, double, double, float, %struct.S0) local_unnamed_addr #0
42define dso_local float @f0_2_call() local_unnamed_addr #0 {
43entry:
44  %call = tail call float @f0_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S0 { [4 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
45  ret float %call
46}
47; CHECK-LABEL: f0_2_call:
48; CHECK:       movw r1, #26214
49; CHECK:       movw r2, #52429
50; CHECK:       mov  r0, #0
51; CHECK:       movt r1, #16230
52; CHECK:       movt r2, #16204
53; CHECK-DAG:   str  r2, [sp]
54; CHECK-DAG:   str  r1, [sp, #4]
55; CHECK-DAG:   str  r0, [sp, #8]
56; CHECK-DAG:   str  r0, [sp, #12]
57; CHECK-DAG:   str  r0, [sp, #16]
58; CHECK:       bl       f0_2
59
60; pass in regs
61declare dso_local float @f1_0(double, double, double, double, double, double, double, %struct.S1 alignstack(8)) local_unnamed_addr #0
62define dso_local float @f1_0_call() local_unnamed_addr #0 {
63entry:
64  %call = tail call float @f1_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.S1 alignstack(8) { [2 x float] [float 0x3FE6666660000000, float 0.000000e+00] }) #0
65  ret float %call
66}
67; CHECK-LABEL: f1_0_call:
68; CHECK-DAG:   vldr s14, .L[[L0:.*]]
69; CHECK-DAG:   vldr s15, .L[[L1:.*]]
70; CHECK:       b    f1_0
71; CHECK:       .L[[L0]]:
72; CHECK-NEXT:  .long 0x3f333333
73; CHECK:       .L[[L1:.*]]:
74; CHECK-NEXT:  .long 0x00000000
75
76; pass in memory, no split
77declare dso_local float @f1_1(double, double, double, double, double, double, double, float, %struct.S1 alignstack(8)) local_unnamed_addr #0
78define dso_local float @f1_1_call() local_unnamed_addr #0 {
79entry:
80  %call = tail call float @f1_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, float 0x3FE6666660000000, %struct.S1 alignstack(8) { [2 x float] [float 0x3FE99999A0000000, float 0.000000e+00] }) #0
81  ret float %call
82}
83; CHECK-LABEL: f1_1_call:
84; CHECK:       movw r1, #52429
85; CHECK:       mov  r0, #0
86; CHECK:       movt r1, #16204
87; CHECK-DAG:   str  r1, [sp]
88; CHECK-DAG:   str  r0, [sp, #4]
89; CHECK:       bl   f1_1
90
91; pass in memory, alignment 8
92declare dso_local float @f1_2(double, double, double, double, double, double, double, double, float, %struct.S1 alignstack(8)) local_unnamed_addr #0
93define dso_local float @f1_2_call() local_unnamed_addr #0 {
94entry:
95  %call = tail call float @f1_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S1 alignstack(8) { [2 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00] }) #0
96  ret float %call
97}
98; CHECK-LABEL: f1_2_call:
99; CHECK-DAG:   mov   r0, #0
100; CHECK-DAG:   movw  r1, #26214
101; CHECK:       str   r0, [sp, #12]
102; CHECK:       movw  r0, #52429
103; CHECK:       movt  r1, #16230
104; CHECK:       movt  r0, #16204
105; CHECK-DAG:   str   r1, [sp, #8]
106; CHECK-DAG:   str   r0, [sp]
107; CHECK:       bl    f1_2
108
109
110; pass in registers
111declare dso_local float @f2_0(double, double, double, double, double, double, %struct.S2 alignstack(8)) local_unnamed_addr #0
112define dso_local float @f2_0_call() local_unnamed_addr #0 {
113entry:
114  %call = tail call float @f2_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.S2 alignstack(8) { [4 x float] [float 0x3FE3333340000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
115  ret float %call
116}
117; CHECK-LABEL: f2_0_call:
118; CHECK-DAG:   vldr     s12, .L[[L0:.*]]
119; CHECK-DAG:   vldr     s13, .L[[L1:.*]]
120; CHECK-DAG:   vmov.f32 s14, s13
121; CHECK-DAG:   vmov.f32 s15, s13
122; CHECK:       b        f2_0
123; CHECK:       .L[[L0]]:
124; CHECK-NEXT:  .long 0x3f19999a
125; CHECK:       .L[[L1]]:
126; CHECK-NEXT:  .long 0x00000000
127
128; pass in memory, no split
129declare dso_local float @f2_1(double, double, double, double, double, double, float, %struct.S2 alignstack(8)) local_unnamed_addr #0
130define dso_local float @f2_1_call() local_unnamed_addr #0 {
131entry:
132  %call = tail call float @f2_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, float 0x3FE3333340000000, %struct.S2 alignstack(8) { [4 x float] [float 0x3FE6666660000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
133  ret float %call
134}
135; CHECK-LABEL: f2_1_call:
136; CHECK:       movw  r1, #13107
137; CHECK:       mov   r0, #0
138; CHECK:       movt  r1, #16179
139; CHECK:       str   r1, [sp]
140; CHECK:       str   r0, [sp, #4]
141; CHECK:       vldr  s12, .L[[L:.*]]
142; CHECK:       str   r0, [sp, #8]
143; CHECK:       str   r0, [sp, #12]
144; CHECK:       bl    f2_1
145; CHECK:       .L[[L]]:
146; CHECK-NEXT:  .long    0x3f19999a
147
148; pass in memory, alignment 8
149declare dso_local float @f2_2(double, double, double, double, double, double, double, double, float, %struct.S2 alignstack(8)) local_unnamed_addr #0
150define dso_local float @f2_2_call() local_unnamed_addr #0 {
151entry:
152  %call = tail call float @f2_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.S2 alignstack(8) { [4 x float] [float 0x3FECCCCCC0000000, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00] }) #0
153  ret float %call
154}
155; CHECK-LABEL: f2_2_call:
156; CHECK:       mov  r0, #0
157; CHECK:       movw r1, #26214
158; CHECK:       str  r0, [sp, #12]
159; CHECK:       str  r0, [sp, #16]
160; CHECK:       movt r1, #16230
161; CHECK:       str  r0, [sp, #20]
162; CHECK:       movw r0, #52429
163; CHECK:       movt r0, #16204
164; CHECK:       str  r1, [sp, #8]
165; CHECK:       str  r0, [sp]
166; CHECK:       bl   f2_2
167
168; pass in registers
169declare dso_local double @g0_0(double, double, double, double, double, double, %struct.D0) local_unnamed_addr #0
170define dso_local double @g0_0_call() local_unnamed_addr #0 {
171entry:
172  %call = tail call double @g0_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.D0 { [2 x double] [double 6.000000e-01, double 0.000000e+00] }) #0
173  ret double %call
174}
175; CHECK-LABEL: g0_0_call:
176; CHECK:       vldr    d6, .L[[L:.*]]
177; CHECK:       b    g0_0
178; CHECK:       .L[[L]]
179; CHECK-NEXT:  long 858993459
180; CHECK-NEXT:  long 1071854387
181
182; pass in memory, no split
183declare dso_local double @g0_1(double, double, double, double, double, double, double, %struct.D0) local_unnamed_addr #0
184define dso_local double @g0_1_call() local_unnamed_addr #0 {
185entry:
186  %call = tail call double @g0_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.D0 { [2 x double] [double 0x3FE6666666666666, double 0.000000e+00] }) #0
187  ret double %call
188}
189; CHECK-LABEL: g0_1_call:
190; CHECK:       movw  r0, #26214
191; CHECK:       movw  r1, #26214
192; CHECK:       mov   r2, #0
193; CHECK:       movt  r0, #16358
194; CHECK:       movt  r1, #26214
195; CHECK:       str   r1, [sp]
196; CHECK:       stmib sp, {r0, r2}
197; CHECK:       str   r2, [sp, #12]
198; CHECK:       bl    g0_1
199
200; pass in memory, alignment 8
201declare dso_local double @g0_2(double, double, double, double, double, double, double, double, float, %struct.D0) local_unnamed_addr #0
202define dso_local double @g0_2_call() local_unnamed_addr #0 {
203entry:
204  %call = tail call double @g0_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D0 { [2 x double] [double 9.000000e-01, double 0.000000e+00] }) #0
205  ret double %call
206}
207; CHECK-LABEL: g0_2_call:
208; CHECK:       movw r0, #52428
209; CHECK:       movt r0, #16364
210; CHECK:       movw r1, #52429
211; CHECK:       str  r0, [sp, #12]
212; CHECK:       movw r0, #52429
213; CHECK:       mov  r2, #0
214; CHECK:       movt r1, #52428
215; CHECK:       movt r0, #16204
216; CHECK:       str  r1, [sp, #8]
217; CHECK:       str  r2, [sp, #16]
218; CHECK:       str  r2, [sp, #20]
219; CHECK:       str  r0, [sp]
220; CHECK:       bl   g0_2
221
222; pass in registers
223declare dso_local double @g1_0(double, double, double, double, double, double, %struct.D1 alignstack(8)) local_unnamed_addr #0
224define dso_local double @g1_0_call() local_unnamed_addr #0 {
225entry:
226  %call = tail call double @g1_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, %struct.D1 alignstack(8) { [2 x double] [double 6.000000e-01, double 0.000000e+00] }) #0
227  ret double %call
228}
229; CHECK-LABEL: g1_0_call:
230; CHECK-DAG:   vmov.i32 d7, #0x0
231; CHECK-DAG:   vldr     d6, .L[[L:.*]]
232; CHECK:       b        g1_0
233; CHECK:      .L[[L]]:
234; CHECK-NEXT: .long    858993459
235; CHECK-NEXT: .long    107185438
236
237; pass in memory, no split
238declare dso_local double @g1_1(double, double, double, double, double, double, double, %struct.D1 alignstack(8)) local_unnamed_addr #0
239define dso_local double @g1_1_call() local_unnamed_addr #0 {
240entry:
241  %call = tail call double @g1_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, %struct.D1 alignstack(8) { [2 x double] [double 0x3FE6666666666666, double 0.000000e+00] }) #0
242  ret double %call
243}
244; CHECK-LABEL: g1_1_call:
245; CHECK:       movw  r0, #26214
246; CHECK:       movw  r1, #26214
247; CHECK:       mov   r2, #0
248; CHECK:       movt  r0, #16358
249; CHECK:       movt  r1, #26214
250; CHECK:       str   r1, [sp]
251; CHECK:       stmib sp, {r0, r2}
252; CHECK:       str   r2, [sp, #12]
253; CHECK:       bl    g1_1
254
255; pass in memory, alignment 8
256declare dso_local double @g1_2(double, double, double, double, double, double, double, double, float, %struct.D1 alignstack(8)) local_unnamed_addr #0
257define dso_local double @g1_2_call() local_unnamed_addr #0 {
258entry:
259  %call = tail call double @g1_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D1 alignstack(8) { [2 x double] [double 9.000000e-01, double 0.000000e+00] }) #0
260  ret double %call
261}
262; CHECK-LABEL: g1_2_call:
263; CHECK:       movw r0, #52428
264; CHECK:       movt r0, #16364
265; CHECK:       movw r1, #52429
266; CHECK:       str  r0, [sp, #12]
267; CHECK:       movw r0, #52429
268; CHECK:       mov  r2, #0
269; CHECK:       movt r1, #52428
270; CHECK:       movt r0, #16204
271; CHECK:       str  r1, [sp, #8]
272; CHECK:       str  r2, [sp, #16]
273; CHECK:       str  r2, [sp, #20]
274; CHECK:       str  r0, [sp]
275; CHECK:       bl   g1_2
276
277; pass in registers
278declare dso_local double @g2_0(double, double, double, double, %struct.D2 alignstack(8)) local_unnamed_addr #0
279define dso_local double @g2_0_call() local_unnamed_addr #0 {
280entry:
281  %call = tail call double @g2_0(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, %struct.D2 alignstack(8) { [4 x double] [double 4.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0
282  ret double %call
283}
284; CHECK-LABEL: g2_0_call:
285; CHECK-DAG:   vldr     d4, .L[[L:.*]]
286; CHECK-DAG:   vmov.i32 d5, #0x0
287; CHECK-DAG:   vmov.i32 d6, #0x0
288; CHECK-DAG:   vmov.i32 d7, #0x0
289; CHECK:       b        g2_0
290; CHECK:       .L[[L]]:
291; CHECK-NEXT:  .long    2576980378
292; CHECK-NEXT:  .long    1071225241
293
294; pass in memory, no split
295; [sp] [sp + 4] =  0x00000000 0x3fe00000 = .5
296; [sp + 8] [sp + 12] = 0 0 = .0
297; ...
298declare dso_local double @g2_1(double, double, double, double, double, %struct.D2 alignstack(8)) local_unnamed_addr #0
299define dso_local double @g2_1_call() local_unnamed_addr #0 {
300entry:
301  %call = tail call double @g2_1(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, %struct.D2 alignstack(8) { [4 x double] [double 5.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0
302  ret double %call
303}
304; CHECK-LABEL: g2_1_call:
305; CHECK:       movw   r0, #0
306; CHECK:       mov    r1, #0
307; CHECK:       movt   r0, #16352
308; CHECK:       str    r1, [sp]
309; CHECK:       stmib  sp, {r0, r1}
310; CHECK:       str    r1, [sp, #12]
311; CHECK:       str    r1, [sp, #16]
312; CHECK:       str    r1, [sp, #20]
313; CHECK:       str    r1, [sp, #24]
314; CHECK:       str    r1, [sp, #28]
315; CHECK:       bl    g2_1
316
317; pass in memory, alignment 8
318declare dso_local double @g2_2(double, double, double, double, double, double, double, double, float, %struct.D2 alignstack(8)) local_unnamed_addr #0
319define dso_local double @g2_2call() local_unnamed_addr #0 {
320entry:
321  %call = tail call double @g2_2(double 0.000000e+00, double 1.000000e-01, double 2.000000e-01, double 3.000000e-01, double 4.000000e-01, double 5.000000e-01, double 6.000000e-01, double 0x3FE6666666666666, float 0x3FE99999A0000000, %struct.D2 alignstack(8) { [4 x double] [double 9.000000e-01, double 0.000000e+00, double 0.000000e+00, double 0.000000e+00] }) #0
322  ret double %call
323}
324; CHECK-LABEL: g2_2call:
325; CHECK:       movw r0, #52428
326; CHECK:       movt r0, #16364
327; CHECK:       movw r1, #52429
328; CHECK:       str  r0, [sp, #12]
329; CHECK:       movw r0, #52429
330; CHECK:       mov  r2, #0
331; CHECK:       movt r1, #52428
332; CHECK:       movt r0, #16204
333; CHECK:       str  r1, [sp, #8]
334; CHECK:       str  r2, [sp, #16]
335; CHECK:       str  r2, [sp, #20]
336; CHECK:       str  r2, [sp, #24]
337; CHECK:       str  r2, [sp, #28]
338; CHECK:       str  r2, [sp, #32]
339; CHECK:       str  r2, [sp, #36]
340; CHECK:       str  r0, [sp]
341; CHECK:       bl   g2_2
342
343attributes #0 = { nounwind "target-cpu"="generic" "target-features"="+armv7-a,+d32,+dsp,+fp64,+neon,+strict-align,+vfp2,+vfp2sp,+vfp3,+vfp3d16,+vfp3d16sp,+vfp3sp,-thumb-mode" }
344