[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / RISCV / calling-conv-ilp32d.ll
blob5ad002f5c423f9ee4f7a8115abcdf50c6d699cfc
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs -mattr=+d \
3 ; RUN:     -target-abi ilp32d < %s \
4 ; RUN:   | FileCheck -check-prefix=RV32-ILP32D %s
6 ; This file contains tests that will have differing output for the ilp32 and
7 ; ilp32f ABIs.
9 define i32 @callee_double_in_fpr(i32 %a, double %b) nounwind {
10 ; RV32-ILP32D-LABEL: callee_double_in_fpr:
11 ; RV32-ILP32D:       # %bb.0:
12 ; RV32-ILP32D-NEXT:    fcvt.w.d a1, fa0, rtz
13 ; RV32-ILP32D-NEXT:    add a0, a0, a1
14 ; RV32-ILP32D-NEXT:    ret
15   %b_fptosi = fptosi double %b to i32
16   %1 = add i32 %a, %b_fptosi
17   ret i32 %1
20 define i32 @caller_double_in_fpr() nounwind {
21 ; RV32-ILP32D-LABEL: caller_double_in_fpr:
22 ; RV32-ILP32D:       # %bb.0:
23 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
24 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
25 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI1_0)
26 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI1_0)
27 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
28 ; RV32-ILP32D-NEXT:    addi a0, zero, 1
29 ; RV32-ILP32D-NEXT:    call callee_double_in_fpr
30 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
31 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
32 ; RV32-ILP32D-NEXT:    ret
33   %1 = call i32 @callee_double_in_fpr(i32 1, double 2.0)
34   ret i32 %1
37 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
38 define i32 @callee_double_in_fpr_exhausted_gprs(i64 %a, i64 %b, i64 %c, i64 %d, i32 %e, double %f) nounwind {
39 ; RV32-ILP32D-LABEL: callee_double_in_fpr_exhausted_gprs:
40 ; RV32-ILP32D:       # %bb.0:
41 ; RV32-ILP32D-NEXT:    lw a0, 0(sp)
42 ; RV32-ILP32D-NEXT:    fcvt.w.d a1, fa0, rtz
43 ; RV32-ILP32D-NEXT:    add a0, a0, a1
44 ; RV32-ILP32D-NEXT:    ret
45   %f_fptosi = fptosi double %f to i32
46   %1 = add i32 %e, %f_fptosi
47   ret i32 %1
50 define i32 @caller_double_in_fpr_exhausted_gprs() nounwind {
51 ; RV32-ILP32D-LABEL: caller_double_in_fpr_exhausted_gprs:
52 ; RV32-ILP32D:       # %bb.0:
53 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
54 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
55 ; RV32-ILP32D-NEXT:    addi a1, zero, 5
56 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI3_0)
57 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI3_0)
58 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
59 ; RV32-ILP32D-NEXT:    addi a0, zero, 1
60 ; RV32-ILP32D-NEXT:    addi a2, zero, 2
61 ; RV32-ILP32D-NEXT:    addi a4, zero, 3
62 ; RV32-ILP32D-NEXT:    addi a6, zero, 4
63 ; RV32-ILP32D-NEXT:    sw a1, 0(sp)
64 ; RV32-ILP32D-NEXT:    mv a1, zero
65 ; RV32-ILP32D-NEXT:    mv a3, zero
66 ; RV32-ILP32D-NEXT:    mv a5, zero
67 ; RV32-ILP32D-NEXT:    mv a7, zero
68 ; RV32-ILP32D-NEXT:    call callee_double_in_fpr_exhausted_gprs
69 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
70 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
71 ; RV32-ILP32D-NEXT:    ret
72   %1 = call i32 @callee_double_in_fpr_exhausted_gprs(
73       i64 1, i64 2, i64 3, i64 4, i32 5, double 6.0)
74   ret i32 %1
77 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
78 define i32 @callee_double_in_gpr_exhausted_fprs(double %a, double %b, double %c, double %d, double %e, double %f, double %g, double %h, double %i) nounwind {
79 ; RV32-ILP32D-LABEL: callee_double_in_gpr_exhausted_fprs:
80 ; RV32-ILP32D:       # %bb.0:
81 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
82 ; RV32-ILP32D-NEXT:    sw a0, 8(sp)
83 ; RV32-ILP32D-NEXT:    sw a1, 12(sp)
84 ; RV32-ILP32D-NEXT:    fld ft0, 8(sp)
85 ; RV32-ILP32D-NEXT:    fcvt.w.d a0, fa7, rtz
86 ; RV32-ILP32D-NEXT:    fcvt.w.d a1, ft0, rtz
87 ; RV32-ILP32D-NEXT:    add a0, a0, a1
88 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
89 ; RV32-ILP32D-NEXT:    ret
90   %h_fptosi = fptosi double %h to i32
91   %i_fptosi = fptosi double %i to i32
92   %1 = add i32 %h_fptosi, %i_fptosi
93   ret i32 %1
96 define i32 @caller_double_in_gpr_exhausted_fprs() nounwind {
97 ; RV32-ILP32D-LABEL: caller_double_in_gpr_exhausted_fprs:
98 ; RV32-ILP32D:       # %bb.0:
99 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
100 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
101 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_0)
102 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_0)
103 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
104 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_1)
105 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_1)
106 ; RV32-ILP32D-NEXT:    fld fa1, 0(a0)
107 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_2)
108 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_2)
109 ; RV32-ILP32D-NEXT:    fld fa2, 0(a0)
110 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_3)
111 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_3)
112 ; RV32-ILP32D-NEXT:    fld fa3, 0(a0)
113 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_4)
114 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_4)
115 ; RV32-ILP32D-NEXT:    fld fa4, 0(a0)
116 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_5)
117 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_5)
118 ; RV32-ILP32D-NEXT:    fld fa5, 0(a0)
119 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_6)
120 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_6)
121 ; RV32-ILP32D-NEXT:    fld fa6, 0(a0)
122 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI5_7)
123 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI5_7)
124 ; RV32-ILP32D-NEXT:    fld fa7, 0(a0)
125 ; RV32-ILP32D-NEXT:    lui a1, 262688
126 ; RV32-ILP32D-NEXT:    mv a0, zero
127 ; RV32-ILP32D-NEXT:    call callee_double_in_gpr_exhausted_fprs
128 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
129 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
130 ; RV32-ILP32D-NEXT:    ret
131   %1 = call i32 @callee_double_in_gpr_exhausted_fprs(
132       double 1.0, double 2.0, double 3.0, double 4.0, double 5.0, double 6.0,
133       double 7.0, double 8.0, double 9.0)
134   ret i32 %1
137 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
138 define i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i32 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
139 ; RV32-ILP32D-LABEL: callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
140 ; RV32-ILP32D:       # %bb.0:
141 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
142 ; RV32-ILP32D-NEXT:    lw a0, 16(sp)
143 ; RV32-ILP32D-NEXT:    sw a7, 8(sp)
144 ; RV32-ILP32D-NEXT:    sw a0, 12(sp)
145 ; RV32-ILP32D-NEXT:    fld ft0, 8(sp)
146 ; RV32-ILP32D-NEXT:    fcvt.w.d a0, ft0, rtz
147 ; RV32-ILP32D-NEXT:    add a0, a6, a0
148 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
149 ; RV32-ILP32D-NEXT:    ret
150   %m_fptosi = fptosi double %m to i32
151   %1 = add i32 %g, %m_fptosi
152   ret i32 %1
155 define i32 @caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs() nounwind {
156 ; RV32-ILP32D-LABEL: caller_double_in_gpr_and_stack_almost_exhausted_gprs_fprs:
157 ; RV32-ILP32D:       # %bb.0:
158 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
159 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
160 ; RV32-ILP32D-NEXT:    lui a1, 262816
161 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_0)
162 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_0)
163 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
164 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_1)
165 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_1)
166 ; RV32-ILP32D-NEXT:    fld fa1, 0(a0)
167 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_2)
168 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_2)
169 ; RV32-ILP32D-NEXT:    fld fa2, 0(a0)
170 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_3)
171 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_3)
172 ; RV32-ILP32D-NEXT:    fld fa3, 0(a0)
173 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_4)
174 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_4)
175 ; RV32-ILP32D-NEXT:    fld fa4, 0(a0)
176 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_5)
177 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_5)
178 ; RV32-ILP32D-NEXT:    fld fa5, 0(a0)
179 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_6)
180 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_6)
181 ; RV32-ILP32D-NEXT:    fld fa6, 0(a0)
182 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI7_7)
183 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI7_7)
184 ; RV32-ILP32D-NEXT:    fld fa7, 0(a0)
185 ; RV32-ILP32D-NEXT:    addi a0, zero, 1
186 ; RV32-ILP32D-NEXT:    addi a2, zero, 3
187 ; RV32-ILP32D-NEXT:    addi a4, zero, 5
188 ; RV32-ILP32D-NEXT:    addi a6, zero, 7
189 ; RV32-ILP32D-NEXT:    sw a1, 0(sp)
190 ; RV32-ILP32D-NEXT:    mv a1, zero
191 ; RV32-ILP32D-NEXT:    mv a3, zero
192 ; RV32-ILP32D-NEXT:    mv a5, zero
193 ; RV32-ILP32D-NEXT:    mv a7, zero
194 ; RV32-ILP32D-NEXT:    call callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs
195 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
196 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
197 ; RV32-ILP32D-NEXT:    ret
198   %1 = call i32 @callee_double_in_gpr_and_stack_almost_exhausted_gprs_fprs(
199       i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i32 7, double 8.0,
200       double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
201   ret i32 %1
205 ; Must keep define on a single line due to an update_llc_test_checks.py limitation
206 define i32 @callee_double_on_stack_exhausted_gprs_fprs(i64 %a, double %b, i64 %c, double %d, i64 %e, double %f, i64 %g, double %h, double %i, double %j, double %k, double %l, double %m) nounwind {
207 ; RV32-ILP32D-LABEL: callee_double_on_stack_exhausted_gprs_fprs:
208 ; RV32-ILP32D:       # %bb.0:
209 ; RV32-ILP32D-NEXT:    fld ft0, 0(sp)
210 ; RV32-ILP32D-NEXT:    fcvt.w.d a0, ft0, rtz
211 ; RV32-ILP32D-NEXT:    add a0, a6, a0
212 ; RV32-ILP32D-NEXT:    ret
213   %g_trunc = trunc i64 %g to i32
214   %m_fptosi = fptosi double %m to i32
215   %1 = add i32 %g_trunc, %m_fptosi
216   ret i32 %1
219 define i32 @caller_double_on_stack_exhausted_gprs_fprs() nounwind {
220 ; RV32-ILP32D-LABEL: caller_double_on_stack_exhausted_gprs_fprs:
221 ; RV32-ILP32D:       # %bb.0:
222 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
223 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
224 ; RV32-ILP32D-NEXT:    lui a0, 262816
225 ; RV32-ILP32D-NEXT:    sw a0, 4(sp)
226 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_0)
227 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_0)
228 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
229 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_1)
230 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_1)
231 ; RV32-ILP32D-NEXT:    fld fa1, 0(a0)
232 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_2)
233 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_2)
234 ; RV32-ILP32D-NEXT:    fld fa2, 0(a0)
235 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_3)
236 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_3)
237 ; RV32-ILP32D-NEXT:    fld fa3, 0(a0)
238 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_4)
239 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_4)
240 ; RV32-ILP32D-NEXT:    fld fa4, 0(a0)
241 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_5)
242 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_5)
243 ; RV32-ILP32D-NEXT:    fld fa5, 0(a0)
244 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_6)
245 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_6)
246 ; RV32-ILP32D-NEXT:    fld fa6, 0(a0)
247 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI9_7)
248 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI9_7)
249 ; RV32-ILP32D-NEXT:    fld fa7, 0(a0)
250 ; RV32-ILP32D-NEXT:    addi a0, zero, 1
251 ; RV32-ILP32D-NEXT:    addi a2, zero, 3
252 ; RV32-ILP32D-NEXT:    addi a4, zero, 5
253 ; RV32-ILP32D-NEXT:    addi a6, zero, 7
254 ; RV32-ILP32D-NEXT:    sw zero, 0(sp)
255 ; RV32-ILP32D-NEXT:    mv a1, zero
256 ; RV32-ILP32D-NEXT:    mv a3, zero
257 ; RV32-ILP32D-NEXT:    mv a5, zero
258 ; RV32-ILP32D-NEXT:    mv a7, zero
259 ; RV32-ILP32D-NEXT:    call callee_double_on_stack_exhausted_gprs_fprs
260 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
261 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
262 ; RV32-ILP32D-NEXT:    ret
263   %1 = call i32 @callee_double_on_stack_exhausted_gprs_fprs(
264       i64 1, double 2.0, i64 3, double 4.0, i64 5, double 6.0, i64 7, double 8.0,
265       double 9.0, double 10.0, double 11.0, double 12.0, double 13.0)
266   ret i32 %1
269 define double @callee_double_ret() nounwind {
270 ; RV32-ILP32D-LABEL: callee_double_ret:
271 ; RV32-ILP32D:       # %bb.0:
272 ; RV32-ILP32D-NEXT:    lui a0, %hi(.LCPI10_0)
273 ; RV32-ILP32D-NEXT:    addi a0, a0, %lo(.LCPI10_0)
274 ; RV32-ILP32D-NEXT:    fld fa0, 0(a0)
275 ; RV32-ILP32D-NEXT:    ret
276   ret double 1.0
279 define i32 @caller_double_ret() nounwind {
280 ; RV32-ILP32D-LABEL: caller_double_ret:
281 ; RV32-ILP32D:       # %bb.0:
282 ; RV32-ILP32D-NEXT:    addi sp, sp, -16
283 ; RV32-ILP32D-NEXT:    sw ra, 12(sp)
284 ; RV32-ILP32D-NEXT:    call callee_double_ret
285 ; RV32-ILP32D-NEXT:    fsd fa0, 0(sp)
286 ; RV32-ILP32D-NEXT:    lw a0, 0(sp)
287 ; RV32-ILP32D-NEXT:    lw ra, 12(sp)
288 ; RV32-ILP32D-NEXT:    addi sp, sp, 16
289 ; RV32-ILP32D-NEXT:    ret
290   %1 = call double @callee_double_ret()
291   %2 = bitcast double %1 to i64
292   %3 = trunc i64 %2 to i32
293   ret i32 %3