xref: /llvm-project/llvm/test/CodeGen/RISCV/rv64-half-convert.ll (revision 73186546f0c0209c65c4b4ef1379a4832545b871)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv64 -verify-machineinstrs \
3; RUN:   -target-abi lp64 < %s | FileCheck %s -check-prefixes=CHECK,RV64I
4; RUN: llc -mtriple=riscv64 -mattr=+zfh -verify-machineinstrs \
5; RUN:   -target-abi lp64f < %s | FileCheck %s -check-prefixes=CHECK,RV64IZFH
6; RUN: llc -mtriple=riscv64 -mattr=+zhinx -verify-machineinstrs \
7; RUN:   -target-abi lp64 < %s | FileCheck %s -check-prefixes=CHECK,RV64IZHINX
8
9define half @sitofp_i128_to_f16(i128 %a) nounwind {
10; RV64I-LABEL: sitofp_i128_to_f16:
11; RV64I:       # %bb.0:
12; RV64I-NEXT:    addi sp, sp, -16
13; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
14; RV64I-NEXT:    call __floattisf
15; RV64I-NEXT:    call __truncsfhf2
16; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
17; RV64I-NEXT:    addi sp, sp, 16
18; RV64I-NEXT:    ret
19;
20; RV64IZFH-LABEL: sitofp_i128_to_f16:
21; RV64IZFH:       # %bb.0:
22; RV64IZFH-NEXT:    addi sp, sp, -16
23; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
24; RV64IZFH-NEXT:    call __floattihf
25; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
26; RV64IZFH-NEXT:    addi sp, sp, 16
27; RV64IZFH-NEXT:    ret
28;
29; RV64IZHINX-LABEL: sitofp_i128_to_f16:
30; RV64IZHINX:       # %bb.0:
31; RV64IZHINX-NEXT:    addi sp, sp, -16
32; RV64IZHINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
33; RV64IZHINX-NEXT:    call __floattihf
34; RV64IZHINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
35; RV64IZHINX-NEXT:    addi sp, sp, 16
36; RV64IZHINX-NEXT:    ret
37  %1 = sitofp i128 %a to half
38  ret half %1
39}
40
41define half @uitofp_i128_to_f16(i128 %a) nounwind {
42; RV64I-LABEL: uitofp_i128_to_f16:
43; RV64I:       # %bb.0:
44; RV64I-NEXT:    addi sp, sp, -16
45; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
46; RV64I-NEXT:    call __floatuntisf
47; RV64I-NEXT:    call __truncsfhf2
48; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
49; RV64I-NEXT:    addi sp, sp, 16
50; RV64I-NEXT:    ret
51;
52; RV64IZFH-LABEL: uitofp_i128_to_f16:
53; RV64IZFH:       # %bb.0:
54; RV64IZFH-NEXT:    addi sp, sp, -16
55; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
56; RV64IZFH-NEXT:    call __floatuntihf
57; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
58; RV64IZFH-NEXT:    addi sp, sp, 16
59; RV64IZFH-NEXT:    ret
60;
61; RV64IZHINX-LABEL: uitofp_i128_to_f16:
62; RV64IZHINX:       # %bb.0:
63; RV64IZHINX-NEXT:    addi sp, sp, -16
64; RV64IZHINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
65; RV64IZHINX-NEXT:    call __floatuntihf
66; RV64IZHINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
67; RV64IZHINX-NEXT:    addi sp, sp, 16
68; RV64IZHINX-NEXT:    ret
69  %1 = uitofp i128 %a to half
70  ret half %1
71}
72
73define i128 @fptosi_f16_to_i128(half %a) nounwind {
74; RV64I-LABEL: fptosi_f16_to_i128:
75; RV64I:       # %bb.0:
76; RV64I-NEXT:    addi sp, sp, -16
77; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
78; RV64I-NEXT:    call __extendhfsf2
79; RV64I-NEXT:    call __fixsfti
80; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
81; RV64I-NEXT:    addi sp, sp, 16
82; RV64I-NEXT:    ret
83;
84; RV64IZFH-LABEL: fptosi_f16_to_i128:
85; RV64IZFH:       # %bb.0:
86; RV64IZFH-NEXT:    addi sp, sp, -16
87; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
88; RV64IZFH-NEXT:    call __fixhfti
89; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
90; RV64IZFH-NEXT:    addi sp, sp, 16
91; RV64IZFH-NEXT:    ret
92;
93; RV64IZHINX-LABEL: fptosi_f16_to_i128:
94; RV64IZHINX:       # %bb.0:
95; RV64IZHINX-NEXT:    addi sp, sp, -16
96; RV64IZHINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
97; RV64IZHINX-NEXT:    call __fixhfti
98; RV64IZHINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
99; RV64IZHINX-NEXT:    addi sp, sp, 16
100; RV64IZHINX-NEXT:    ret
101  %1 = fptosi half %a to i128
102  ret i128 %1
103}
104
105define i128 @fptoui_f16_to_i128(half %a) nounwind {
106; RV64I-LABEL: fptoui_f16_to_i128:
107; RV64I:       # %bb.0:
108; RV64I-NEXT:    addi sp, sp, -16
109; RV64I-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
110; RV64I-NEXT:    call __extendhfsf2
111; RV64I-NEXT:    call __fixunssfti
112; RV64I-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
113; RV64I-NEXT:    addi sp, sp, 16
114; RV64I-NEXT:    ret
115;
116; RV64IZFH-LABEL: fptoui_f16_to_i128:
117; RV64IZFH:       # %bb.0:
118; RV64IZFH-NEXT:    addi sp, sp, -16
119; RV64IZFH-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
120; RV64IZFH-NEXT:    call __fixunshfti
121; RV64IZFH-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
122; RV64IZFH-NEXT:    addi sp, sp, 16
123; RV64IZFH-NEXT:    ret
124;
125; RV64IZHINX-LABEL: fptoui_f16_to_i128:
126; RV64IZHINX:       # %bb.0:
127; RV64IZHINX-NEXT:    addi sp, sp, -16
128; RV64IZHINX-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
129; RV64IZHINX-NEXT:    call __fixunshfti
130; RV64IZHINX-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
131; RV64IZHINX-NEXT:    addi sp, sp, 16
132; RV64IZHINX-NEXT:    ret
133  %1 = fptoui half %a to i128
134  ret i128 %1
135}
136
137define i128 @fptosi_sat_f16_to_i128(half %a) nounwind {
138; RV64I-LABEL: fptosi_sat_f16_to_i128:
139; RV64I:       # %bb.0:
140; RV64I-NEXT:    addi sp, sp, -64
141; RV64I-NEXT:    sd ra, 56(sp) # 8-byte Folded Spill
142; RV64I-NEXT:    sd s0, 48(sp) # 8-byte Folded Spill
143; RV64I-NEXT:    sd s1, 40(sp) # 8-byte Folded Spill
144; RV64I-NEXT:    sd s2, 32(sp) # 8-byte Folded Spill
145; RV64I-NEXT:    sd s3, 24(sp) # 8-byte Folded Spill
146; RV64I-NEXT:    sd s4, 16(sp) # 8-byte Folded Spill
147; RV64I-NEXT:    sd s5, 8(sp) # 8-byte Folded Spill
148; RV64I-NEXT:    call __extendhfsf2
149; RV64I-NEXT:    mv s2, a0
150; RV64I-NEXT:    lui a1, 1044480
151; RV64I-NEXT:    call __gesf2
152; RV64I-NEXT:    mv s0, a0
153; RV64I-NEXT:    mv a0, s2
154; RV64I-NEXT:    call __fixsfti
155; RV64I-NEXT:    mv s1, a0
156; RV64I-NEXT:    mv s3, a1
157; RV64I-NEXT:    li s5, -1
158; RV64I-NEXT:    bgez s0, .LBB4_2
159; RV64I-NEXT:  # %bb.1:
160; RV64I-NEXT:    slli s3, s5, 63
161; RV64I-NEXT:  .LBB4_2:
162; RV64I-NEXT:    lui a1, 520192
163; RV64I-NEXT:    addiw a1, a1, -1
164; RV64I-NEXT:    mv a0, s2
165; RV64I-NEXT:    call __gtsf2
166; RV64I-NEXT:    mv s4, a0
167; RV64I-NEXT:    blez a0, .LBB4_4
168; RV64I-NEXT:  # %bb.3:
169; RV64I-NEXT:    srli s3, s5, 1
170; RV64I-NEXT:  .LBB4_4:
171; RV64I-NEXT:    mv a0, s2
172; RV64I-NEXT:    mv a1, s2
173; RV64I-NEXT:    call __unordsf2
174; RV64I-NEXT:    snez a0, a0
175; RV64I-NEXT:    sgtz a1, s4
176; RV64I-NEXT:    slti a2, s0, 0
177; RV64I-NEXT:    addi a0, a0, -1
178; RV64I-NEXT:    neg a3, a1
179; RV64I-NEXT:    addi a2, a2, -1
180; RV64I-NEXT:    and a1, a0, s3
181; RV64I-NEXT:    and a2, a2, s1
182; RV64I-NEXT:    or a2, a3, a2
183; RV64I-NEXT:    and a0, a0, a2
184; RV64I-NEXT:    ld ra, 56(sp) # 8-byte Folded Reload
185; RV64I-NEXT:    ld s0, 48(sp) # 8-byte Folded Reload
186; RV64I-NEXT:    ld s1, 40(sp) # 8-byte Folded Reload
187; RV64I-NEXT:    ld s2, 32(sp) # 8-byte Folded Reload
188; RV64I-NEXT:    ld s3, 24(sp) # 8-byte Folded Reload
189; RV64I-NEXT:    ld s4, 16(sp) # 8-byte Folded Reload
190; RV64I-NEXT:    ld s5, 8(sp) # 8-byte Folded Reload
191; RV64I-NEXT:    addi sp, sp, 64
192; RV64I-NEXT:    ret
193;
194; RV64IZFH-LABEL: fptosi_sat_f16_to_i128:
195; RV64IZFH:       # %bb.0:
196; RV64IZFH-NEXT:    addi sp, sp, -32
197; RV64IZFH-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
198; RV64IZFH-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
199; RV64IZFH-NEXT:    fsw fs0, 12(sp) # 4-byte Folded Spill
200; RV64IZFH-NEXT:    fcvt.s.h fs0, fa0
201; RV64IZFH-NEXT:    lui a0, 1044480
202; RV64IZFH-NEXT:    fmv.w.x fa5, a0
203; RV64IZFH-NEXT:    fle.s s0, fa5, fs0
204; RV64IZFH-NEXT:    fmv.s fa0, fs0
205; RV64IZFH-NEXT:    call __fixsfti
206; RV64IZFH-NEXT:    li a2, -1
207; RV64IZFH-NEXT:    bnez s0, .LBB4_2
208; RV64IZFH-NEXT:  # %bb.1:
209; RV64IZFH-NEXT:    slli a1, a2, 63
210; RV64IZFH-NEXT:  .LBB4_2:
211; RV64IZFH-NEXT:    lui a3, %hi(.LCPI4_0)
212; RV64IZFH-NEXT:    flw fa5, %lo(.LCPI4_0)(a3)
213; RV64IZFH-NEXT:    flt.s a3, fa5, fs0
214; RV64IZFH-NEXT:    beqz a3, .LBB4_4
215; RV64IZFH-NEXT:  # %bb.3:
216; RV64IZFH-NEXT:    srli a1, a2, 1
217; RV64IZFH-NEXT:  .LBB4_4:
218; RV64IZFH-NEXT:    feq.s a2, fs0, fs0
219; RV64IZFH-NEXT:    neg a3, a3
220; RV64IZFH-NEXT:    neg a4, s0
221; RV64IZFH-NEXT:    neg a2, a2
222; RV64IZFH-NEXT:    and a0, a4, a0
223; RV64IZFH-NEXT:    and a1, a2, a1
224; RV64IZFH-NEXT:    or a0, a3, a0
225; RV64IZFH-NEXT:    and a0, a2, a0
226; RV64IZFH-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
227; RV64IZFH-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
228; RV64IZFH-NEXT:    flw fs0, 12(sp) # 4-byte Folded Reload
229; RV64IZFH-NEXT:    addi sp, sp, 32
230; RV64IZFH-NEXT:    ret
231;
232; RV64IZHINX-LABEL: fptosi_sat_f16_to_i128:
233; RV64IZHINX:       # %bb.0:
234; RV64IZHINX-NEXT:    addi sp, sp, -32
235; RV64IZHINX-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
236; RV64IZHINX-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
237; RV64IZHINX-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
238; RV64IZHINX-NEXT:    fcvt.s.h s0, a0
239; RV64IZHINX-NEXT:    lui a0, 1044480
240; RV64IZHINX-NEXT:    fle.s s1, a0, s0
241; RV64IZHINX-NEXT:    mv a0, s0
242; RV64IZHINX-NEXT:    call __fixsfti
243; RV64IZHINX-NEXT:    li a2, -1
244; RV64IZHINX-NEXT:    bnez s1, .LBB4_2
245; RV64IZHINX-NEXT:  # %bb.1:
246; RV64IZHINX-NEXT:    slli a1, a2, 63
247; RV64IZHINX-NEXT:  .LBB4_2:
248; RV64IZHINX-NEXT:    lui a3, 520192
249; RV64IZHINX-NEXT:    addiw a3, a3, -1
250; RV64IZHINX-NEXT:    flt.s a3, a3, s0
251; RV64IZHINX-NEXT:    beqz a3, .LBB4_4
252; RV64IZHINX-NEXT:  # %bb.3:
253; RV64IZHINX-NEXT:    srli a1, a2, 1
254; RV64IZHINX-NEXT:  .LBB4_4:
255; RV64IZHINX-NEXT:    feq.s a2, s0, s0
256; RV64IZHINX-NEXT:    neg a3, a3
257; RV64IZHINX-NEXT:    neg a4, s1
258; RV64IZHINX-NEXT:    neg a2, a2
259; RV64IZHINX-NEXT:    and a0, a4, a0
260; RV64IZHINX-NEXT:    and a1, a2, a1
261; RV64IZHINX-NEXT:    or a0, a3, a0
262; RV64IZHINX-NEXT:    and a0, a2, a0
263; RV64IZHINX-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
264; RV64IZHINX-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
265; RV64IZHINX-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
266; RV64IZHINX-NEXT:    addi sp, sp, 32
267; RV64IZHINX-NEXT:    ret
268  %1 = tail call i128 @llvm.fptosi.sat.i128.f16(half %a)
269  ret i128 %1
270}
271declare i128 @llvm.fptosi.sat.i128.f16(half)
272
273define i128 @fptoui_sat_f16_to_i128(half %a) nounwind {
274; RV64I-LABEL: fptoui_sat_f16_to_i128:
275; RV64I:       # %bb.0:
276; RV64I-NEXT:    addi sp, sp, -32
277; RV64I-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
278; RV64I-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
279; RV64I-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
280; RV64I-NEXT:    sd s2, 0(sp) # 8-byte Folded Spill
281; RV64I-NEXT:    call __extendhfsf2
282; RV64I-NEXT:    mv s0, a0
283; RV64I-NEXT:    lui a1, 522240
284; RV64I-NEXT:    addiw a1, a1, -1
285; RV64I-NEXT:    call __gtsf2
286; RV64I-NEXT:    sgtz a0, a0
287; RV64I-NEXT:    neg s1, a0
288; RV64I-NEXT:    mv a0, s0
289; RV64I-NEXT:    li a1, 0
290; RV64I-NEXT:    call __gesf2
291; RV64I-NEXT:    slti a0, a0, 0
292; RV64I-NEXT:    addi s2, a0, -1
293; RV64I-NEXT:    mv a0, s0
294; RV64I-NEXT:    call __fixunssfti
295; RV64I-NEXT:    and a0, s2, a0
296; RV64I-NEXT:    and a1, s2, a1
297; RV64I-NEXT:    or a0, s1, a0
298; RV64I-NEXT:    or a1, s1, a1
299; RV64I-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
300; RV64I-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
301; RV64I-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
302; RV64I-NEXT:    ld s2, 0(sp) # 8-byte Folded Reload
303; RV64I-NEXT:    addi sp, sp, 32
304; RV64I-NEXT:    ret
305;
306; RV64IZFH-LABEL: fptoui_sat_f16_to_i128:
307; RV64IZFH:       # %bb.0:
308; RV64IZFH-NEXT:    addi sp, sp, -32
309; RV64IZFH-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
310; RV64IZFH-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
311; RV64IZFH-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
312; RV64IZFH-NEXT:    lui a0, %hi(.LCPI5_0)
313; RV64IZFH-NEXT:    flw fa5, %lo(.LCPI5_0)(a0)
314; RV64IZFH-NEXT:    fcvt.s.h fa0, fa0
315; RV64IZFH-NEXT:    fmv.w.x fa4, zero
316; RV64IZFH-NEXT:    fle.s a0, fa4, fa0
317; RV64IZFH-NEXT:    flt.s a1, fa5, fa0
318; RV64IZFH-NEXT:    neg s0, a1
319; RV64IZFH-NEXT:    neg s1, a0
320; RV64IZFH-NEXT:    call __fixunssfti
321; RV64IZFH-NEXT:    and a0, s1, a0
322; RV64IZFH-NEXT:    and a1, s1, a1
323; RV64IZFH-NEXT:    or a0, s0, a0
324; RV64IZFH-NEXT:    or a1, s0, a1
325; RV64IZFH-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
326; RV64IZFH-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
327; RV64IZFH-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
328; RV64IZFH-NEXT:    addi sp, sp, 32
329; RV64IZFH-NEXT:    ret
330;
331; RV64IZHINX-LABEL: fptoui_sat_f16_to_i128:
332; RV64IZHINX:       # %bb.0:
333; RV64IZHINX-NEXT:    addi sp, sp, -32
334; RV64IZHINX-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
335; RV64IZHINX-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
336; RV64IZHINX-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
337; RV64IZHINX-NEXT:    fcvt.s.h a0, a0
338; RV64IZHINX-NEXT:    lui a1, 522240
339; RV64IZHINX-NEXT:    addiw a1, a1, -1
340; RV64IZHINX-NEXT:    fle.s a2, zero, a0
341; RV64IZHINX-NEXT:    flt.s a1, a1, a0
342; RV64IZHINX-NEXT:    neg s0, a1
343; RV64IZHINX-NEXT:    neg s1, a2
344; RV64IZHINX-NEXT:    call __fixunssfti
345; RV64IZHINX-NEXT:    and a0, s1, a0
346; RV64IZHINX-NEXT:    and a1, s1, a1
347; RV64IZHINX-NEXT:    or a0, s0, a0
348; RV64IZHINX-NEXT:    or a1, s0, a1
349; RV64IZHINX-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
350; RV64IZHINX-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
351; RV64IZHINX-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
352; RV64IZHINX-NEXT:    addi sp, sp, 32
353; RV64IZHINX-NEXT:    ret
354  %1 = tail call i128 @llvm.fptoui.sat.i128.f16(half %a)
355  ret i128 %1
356}
357declare i128 @llvm.fptoui.sat.i128.f16(half)
358;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
359; CHECK: {{.*}}
360