1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN: | FileCheck -check-prefix=RV32I %s
4 ; RUN: llc -relocation-model=pic -mtriple=riscv32 -verify-machineinstrs < %s \
5 ; RUN: | FileCheck -check-prefix=RV32I-PIC %s
7 declare i32 @external_function(i32)
9 define i32 @test_call_external(i32 %a) nounwind {
10 ; RV32I-LABEL: test_call_external:
12 ; RV32I-NEXT: addi sp, sp, -16
13 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
14 ; RV32I-NEXT: call external_function
15 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
16 ; RV32I-NEXT: addi sp, sp, 16
19 ; RV32I-PIC-LABEL: test_call_external:
21 ; RV32I-PIC-NEXT: addi sp, sp, -16
22 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
23 ; RV32I-PIC-NEXT: call external_function
24 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
25 ; RV32I-PIC-NEXT: addi sp, sp, 16
27 %1 = call i32 @external_function(i32 %a)
31 declare dso_local i32 @dso_local_function(i32)
33 define i32 @test_call_dso_local(i32 %a) nounwind {
34 ; RV32I-LABEL: test_call_dso_local:
36 ; RV32I-NEXT: addi sp, sp, -16
37 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
38 ; RV32I-NEXT: call dso_local_function
39 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
40 ; RV32I-NEXT: addi sp, sp, 16
43 ; RV32I-PIC-LABEL: test_call_dso_local:
45 ; RV32I-PIC-NEXT: addi sp, sp, -16
46 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
47 ; RV32I-PIC-NEXT: call dso_local_function
48 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
49 ; RV32I-PIC-NEXT: addi sp, sp, 16
51 %1 = call i32 @dso_local_function(i32 %a)
55 define i32 @defined_function(i32 %a) nounwind {
56 ; RV32I-LABEL: defined_function:
58 ; RV32I-NEXT: addi a0, a0, 1
61 ; RV32I-PIC-LABEL: defined_function:
63 ; RV32I-PIC-NEXT: addi a0, a0, 1
69 define i32 @test_call_defined(i32 %a) nounwind {
70 ; RV32I-LABEL: test_call_defined:
72 ; RV32I-NEXT: addi sp, sp, -16
73 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
74 ; RV32I-NEXT: call defined_function
75 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
76 ; RV32I-NEXT: addi sp, sp, 16
79 ; RV32I-PIC-LABEL: test_call_defined:
81 ; RV32I-PIC-NEXT: addi sp, sp, -16
82 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
83 ; RV32I-PIC-NEXT: call defined_function
84 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
85 ; RV32I-PIC-NEXT: addi sp, sp, 16
87 %1 = call i32 @defined_function(i32 %a)
91 define i32 @test_call_indirect(ptr %a, i32 %b) nounwind {
92 ; RV32I-LABEL: test_call_indirect:
94 ; RV32I-NEXT: addi sp, sp, -16
95 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
96 ; RV32I-NEXT: mv a2, a0
97 ; RV32I-NEXT: mv a0, a1
99 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
100 ; RV32I-NEXT: addi sp, sp, 16
103 ; RV32I-PIC-LABEL: test_call_indirect:
104 ; RV32I-PIC: # %bb.0:
105 ; RV32I-PIC-NEXT: addi sp, sp, -16
106 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
107 ; RV32I-PIC-NEXT: mv a2, a0
108 ; RV32I-PIC-NEXT: mv a0, a1
109 ; RV32I-PIC-NEXT: jalr a2
110 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
111 ; RV32I-PIC-NEXT: addi sp, sp, 16
112 ; RV32I-PIC-NEXT: ret
113 %1 = call i32 %a(i32 %b)
117 ; Make sure we don't use t0 as the source for jalr as that is a hint to pop the
118 ; return address stack on some microarchitectures.
119 define i32 @test_call_indirect_no_t0(ptr %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h) nounwind {
120 ; RV32I-LABEL: test_call_indirect_no_t0:
122 ; RV32I-NEXT: addi sp, sp, -16
123 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
124 ; RV32I-NEXT: mv t1, a0
125 ; RV32I-NEXT: mv a0, a1
126 ; RV32I-NEXT: mv a1, a2
127 ; RV32I-NEXT: mv a2, a3
128 ; RV32I-NEXT: mv a3, a4
129 ; RV32I-NEXT: mv a4, a5
130 ; RV32I-NEXT: mv a5, a6
131 ; RV32I-NEXT: mv a6, a7
132 ; RV32I-NEXT: jalr t1
133 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
134 ; RV32I-NEXT: addi sp, sp, 16
137 ; RV32I-PIC-LABEL: test_call_indirect_no_t0:
138 ; RV32I-PIC: # %bb.0:
139 ; RV32I-PIC-NEXT: addi sp, sp, -16
140 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
141 ; RV32I-PIC-NEXT: mv t1, a0
142 ; RV32I-PIC-NEXT: mv a0, a1
143 ; RV32I-PIC-NEXT: mv a1, a2
144 ; RV32I-PIC-NEXT: mv a2, a3
145 ; RV32I-PIC-NEXT: mv a3, a4
146 ; RV32I-PIC-NEXT: mv a4, a5
147 ; RV32I-PIC-NEXT: mv a5, a6
148 ; RV32I-PIC-NEXT: mv a6, a7
149 ; RV32I-PIC-NEXT: jalr t1
150 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
151 ; RV32I-PIC-NEXT: addi sp, sp, 16
152 ; RV32I-PIC-NEXT: ret
153 %1 = call i32 %a(i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h)
157 ; Ensure that calls to fastcc functions aren't rejected. Such calls may be
158 ; introduced when compiling with optimisation.
160 define fastcc i32 @fastcc_function(i32 %a, i32 %b) nounwind {
161 ; RV32I-LABEL: fastcc_function:
163 ; RV32I-NEXT: add a0, a0, a1
166 ; RV32I-PIC-LABEL: fastcc_function:
167 ; RV32I-PIC: # %bb.0:
168 ; RV32I-PIC-NEXT: add a0, a0, a1
169 ; RV32I-PIC-NEXT: ret
174 define i32 @test_call_fastcc(i32 %a, i32 %b) nounwind {
175 ; RV32I-LABEL: test_call_fastcc:
177 ; RV32I-NEXT: addi sp, sp, -16
178 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
179 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
180 ; RV32I-NEXT: mv s0, a0
181 ; RV32I-NEXT: call fastcc_function
182 ; RV32I-NEXT: mv a0, s0
183 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
184 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
185 ; RV32I-NEXT: addi sp, sp, 16
188 ; RV32I-PIC-LABEL: test_call_fastcc:
189 ; RV32I-PIC: # %bb.0:
190 ; RV32I-PIC-NEXT: addi sp, sp, -16
191 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
192 ; RV32I-PIC-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
193 ; RV32I-PIC-NEXT: mv s0, a0
194 ; RV32I-PIC-NEXT: call fastcc_function
195 ; RV32I-PIC-NEXT: mv a0, s0
196 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
197 ; RV32I-PIC-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
198 ; RV32I-PIC-NEXT: addi sp, sp, 16
199 ; RV32I-PIC-NEXT: ret
200 %1 = call fastcc i32 @fastcc_function(i32 %a, i32 %b)
204 declare i32 @external_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) nounwind
206 define i32 @test_call_external_many_args(i32 %a) nounwind {
207 ; RV32I-LABEL: test_call_external_many_args:
209 ; RV32I-NEXT: addi sp, sp, -16
210 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
211 ; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
212 ; RV32I-NEXT: mv s0, a0
213 ; RV32I-NEXT: sw a0, 4(sp)
214 ; RV32I-NEXT: sw a0, 0(sp)
215 ; RV32I-NEXT: mv a1, a0
216 ; RV32I-NEXT: mv a2, a0
217 ; RV32I-NEXT: mv a3, a0
218 ; RV32I-NEXT: mv a4, a0
219 ; RV32I-NEXT: mv a5, a0
220 ; RV32I-NEXT: mv a6, a0
221 ; RV32I-NEXT: mv a7, a0
222 ; RV32I-NEXT: call external_many_args
223 ; RV32I-NEXT: mv a0, s0
224 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
225 ; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
226 ; RV32I-NEXT: addi sp, sp, 16
229 ; RV32I-PIC-LABEL: test_call_external_many_args:
230 ; RV32I-PIC: # %bb.0:
231 ; RV32I-PIC-NEXT: addi sp, sp, -16
232 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
233 ; RV32I-PIC-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
234 ; RV32I-PIC-NEXT: mv s0, a0
235 ; RV32I-PIC-NEXT: sw a0, 4(sp)
236 ; RV32I-PIC-NEXT: sw a0, 0(sp)
237 ; RV32I-PIC-NEXT: mv a1, a0
238 ; RV32I-PIC-NEXT: mv a2, a0
239 ; RV32I-PIC-NEXT: mv a3, a0
240 ; RV32I-PIC-NEXT: mv a4, a0
241 ; RV32I-PIC-NEXT: mv a5, a0
242 ; RV32I-PIC-NEXT: mv a6, a0
243 ; RV32I-PIC-NEXT: mv a7, a0
244 ; RV32I-PIC-NEXT: call external_many_args
245 ; RV32I-PIC-NEXT: mv a0, s0
246 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
247 ; RV32I-PIC-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
248 ; RV32I-PIC-NEXT: addi sp, sp, 16
249 ; RV32I-PIC-NEXT: ret
250 %1 = call i32 @external_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
251 i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)
255 define i32 @defined_many_args(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 %j) nounwind {
256 ; RV32I-LABEL: defined_many_args:
258 ; RV32I-NEXT: lw a0, 4(sp)
259 ; RV32I-NEXT: addi a0, a0, 1
262 ; RV32I-PIC-LABEL: defined_many_args:
263 ; RV32I-PIC: # %bb.0:
264 ; RV32I-PIC-NEXT: lw a0, 4(sp)
265 ; RV32I-PIC-NEXT: addi a0, a0, 1
266 ; RV32I-PIC-NEXT: ret
267 %added = add i32 %j, 1
271 define i32 @test_call_defined_many_args(i32 %a) nounwind {
272 ; RV32I-LABEL: test_call_defined_many_args:
274 ; RV32I-NEXT: addi sp, sp, -16
275 ; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
276 ; RV32I-NEXT: sw a0, 4(sp)
277 ; RV32I-NEXT: sw a0, 0(sp)
278 ; RV32I-NEXT: mv a1, a0
279 ; RV32I-NEXT: mv a2, a0
280 ; RV32I-NEXT: mv a3, a0
281 ; RV32I-NEXT: mv a4, a0
282 ; RV32I-NEXT: mv a5, a0
283 ; RV32I-NEXT: mv a6, a0
284 ; RV32I-NEXT: mv a7, a0
285 ; RV32I-NEXT: call defined_many_args
286 ; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
287 ; RV32I-NEXT: addi sp, sp, 16
290 ; RV32I-PIC-LABEL: test_call_defined_many_args:
291 ; RV32I-PIC: # %bb.0:
292 ; RV32I-PIC-NEXT: addi sp, sp, -16
293 ; RV32I-PIC-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
294 ; RV32I-PIC-NEXT: sw a0, 4(sp)
295 ; RV32I-PIC-NEXT: sw a0, 0(sp)
296 ; RV32I-PIC-NEXT: mv a1, a0
297 ; RV32I-PIC-NEXT: mv a2, a0
298 ; RV32I-PIC-NEXT: mv a3, a0
299 ; RV32I-PIC-NEXT: mv a4, a0
300 ; RV32I-PIC-NEXT: mv a5, a0
301 ; RV32I-PIC-NEXT: mv a6, a0
302 ; RV32I-PIC-NEXT: mv a7, a0
303 ; RV32I-PIC-NEXT: call defined_many_args
304 ; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
305 ; RV32I-PIC-NEXT: addi sp, sp, 16
306 ; RV32I-PIC-NEXT: ret
307 %1 = call i32 @defined_many_args(i32 %a, i32 %a, i32 %a, i32 %a, i32 %a,
308 i32 %a, i32 %a, i32 %a, i32 %a, i32 %a)