1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=thumbv7-linux-gnueabihf %s -o - | FileCheck %s
3; RUN: llc -mtriple=thumbv7-linux-gnueabi %s -o - | FileCheck -check-prefix=SOFTFLOAT %s
4; RUN: llc -mtriple=thumbv7-linux-gnueabihf -disable-tail-calls %s -o - | FileCheck -check-prefix=HF-NOTAIL %s
5
6; On hard-float targets, the register used to store a float return value
7; changes if the call signature is varargs. The HF-NOTAIL lines are there to
8; easily see when this happens.
9
10declare float @callee_float()
11declare i32 @callee_int()
12declare float @callee_float_vararg(i32, ...)
13declare i32 @callee_int_vararg(i32, ...)
14
15define float @caller_float__callee_float() {
16; CHECK-LABEL: caller_float__callee_float:
17; CHECK:       @ %bb.0:
18; CHECK-NEXT:    b callee_float
19;
20; SOFTFLOAT-LABEL: caller_float__callee_float:
21; SOFTFLOAT:       @ %bb.0:
22; SOFTFLOAT-NEXT:    b callee_float
23;
24; HF-NOTAIL-LABEL: caller_float__callee_float:
25; HF-NOTAIL:       @ %bb.0:
26; HF-NOTAIL-NEXT:    .save {r7, lr}
27; HF-NOTAIL-NEXT:    push {r7, lr}
28; HF-NOTAIL-NEXT:    bl callee_float
29; HF-NOTAIL-NEXT:    pop {r7, pc}
30  %r = tail call float @callee_float()
31  ret float %r
32}
33
34define float @caller_float__callee_float_vararg() {
35; CHECK-LABEL: caller_float__callee_float_vararg:
36; CHECK:       @ %bb.0:
37; CHECK-NEXT:    .save {r7, lr}
38; CHECK-NEXT:    push {r7, lr}
39; CHECK-NEXT:    movs r0, #0
40; CHECK-NEXT:    bl callee_float_vararg
41; CHECK-NEXT:    vmov s0, r0
42; CHECK-NEXT:    pop {r7, pc}
43;
44; SOFTFLOAT-LABEL: caller_float__callee_float_vararg:
45; SOFTFLOAT:       @ %bb.0:
46; SOFTFLOAT-NEXT:    movs r0, #0
47; SOFTFLOAT-NEXT:    b callee_float_vararg
48;
49; HF-NOTAIL-LABEL: caller_float__callee_float_vararg:
50; HF-NOTAIL:       @ %bb.0:
51; HF-NOTAIL-NEXT:    .save {r7, lr}
52; HF-NOTAIL-NEXT:    push {r7, lr}
53; HF-NOTAIL-NEXT:    movs r0, #0
54; HF-NOTAIL-NEXT:    bl callee_float_vararg
55; HF-NOTAIL-NEXT:    vmov s0, r0
56; HF-NOTAIL-NEXT:    pop {r7, pc}
57  %r = tail call float (i32, ...) @callee_float_vararg(i32 0)
58  ret float %r
59}
60
61define float @caller_float_vararg__callee_float(i32, ...) {
62; CHECK-LABEL: caller_float_vararg__callee_float:
63; CHECK:       @ %bb.0:
64; CHECK-NEXT:    .save {r7, lr}
65; CHECK-NEXT:    push {r7, lr}
66; CHECK-NEXT:    bl callee_float
67; CHECK-NEXT:    vmov r0, s0
68; CHECK-NEXT:    pop {r7, pc}
69;
70; SOFTFLOAT-LABEL: caller_float_vararg__callee_float:
71; SOFTFLOAT:       @ %bb.0:
72; SOFTFLOAT-NEXT:    b callee_float
73;
74; HF-NOTAIL-LABEL: caller_float_vararg__callee_float:
75; HF-NOTAIL:       @ %bb.0:
76; HF-NOTAIL-NEXT:    .save {r7, lr}
77; HF-NOTAIL-NEXT:    push {r7, lr}
78; HF-NOTAIL-NEXT:    bl callee_float
79; HF-NOTAIL-NEXT:    vmov r0, s0
80; HF-NOTAIL-NEXT:    pop {r7, pc}
81  %r = tail call float @callee_float()
82  ret float %r
83}
84
85define float @caller_float_vararg__callee_float_vararg(i32, ...) {
86; CHECK-LABEL: caller_float_vararg__callee_float_vararg:
87; CHECK:       @ %bb.0:
88; CHECK-NEXT:    movs r0, #0
89; CHECK-NEXT:    b callee_float_vararg
90;
91; SOFTFLOAT-LABEL: caller_float_vararg__callee_float_vararg:
92; SOFTFLOAT:       @ %bb.0:
93; SOFTFLOAT-NEXT:    movs r0, #0
94; SOFTFLOAT-NEXT:    b callee_float_vararg
95;
96; HF-NOTAIL-LABEL: caller_float_vararg__callee_float_vararg:
97; HF-NOTAIL:       @ %bb.0:
98; HF-NOTAIL-NEXT:    .save {r7, lr}
99; HF-NOTAIL-NEXT:    push {r7, lr}
100; HF-NOTAIL-NEXT:    movs r0, #0
101; HF-NOTAIL-NEXT:    bl callee_float_vararg
102; HF-NOTAIL-NEXT:    pop {r7, pc}
103  %r = tail call float (i32, ...) @callee_float_vararg(i32 0)
104  ret float %r
105}
106
107define i32 @caller_int__callee_int() {
108; CHECK-LABEL: caller_int__callee_int:
109; CHECK:       @ %bb.0:
110; CHECK-NEXT:    b callee_int
111;
112; SOFTFLOAT-LABEL: caller_int__callee_int:
113; SOFTFLOAT:       @ %bb.0:
114; SOFTFLOAT-NEXT:    b callee_int
115;
116; HF-NOTAIL-LABEL: caller_int__callee_int:
117; HF-NOTAIL:       @ %bb.0:
118; HF-NOTAIL-NEXT:    .save {r7, lr}
119; HF-NOTAIL-NEXT:    push {r7, lr}
120; HF-NOTAIL-NEXT:    bl callee_int
121; HF-NOTAIL-NEXT:    pop {r7, pc}
122  %r = tail call i32 @callee_int()
123  ret i32 %r
124}
125
126define i32 @caller_int__callee_int_vararg() {
127; CHECK-LABEL: caller_int__callee_int_vararg:
128; CHECK:       @ %bb.0:
129; CHECK-NEXT:    movs r0, #0
130; CHECK-NEXT:    b callee_int_vararg
131;
132; SOFTFLOAT-LABEL: caller_int__callee_int_vararg:
133; SOFTFLOAT:       @ %bb.0:
134; SOFTFLOAT-NEXT:    movs r0, #0
135; SOFTFLOAT-NEXT:    b callee_int_vararg
136;
137; HF-NOTAIL-LABEL: caller_int__callee_int_vararg:
138; HF-NOTAIL:       @ %bb.0:
139; HF-NOTAIL-NEXT:    .save {r7, lr}
140; HF-NOTAIL-NEXT:    push {r7, lr}
141; HF-NOTAIL-NEXT:    movs r0, #0
142; HF-NOTAIL-NEXT:    bl callee_int_vararg
143; HF-NOTAIL-NEXT:    pop {r7, pc}
144  %r = tail call i32 (i32, ...) @callee_int_vararg(i32 0)
145  ret i32 %r
146}
147
148define i32 @caller_int_vararg__callee_int(i32, ...) {
149; CHECK-LABEL: caller_int_vararg__callee_int:
150; CHECK:       @ %bb.0:
151; CHECK-NEXT:    b callee_int
152;
153; SOFTFLOAT-LABEL: caller_int_vararg__callee_int:
154; SOFTFLOAT:       @ %bb.0:
155; SOFTFLOAT-NEXT:    b callee_int
156;
157; HF-NOTAIL-LABEL: caller_int_vararg__callee_int:
158; HF-NOTAIL:       @ %bb.0:
159; HF-NOTAIL-NEXT:    .save {r7, lr}
160; HF-NOTAIL-NEXT:    push {r7, lr}
161; HF-NOTAIL-NEXT:    bl callee_int
162; HF-NOTAIL-NEXT:    pop {r7, pc}
163  %r = tail call i32 @callee_int()
164  ret i32 %r
165}
166
167define i32 @caller_int_vararg__callee_int_vararg(i32, ...) {
168; CHECK-LABEL: caller_int_vararg__callee_int_vararg:
169; CHECK:       @ %bb.0:
170; CHECK-NEXT:    movs r0, #0
171; CHECK-NEXT:    b callee_int_vararg
172;
173; SOFTFLOAT-LABEL: caller_int_vararg__callee_int_vararg:
174; SOFTFLOAT:       @ %bb.0:
175; SOFTFLOAT-NEXT:    movs r0, #0
176; SOFTFLOAT-NEXT:    b callee_int_vararg
177;
178; HF-NOTAIL-LABEL: caller_int_vararg__callee_int_vararg:
179; HF-NOTAIL:       @ %bb.0:
180; HF-NOTAIL-NEXT:    .save {r7, lr}
181; HF-NOTAIL-NEXT:    push {r7, lr}
182; HF-NOTAIL-NEXT:    movs r0, #0
183; HF-NOTAIL-NEXT:    bl callee_int_vararg
184; HF-NOTAIL-NEXT:    pop {r7, pc}
185  %r = tail call i32 (i32, ...) @callee_int_vararg(i32 0)
186  ret i32 %r
187}
188