[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / RISCV / calling-conv-lp64.ll
blob3135fcd162d140d5305a531f9b5f11ea9426e025
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefix=RV64I-FPELIM %s
4 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs -frame-pointer=all < %s \
5 ; RUN:   | FileCheck -check-prefix=RV64I-WITHFP %s
7 ; As well as calling convention details, we check that ra and fp are
8 ; consistently stored to fp-8 and fp-16.
10 ; Any tests that would have identical output for some combination of the lp64*
11 ; ABIs belong in calling-conv-*-common.ll. This file contains tests that will
12 ; have different output across those ABIs. i.e. where some arguments would be
13 ; passed according to the floating point ABI.
15 ; TODO: softened float values can be passed anyext.
17 define i64 @callee_float_in_regs(i64 %a, float %b) nounwind {
18 ; RV64I-FPELIM-LABEL: callee_float_in_regs:
19 ; RV64I-FPELIM:       # %bb.0:
20 ; RV64I-FPELIM-NEXT:    addi sp, sp, -16
21 ; RV64I-FPELIM-NEXT:    sd ra, 8(sp)
22 ; RV64I-FPELIM-NEXT:    sd s0, 0(sp)
23 ; RV64I-FPELIM-NEXT:    mv s0, a0
24 ; RV64I-FPELIM-NEXT:    mv a0, a1
25 ; RV64I-FPELIM-NEXT:    call __fixsfdi
26 ; RV64I-FPELIM-NEXT:    add a0, s0, a0
27 ; RV64I-FPELIM-NEXT:    ld s0, 0(sp)
28 ; RV64I-FPELIM-NEXT:    ld ra, 8(sp)
29 ; RV64I-FPELIM-NEXT:    addi sp, sp, 16
30 ; RV64I-FPELIM-NEXT:    ret
32 ; RV64I-WITHFP-LABEL: callee_float_in_regs:
33 ; RV64I-WITHFP:       # %bb.0:
34 ; RV64I-WITHFP-NEXT:    addi sp, sp, -32
35 ; RV64I-WITHFP-NEXT:    sd ra, 24(sp)
36 ; RV64I-WITHFP-NEXT:    sd s0, 16(sp)
37 ; RV64I-WITHFP-NEXT:    sd s1, 8(sp)
38 ; RV64I-WITHFP-NEXT:    addi s0, sp, 32
39 ; RV64I-WITHFP-NEXT:    mv s1, a0
40 ; RV64I-WITHFP-NEXT:    mv a0, a1
41 ; RV64I-WITHFP-NEXT:    call __fixsfdi
42 ; RV64I-WITHFP-NEXT:    add a0, s1, a0
43 ; RV64I-WITHFP-NEXT:    ld s1, 8(sp)
44 ; RV64I-WITHFP-NEXT:    ld s0, 16(sp)
45 ; RV64I-WITHFP-NEXT:    ld ra, 24(sp)
46 ; RV64I-WITHFP-NEXT:    addi sp, sp, 32
47 ; RV64I-WITHFP-NEXT:    ret
48   %b_fptosi = fptosi float %b to i64
49   %1 = add i64 %a, %b_fptosi
50   ret i64 %1
53 define i64 @caller_float_in_regs() nounwind {
54 ; RV64I-FPELIM-LABEL: caller_float_in_regs:
55 ; RV64I-FPELIM:       # %bb.0:
56 ; RV64I-FPELIM-NEXT:    addi sp, sp, -16
57 ; RV64I-FPELIM-NEXT:    sd ra, 8(sp)
58 ; RV64I-FPELIM-NEXT:    addi a0, zero, 1
59 ; RV64I-FPELIM-NEXT:    lui a1, 262144
60 ; RV64I-FPELIM-NEXT:    call callee_float_in_regs
61 ; RV64I-FPELIM-NEXT:    ld ra, 8(sp)
62 ; RV64I-FPELIM-NEXT:    addi sp, sp, 16
63 ; RV64I-FPELIM-NEXT:    ret
65 ; RV64I-WITHFP-LABEL: caller_float_in_regs:
66 ; RV64I-WITHFP:       # %bb.0:
67 ; RV64I-WITHFP-NEXT:    addi sp, sp, -16
68 ; RV64I-WITHFP-NEXT:    sd ra, 8(sp)
69 ; RV64I-WITHFP-NEXT:    sd s0, 0(sp)
70 ; RV64I-WITHFP-NEXT:    addi s0, sp, 16
71 ; RV64I-WITHFP-NEXT:    addi a0, zero, 1
72 ; RV64I-WITHFP-NEXT:    lui a1, 262144
73 ; RV64I-WITHFP-NEXT:    call callee_float_in_regs
74 ; RV64I-WITHFP-NEXT:    ld s0, 0(sp)
75 ; RV64I-WITHFP-NEXT:    ld ra, 8(sp)
76 ; RV64I-WITHFP-NEXT:    addi sp, sp, 16
77 ; RV64I-WITHFP-NEXT:    ret
78   %1 = call i64 @callee_float_in_regs(i64 1, float 2.0)
79   ret i64 %1
82 define i64 @callee_float_on_stack(i128 %a, i128 %b, i128 %c, i128 %d, float %e) nounwind {
83 ; RV64I-FPELIM-LABEL: callee_float_on_stack:
84 ; RV64I-FPELIM:       # %bb.0:
85 ; RV64I-FPELIM-NEXT:    lw a0, 0(sp)
86 ; RV64I-FPELIM-NEXT:    ret
88 ; RV64I-WITHFP-LABEL: callee_float_on_stack:
89 ; RV64I-WITHFP:       # %bb.0:
90 ; RV64I-WITHFP-NEXT:    addi sp, sp, -16
91 ; RV64I-WITHFP-NEXT:    sd ra, 8(sp)
92 ; RV64I-WITHFP-NEXT:    sd s0, 0(sp)
93 ; RV64I-WITHFP-NEXT:    addi s0, sp, 16
94 ; RV64I-WITHFP-NEXT:    lw a0, 0(s0)
95 ; RV64I-WITHFP-NEXT:    ld s0, 0(sp)
96 ; RV64I-WITHFP-NEXT:    ld ra, 8(sp)
97 ; RV64I-WITHFP-NEXT:    addi sp, sp, 16
98 ; RV64I-WITHFP-NEXT:    ret
99   %1 = trunc i128 %d to i64
100   %2 = bitcast float %e to i32
101   %3 = sext i32 %2 to i64
102   %4 = add i64 %1, %3
103   ret i64 %3
106 define i64 @caller_float_on_stack() nounwind {
107 ; RV64I-FPELIM-LABEL: caller_float_on_stack:
108 ; RV64I-FPELIM:       # %bb.0:
109 ; RV64I-FPELIM-NEXT:    addi sp, sp, -16
110 ; RV64I-FPELIM-NEXT:    sd ra, 8(sp)
111 ; RV64I-FPELIM-NEXT:    lui a1, 264704
112 ; RV64I-FPELIM-NEXT:    addi a0, zero, 1
113 ; RV64I-FPELIM-NEXT:    addi a2, zero, 2
114 ; RV64I-FPELIM-NEXT:    addi a4, zero, 3
115 ; RV64I-FPELIM-NEXT:    addi a6, zero, 4
116 ; RV64I-FPELIM-NEXT:    sd a1, 0(sp)
117 ; RV64I-FPELIM-NEXT:    mv a1, zero
118 ; RV64I-FPELIM-NEXT:    mv a3, zero
119 ; RV64I-FPELIM-NEXT:    mv a5, zero
120 ; RV64I-FPELIM-NEXT:    mv a7, zero
121 ; RV64I-FPELIM-NEXT:    call callee_float_on_stack
122 ; RV64I-FPELIM-NEXT:    ld ra, 8(sp)
123 ; RV64I-FPELIM-NEXT:    addi sp, sp, 16
124 ; RV64I-FPELIM-NEXT:    ret
126 ; RV64I-WITHFP-LABEL: caller_float_on_stack:
127 ; RV64I-WITHFP:       # %bb.0:
128 ; RV64I-WITHFP-NEXT:    addi sp, sp, -32
129 ; RV64I-WITHFP-NEXT:    sd ra, 24(sp)
130 ; RV64I-WITHFP-NEXT:    sd s0, 16(sp)
131 ; RV64I-WITHFP-NEXT:    addi s0, sp, 32
132 ; RV64I-WITHFP-NEXT:    lui a1, 264704
133 ; RV64I-WITHFP-NEXT:    addi a0, zero, 1
134 ; RV64I-WITHFP-NEXT:    addi a2, zero, 2
135 ; RV64I-WITHFP-NEXT:    addi a4, zero, 3
136 ; RV64I-WITHFP-NEXT:    addi a6, zero, 4
137 ; RV64I-WITHFP-NEXT:    sd a1, 0(sp)
138 ; RV64I-WITHFP-NEXT:    mv a1, zero
139 ; RV64I-WITHFP-NEXT:    mv a3, zero
140 ; RV64I-WITHFP-NEXT:    mv a5, zero
141 ; RV64I-WITHFP-NEXT:    mv a7, zero
142 ; RV64I-WITHFP-NEXT:    call callee_float_on_stack
143 ; RV64I-WITHFP-NEXT:    ld s0, 16(sp)
144 ; RV64I-WITHFP-NEXT:    ld ra, 24(sp)
145 ; RV64I-WITHFP-NEXT:    addi sp, sp, 32
146 ; RV64I-WITHFP-NEXT:    ret
147   %1 = call i64 @callee_float_on_stack(i128 1, i128 2, i128 3, i128 4, float 5.0)
148   ret i64 %1
151 define float @callee_tiny_scalar_ret() nounwind {
152 ; RV64I-FPELIM-LABEL: callee_tiny_scalar_ret:
153 ; RV64I-FPELIM:       # %bb.0:
154 ; RV64I-FPELIM-NEXT:    lui a0, 260096
155 ; RV64I-FPELIM-NEXT:    ret
157 ; RV64I-WITHFP-LABEL: callee_tiny_scalar_ret:
158 ; RV64I-WITHFP:       # %bb.0:
159 ; RV64I-WITHFP-NEXT:    addi sp, sp, -16
160 ; RV64I-WITHFP-NEXT:    sd ra, 8(sp)
161 ; RV64I-WITHFP-NEXT:    sd s0, 0(sp)
162 ; RV64I-WITHFP-NEXT:    addi s0, sp, 16
163 ; RV64I-WITHFP-NEXT:    lui a0, 260096
164 ; RV64I-WITHFP-NEXT:    ld s0, 0(sp)
165 ; RV64I-WITHFP-NEXT:    ld ra, 8(sp)
166 ; RV64I-WITHFP-NEXT:    addi sp, sp, 16
167 ; RV64I-WITHFP-NEXT:    ret
168   ret float 1.0
171 ; The sign extension of the float return is necessary, as softened floats are
172 ; passed anyext.
174 define i64 @caller_tiny_scalar_ret() nounwind {
175 ; RV64I-FPELIM-LABEL: caller_tiny_scalar_ret:
176 ; RV64I-FPELIM:       # %bb.0:
177 ; RV64I-FPELIM-NEXT:    addi sp, sp, -16
178 ; RV64I-FPELIM-NEXT:    sd ra, 8(sp)
179 ; RV64I-FPELIM-NEXT:    call callee_tiny_scalar_ret
180 ; RV64I-FPELIM-NEXT:    sext.w a0, a0
181 ; RV64I-FPELIM-NEXT:    ld ra, 8(sp)
182 ; RV64I-FPELIM-NEXT:    addi sp, sp, 16
183 ; RV64I-FPELIM-NEXT:    ret
185 ; RV64I-WITHFP-LABEL: caller_tiny_scalar_ret:
186 ; RV64I-WITHFP:       # %bb.0:
187 ; RV64I-WITHFP-NEXT:    addi sp, sp, -16
188 ; RV64I-WITHFP-NEXT:    sd ra, 8(sp)
189 ; RV64I-WITHFP-NEXT:    sd s0, 0(sp)
190 ; RV64I-WITHFP-NEXT:    addi s0, sp, 16
191 ; RV64I-WITHFP-NEXT:    call callee_tiny_scalar_ret
192 ; RV64I-WITHFP-NEXT:    sext.w a0, a0
193 ; RV64I-WITHFP-NEXT:    ld s0, 0(sp)
194 ; RV64I-WITHFP-NEXT:    ld ra, 8(sp)
195 ; RV64I-WITHFP-NEXT:    addi sp, sp, 16
196 ; RV64I-WITHFP-NEXT:    ret
197   %1 = call float @callee_tiny_scalar_ret()
198   %2 = bitcast float %1 to i32
199   %3 = sext i32 %2 to i64
200   ret i64 %3