• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
6
7; As well as calling convention details, we check that ra and fp are
8; consistently stored to fp-8 and fp-16.
9
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.
14
15; TODO: softened float values can be passed anyext.
16
17define 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
31;
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
51}
52
53define 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
64;
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
80}
81
82define 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
87;
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
104}
105
106define 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
125;
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
149}
150
151define 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
156;
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
169}
170
171; The sign extension of the float return is necessary, as softened floats are
172; passed anyext.
173
174define 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
184;
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
201}
202