xref: /llvm-project/llvm/test/CodeGen/RISCV/libcall-tail-calls.ll (revision eabaee0c59110d0e11b33a69db54ccda526b35fd)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs -target-abi=ilp32d < %s \
3; RUN:   | FileCheck -check-prefixes=RV32-ALL,F-ABI-ALL,D-ABI-ALL,RV32IFD-ILP32D %s
4; RUN: llc -mtriple=riscv32 -mattr=+f -verify-machineinstrs -target-abi=ilp32f < %s \
5; RUN:   | FileCheck -check-prefixes=RV32-ALL,F-ABI-ALL,RV32IF-ILP32F %s
6; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs -target-abi=ilp32 < %s \
7; RUN:   | FileCheck -check-prefixes=RV32-ALL,RV32-ILP32-ALL,RV32IFD-ILP32 %s
8; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
9; RUN:   | FileCheck -check-prefixes=RV32-ALL,RV32-ILP32-ALL,RV32I-ILP32 %s
10; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs -target-abi=lp64d < %s \
11; RUN:   | FileCheck -check-prefixes=RV64-ALL,F-ABI-ALL,D-ABI-ALL,RV64IFD-LP64D %s
12; RUN: llc -mtriple=riscv64 -mattr=+f -verify-machineinstrs -target-abi=lp64f < %s \
13; RUN:   | FileCheck -check-prefixes=RV64-ALL,F-ABI-ALL,RV64IF-LP64F %s
14; RUN: llc -mtriple=riscv64 -mattr=+d -verify-machineinstrs -target-abi=lp64 < %s \
15; RUN:   | FileCheck -check-prefixes=RV64-ALL,RV64-LP64-ALL,RV64IFD-LP64 %s
16; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
17; RUN:   | FileCheck -check-prefixes=RV64-ALL,RV64-LP64-ALL,RV64I-LP64 %s
18
19; This file checks for the backend's ability to tailcall libcalls. While other
20; tests exhaustively check for selection of libcalls, this file is focused on
21; testing a representative selection of libcalls under all relevant ABI and
22; ISA combinations.
23
24; Integer arithmetic libcalls:
25
26define zeroext i8 @udiv8(i8 zeroext %a, i8 zeroext %b) nounwind {
27; RV32-ALL-LABEL: udiv8:
28; RV32-ALL:       # %bb.0:
29; RV32-ALL-NEXT:    addi sp, sp, -16
30; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
31; RV32-ALL-NEXT:    call __udivsi3
32; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
33; RV32-ALL-NEXT:    addi sp, sp, 16
34; RV32-ALL-NEXT:    ret
35;
36; RV64-ALL-LABEL: udiv8:
37; RV64-ALL:       # %bb.0:
38; RV64-ALL-NEXT:    addi sp, sp, -16
39; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
40; RV64-ALL-NEXT:    call __udivdi3
41; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
42; RV64-ALL-NEXT:    addi sp, sp, 16
43; RV64-ALL-NEXT:    ret
44  %1 = udiv i8 %a, %b
45  ret i8 %1
46}
47
48define signext i16 @sdiv16(i16 signext %a, i16 signext %b) nounwind {
49; RV32-ALL-LABEL: sdiv16:
50; RV32-ALL:       # %bb.0:
51; RV32-ALL-NEXT:    addi sp, sp, -16
52; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
53; RV32-ALL-NEXT:    call __divsi3
54; RV32-ALL-NEXT:    slli a0, a0, 16
55; RV32-ALL-NEXT:    srai a0, a0, 16
56; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
57; RV32-ALL-NEXT:    addi sp, sp, 16
58; RV32-ALL-NEXT:    ret
59;
60; RV64-ALL-LABEL: sdiv16:
61; RV64-ALL:       # %bb.0:
62; RV64-ALL-NEXT:    addi sp, sp, -16
63; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
64; RV64-ALL-NEXT:    call __divdi3
65; RV64-ALL-NEXT:    slli a0, a0, 48
66; RV64-ALL-NEXT:    srai a0, a0, 48
67; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
68; RV64-ALL-NEXT:    addi sp, sp, 16
69; RV64-ALL-NEXT:    ret
70  %1 = sdiv i16 %a, %b
71  ret i16 %1
72}
73
74define signext i32 @mul32(i32 %a, i32 %b) nounwind {
75; RV32-ALL-LABEL: mul32:
76; RV32-ALL:       # %bb.0:
77; RV32-ALL-NEXT:    addi sp, sp, -16
78; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
79; RV32-ALL-NEXT:    call __mulsi3
80; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
81; RV32-ALL-NEXT:    addi sp, sp, 16
82; RV32-ALL-NEXT:    ret
83;
84; RV64-ALL-LABEL: mul32:
85; RV64-ALL:       # %bb.0:
86; RV64-ALL-NEXT:    addi sp, sp, -16
87; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
88; RV64-ALL-NEXT:    call __muldi3
89; RV64-ALL-NEXT:    sext.w a0, a0
90; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
91; RV64-ALL-NEXT:    addi sp, sp, 16
92; RV64-ALL-NEXT:    ret
93  %1 = mul i32 %a, %b
94  ret i32 %1
95}
96
97define i64 @mul64(i64 %a, i64 %b) nounwind {
98; RV32-ALL-LABEL: mul64:
99; RV32-ALL:       # %bb.0:
100; RV32-ALL-NEXT:    addi sp, sp, -16
101; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
102; RV32-ALL-NEXT:    call __muldi3
103; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
104; RV32-ALL-NEXT:    addi sp, sp, 16
105; RV32-ALL-NEXT:    ret
106;
107; RV64-ALL-LABEL: mul64:
108; RV64-ALL:       # %bb.0:
109; RV64-ALL-NEXT:    tail __muldi3
110  %1 = mul i64 %a, %b
111  ret i64 %1
112}
113
114; Half libcalls:
115
116declare half @llvm.sin.f16(half)
117
118define half @sin_f16(half %a) nounwind {
119; RV32IFD-ILP32D-LABEL: sin_f16:
120; RV32IFD-ILP32D:       # %bb.0:
121; RV32IFD-ILP32D-NEXT:    addi sp, sp, -16
122; RV32IFD-ILP32D-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
123; RV32IFD-ILP32D-NEXT:    call __extendhfsf2
124; RV32IFD-ILP32D-NEXT:    call sinf
125; RV32IFD-ILP32D-NEXT:    call __truncsfhf2
126; RV32IFD-ILP32D-NEXT:    fmv.x.w a0, fa0
127; RV32IFD-ILP32D-NEXT:    lui a1, 1048560
128; RV32IFD-ILP32D-NEXT:    or a0, a0, a1
129; RV32IFD-ILP32D-NEXT:    fmv.w.x fa0, a0
130; RV32IFD-ILP32D-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
131; RV32IFD-ILP32D-NEXT:    addi sp, sp, 16
132; RV32IFD-ILP32D-NEXT:    ret
133;
134; RV32IF-ILP32F-LABEL: sin_f16:
135; RV32IF-ILP32F:       # %bb.0:
136; RV32IF-ILP32F-NEXT:    addi sp, sp, -16
137; RV32IF-ILP32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
138; RV32IF-ILP32F-NEXT:    call __extendhfsf2
139; RV32IF-ILP32F-NEXT:    call sinf
140; RV32IF-ILP32F-NEXT:    call __truncsfhf2
141; RV32IF-ILP32F-NEXT:    fmv.x.w a0, fa0
142; RV32IF-ILP32F-NEXT:    lui a1, 1048560
143; RV32IF-ILP32F-NEXT:    or a0, a0, a1
144; RV32IF-ILP32F-NEXT:    fmv.w.x fa0, a0
145; RV32IF-ILP32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
146; RV32IF-ILP32F-NEXT:    addi sp, sp, 16
147; RV32IF-ILP32F-NEXT:    ret
148;
149; RV32IFD-ILP32-LABEL: sin_f16:
150; RV32IFD-ILP32:       # %bb.0:
151; RV32IFD-ILP32-NEXT:    addi sp, sp, -16
152; RV32IFD-ILP32-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
153; RV32IFD-ILP32-NEXT:    call __extendhfsf2
154; RV32IFD-ILP32-NEXT:    call sinf
155; RV32IFD-ILP32-NEXT:    call __truncsfhf2
156; RV32IFD-ILP32-NEXT:    lui a1, 1048560
157; RV32IFD-ILP32-NEXT:    or a0, a0, a1
158; RV32IFD-ILP32-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
159; RV32IFD-ILP32-NEXT:    addi sp, sp, 16
160; RV32IFD-ILP32-NEXT:    ret
161;
162; RV32I-ILP32-LABEL: sin_f16:
163; RV32I-ILP32:       # %bb.0:
164; RV32I-ILP32-NEXT:    addi sp, sp, -16
165; RV32I-ILP32-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
166; RV32I-ILP32-NEXT:    slli a0, a0, 16
167; RV32I-ILP32-NEXT:    srli a0, a0, 16
168; RV32I-ILP32-NEXT:    call __extendhfsf2
169; RV32I-ILP32-NEXT:    call sinf
170; RV32I-ILP32-NEXT:    call __truncsfhf2
171; RV32I-ILP32-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
172; RV32I-ILP32-NEXT:    addi sp, sp, 16
173; RV32I-ILP32-NEXT:    ret
174;
175; RV64IFD-LP64D-LABEL: sin_f16:
176; RV64IFD-LP64D:       # %bb.0:
177; RV64IFD-LP64D-NEXT:    addi sp, sp, -16
178; RV64IFD-LP64D-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
179; RV64IFD-LP64D-NEXT:    call __extendhfsf2
180; RV64IFD-LP64D-NEXT:    call sinf
181; RV64IFD-LP64D-NEXT:    call __truncsfhf2
182; RV64IFD-LP64D-NEXT:    fmv.x.w a0, fa0
183; RV64IFD-LP64D-NEXT:    lui a1, 1048560
184; RV64IFD-LP64D-NEXT:    or a0, a0, a1
185; RV64IFD-LP64D-NEXT:    fmv.w.x fa0, a0
186; RV64IFD-LP64D-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
187; RV64IFD-LP64D-NEXT:    addi sp, sp, 16
188; RV64IFD-LP64D-NEXT:    ret
189;
190; RV64IF-LP64F-LABEL: sin_f16:
191; RV64IF-LP64F:       # %bb.0:
192; RV64IF-LP64F-NEXT:    addi sp, sp, -16
193; RV64IF-LP64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
194; RV64IF-LP64F-NEXT:    call __extendhfsf2
195; RV64IF-LP64F-NEXT:    call sinf
196; RV64IF-LP64F-NEXT:    call __truncsfhf2
197; RV64IF-LP64F-NEXT:    fmv.x.w a0, fa0
198; RV64IF-LP64F-NEXT:    lui a1, 1048560
199; RV64IF-LP64F-NEXT:    or a0, a0, a1
200; RV64IF-LP64F-NEXT:    fmv.w.x fa0, a0
201; RV64IF-LP64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
202; RV64IF-LP64F-NEXT:    addi sp, sp, 16
203; RV64IF-LP64F-NEXT:    ret
204;
205; RV64IFD-LP64-LABEL: sin_f16:
206; RV64IFD-LP64:       # %bb.0:
207; RV64IFD-LP64-NEXT:    addi sp, sp, -16
208; RV64IFD-LP64-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
209; RV64IFD-LP64-NEXT:    call __extendhfsf2
210; RV64IFD-LP64-NEXT:    call sinf
211; RV64IFD-LP64-NEXT:    call __truncsfhf2
212; RV64IFD-LP64-NEXT:    lui a1, 1048560
213; RV64IFD-LP64-NEXT:    or a0, a0, a1
214; RV64IFD-LP64-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
215; RV64IFD-LP64-NEXT:    addi sp, sp, 16
216; RV64IFD-LP64-NEXT:    ret
217;
218; RV64I-LP64-LABEL: sin_f16:
219; RV64I-LP64:       # %bb.0:
220; RV64I-LP64-NEXT:    addi sp, sp, -16
221; RV64I-LP64-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
222; RV64I-LP64-NEXT:    slli a0, a0, 48
223; RV64I-LP64-NEXT:    srli a0, a0, 48
224; RV64I-LP64-NEXT:    call __extendhfsf2
225; RV64I-LP64-NEXT:    call sinf
226; RV64I-LP64-NEXT:    call __truncsfhf2
227; RV64I-LP64-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
228; RV64I-LP64-NEXT:    addi sp, sp, 16
229; RV64I-LP64-NEXT:    ret
230  %1 = call half @llvm.sin.f16(half %a)
231  ret half %1
232}
233
234; Float libcalls:
235
236declare float @llvm.sin.f32(float)
237
238define float @sin_f32(float %a) nounwind {
239; F-ABI-ALL-LABEL: sin_f32:
240; F-ABI-ALL:       # %bb.0:
241; F-ABI-ALL-NEXT:    tail sinf
242;
243; RV32IFD-ILP32-LABEL: sin_f32:
244; RV32IFD-ILP32:       # %bb.0:
245; RV32IFD-ILP32-NEXT:    tail sinf
246;
247; RV32I-ILP32-LABEL: sin_f32:
248; RV32I-ILP32:       # %bb.0:
249; RV32I-ILP32-NEXT:    addi sp, sp, -16
250; RV32I-ILP32-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
251; RV32I-ILP32-NEXT:    call sinf
252; RV32I-ILP32-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
253; RV32I-ILP32-NEXT:    addi sp, sp, 16
254; RV32I-ILP32-NEXT:    ret
255;
256; RV64-LP64-ALL-LABEL: sin_f32:
257; RV64-LP64-ALL:       # %bb.0:
258; RV64-LP64-ALL-NEXT:    addi sp, sp, -16
259; RV64-LP64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
260; RV64-LP64-ALL-NEXT:    call sinf
261; RV64-LP64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
262; RV64-LP64-ALL-NEXT:    addi sp, sp, 16
263; RV64-LP64-ALL-NEXT:    ret
264  %1 = call float @llvm.sin.f32(float %a)
265  ret float %1
266}
267
268declare float @llvm.powi.f32.i32(float, i32)
269
270define float @powi_f32(float %a, i32 %b) nounwind {
271; RV32IFD-ILP32D-LABEL: powi_f32:
272; RV32IFD-ILP32D:       # %bb.0:
273; RV32IFD-ILP32D-NEXT:    tail __powisf2
274;
275; RV32IF-ILP32F-LABEL: powi_f32:
276; RV32IF-ILP32F:       # %bb.0:
277; RV32IF-ILP32F-NEXT:    tail __powisf2
278;
279; RV32IFD-ILP32-LABEL: powi_f32:
280; RV32IFD-ILP32:       # %bb.0:
281; RV32IFD-ILP32-NEXT:    tail __powisf2
282;
283; RV32I-ILP32-LABEL: powi_f32:
284; RV32I-ILP32:       # %bb.0:
285; RV32I-ILP32-NEXT:    addi sp, sp, -16
286; RV32I-ILP32-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
287; RV32I-ILP32-NEXT:    call __powisf2
288; RV32I-ILP32-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
289; RV32I-ILP32-NEXT:    addi sp, sp, 16
290; RV32I-ILP32-NEXT:    ret
291;
292; RV64IFD-LP64D-LABEL: powi_f32:
293; RV64IFD-LP64D:       # %bb.0:
294; RV64IFD-LP64D-NEXT:    addi sp, sp, -16
295; RV64IFD-LP64D-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
296; RV64IFD-LP64D-NEXT:    sext.w a0, a0
297; RV64IFD-LP64D-NEXT:    call __powisf2
298; RV64IFD-LP64D-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
299; RV64IFD-LP64D-NEXT:    addi sp, sp, 16
300; RV64IFD-LP64D-NEXT:    ret
301;
302; RV64IF-LP64F-LABEL: powi_f32:
303; RV64IF-LP64F:       # %bb.0:
304; RV64IF-LP64F-NEXT:    addi sp, sp, -16
305; RV64IF-LP64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
306; RV64IF-LP64F-NEXT:    sext.w a0, a0
307; RV64IF-LP64F-NEXT:    call __powisf2
308; RV64IF-LP64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
309; RV64IF-LP64F-NEXT:    addi sp, sp, 16
310; RV64IF-LP64F-NEXT:    ret
311;
312; RV64-LP64-ALL-LABEL: powi_f32:
313; RV64-LP64-ALL:       # %bb.0:
314; RV64-LP64-ALL-NEXT:    addi sp, sp, -16
315; RV64-LP64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
316; RV64-LP64-ALL-NEXT:    sext.w a1, a1
317; RV64-LP64-ALL-NEXT:    call __powisf2
318; RV64-LP64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
319; RV64-LP64-ALL-NEXT:    addi sp, sp, 16
320; RV64-LP64-ALL-NEXT:    ret
321  %1 = call float @llvm.powi.f32.i32(float %a, i32 %b)
322  ret float %1
323}
324
325declare i64 @llvm.llround.i64.f32(float)
326
327define i64 @llround_f32(float %a) nounwind {
328; RV32-ALL-LABEL: llround_f32:
329; RV32-ALL:       # %bb.0:
330; RV32-ALL-NEXT:    addi sp, sp, -16
331; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
332; RV32-ALL-NEXT:    call llroundf
333; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
334; RV32-ALL-NEXT:    addi sp, sp, 16
335; RV32-ALL-NEXT:    ret
336;
337; RV64IFD-LP64D-LABEL: llround_f32:
338; RV64IFD-LP64D:       # %bb.0:
339; RV64IFD-LP64D-NEXT:    fcvt.l.s a0, fa0, rmm
340; RV64IFD-LP64D-NEXT:    ret
341;
342; RV64IF-LP64F-LABEL: llround_f32:
343; RV64IF-LP64F:       # %bb.0:
344; RV64IF-LP64F-NEXT:    fcvt.l.s a0, fa0, rmm
345; RV64IF-LP64F-NEXT:    ret
346;
347; RV64IFD-LP64-LABEL: llround_f32:
348; RV64IFD-LP64:       # %bb.0:
349; RV64IFD-LP64-NEXT:    fmv.w.x fa5, a0
350; RV64IFD-LP64-NEXT:    fcvt.l.s a0, fa5, rmm
351; RV64IFD-LP64-NEXT:    ret
352;
353; RV64I-LP64-LABEL: llround_f32:
354; RV64I-LP64:       # %bb.0:
355; RV64I-LP64-NEXT:    addi sp, sp, -16
356; RV64I-LP64-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
357; RV64I-LP64-NEXT:    call llroundf
358; RV64I-LP64-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
359; RV64I-LP64-NEXT:    addi sp, sp, 16
360; RV64I-LP64-NEXT:    ret
361  %1 = call i64 @llvm.llround.i64.f32(float %a)
362  ret i64 %1
363}
364
365; Double libcalls:
366
367declare double @llvm.sin.f64(double)
368
369define double @sin_f64(double %a) nounwind {
370; D-ABI-ALL-LABEL: sin_f64:
371; D-ABI-ALL:       # %bb.0:
372; D-ABI-ALL-NEXT:    tail sin
373;
374; RV32IF-ILP32F-LABEL: sin_f64:
375; RV32IF-ILP32F:       # %bb.0:
376; RV32IF-ILP32F-NEXT:    addi sp, sp, -16
377; RV32IF-ILP32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
378; RV32IF-ILP32F-NEXT:    call sin
379; RV32IF-ILP32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
380; RV32IF-ILP32F-NEXT:    addi sp, sp, 16
381; RV32IF-ILP32F-NEXT:    ret
382;
383; RV32-ILP32-ALL-LABEL: sin_f64:
384; RV32-ILP32-ALL:       # %bb.0:
385; RV32-ILP32-ALL-NEXT:    addi sp, sp, -16
386; RV32-ILP32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
387; RV32-ILP32-ALL-NEXT:    call sin
388; RV32-ILP32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
389; RV32-ILP32-ALL-NEXT:    addi sp, sp, 16
390; RV32-ILP32-ALL-NEXT:    ret
391;
392; RV64IF-LP64F-LABEL: sin_f64:
393; RV64IF-LP64F:       # %bb.0:
394; RV64IF-LP64F-NEXT:    addi sp, sp, -16
395; RV64IF-LP64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
396; RV64IF-LP64F-NEXT:    call sin
397; RV64IF-LP64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
398; RV64IF-LP64F-NEXT:    addi sp, sp, 16
399; RV64IF-LP64F-NEXT:    ret
400;
401; RV64IFD-LP64-LABEL: sin_f64:
402; RV64IFD-LP64:       # %bb.0:
403; RV64IFD-LP64-NEXT:    tail sin
404;
405; RV64I-LP64-LABEL: sin_f64:
406; RV64I-LP64:       # %bb.0:
407; RV64I-LP64-NEXT:    addi sp, sp, -16
408; RV64I-LP64-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
409; RV64I-LP64-NEXT:    call sin
410; RV64I-LP64-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
411; RV64I-LP64-NEXT:    addi sp, sp, 16
412; RV64I-LP64-NEXT:    ret
413  %1 = call double @llvm.sin.f64(double %a)
414  ret double %1
415}
416
417declare double @llvm.powi.f64.i32(double, i32)
418
419define double @powi_f64(double %a, i32 %b) nounwind {
420; RV32IFD-ILP32D-LABEL: powi_f64:
421; RV32IFD-ILP32D:       # %bb.0:
422; RV32IFD-ILP32D-NEXT:    tail __powidf2
423;
424; RV32IF-ILP32F-LABEL: powi_f64:
425; RV32IF-ILP32F:       # %bb.0:
426; RV32IF-ILP32F-NEXT:    addi sp, sp, -16
427; RV32IF-ILP32F-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
428; RV32IF-ILP32F-NEXT:    call __powidf2
429; RV32IF-ILP32F-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
430; RV32IF-ILP32F-NEXT:    addi sp, sp, 16
431; RV32IF-ILP32F-NEXT:    ret
432;
433; RV32-ILP32-ALL-LABEL: powi_f64:
434; RV32-ILP32-ALL:       # %bb.0:
435; RV32-ILP32-ALL-NEXT:    addi sp, sp, -16
436; RV32-ILP32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
437; RV32-ILP32-ALL-NEXT:    call __powidf2
438; RV32-ILP32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
439; RV32-ILP32-ALL-NEXT:    addi sp, sp, 16
440; RV32-ILP32-ALL-NEXT:    ret
441;
442; RV64IFD-LP64D-LABEL: powi_f64:
443; RV64IFD-LP64D:       # %bb.0:
444; RV64IFD-LP64D-NEXT:    addi sp, sp, -16
445; RV64IFD-LP64D-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
446; RV64IFD-LP64D-NEXT:    sext.w a0, a0
447; RV64IFD-LP64D-NEXT:    call __powidf2
448; RV64IFD-LP64D-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
449; RV64IFD-LP64D-NEXT:    addi sp, sp, 16
450; RV64IFD-LP64D-NEXT:    ret
451;
452; RV64IF-LP64F-LABEL: powi_f64:
453; RV64IF-LP64F:       # %bb.0:
454; RV64IF-LP64F-NEXT:    addi sp, sp, -16
455; RV64IF-LP64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
456; RV64IF-LP64F-NEXT:    sext.w a1, a1
457; RV64IF-LP64F-NEXT:    call __powidf2
458; RV64IF-LP64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
459; RV64IF-LP64F-NEXT:    addi sp, sp, 16
460; RV64IF-LP64F-NEXT:    ret
461;
462; RV64-LP64-ALL-LABEL: powi_f64:
463; RV64-LP64-ALL:       # %bb.0:
464; RV64-LP64-ALL-NEXT:    addi sp, sp, -16
465; RV64-LP64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
466; RV64-LP64-ALL-NEXT:    sext.w a1, a1
467; RV64-LP64-ALL-NEXT:    call __powidf2
468; RV64-LP64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
469; RV64-LP64-ALL-NEXT:    addi sp, sp, 16
470; RV64-LP64-ALL-NEXT:    ret
471  %1 = call double @llvm.powi.f64.i32(double %a, i32 %b)
472  ret double %1
473}
474
475declare i64 @llvm.llround.i64.f64(double)
476
477define i64 @llround_f64(double %a) nounwind {
478; RV32-ALL-LABEL: llround_f64:
479; RV32-ALL:       # %bb.0:
480; RV32-ALL-NEXT:    addi sp, sp, -16
481; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
482; RV32-ALL-NEXT:    call llround
483; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
484; RV32-ALL-NEXT:    addi sp, sp, 16
485; RV32-ALL-NEXT:    ret
486;
487; RV64IFD-LP64D-LABEL: llround_f64:
488; RV64IFD-LP64D:       # %bb.0:
489; RV64IFD-LP64D-NEXT:    fcvt.l.d a0, fa0, rmm
490; RV64IFD-LP64D-NEXT:    ret
491;
492; RV64IF-LP64F-LABEL: llround_f64:
493; RV64IF-LP64F:       # %bb.0:
494; RV64IF-LP64F-NEXT:    addi sp, sp, -16
495; RV64IF-LP64F-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
496; RV64IF-LP64F-NEXT:    call llround
497; RV64IF-LP64F-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
498; RV64IF-LP64F-NEXT:    addi sp, sp, 16
499; RV64IF-LP64F-NEXT:    ret
500;
501; RV64IFD-LP64-LABEL: llround_f64:
502; RV64IFD-LP64:       # %bb.0:
503; RV64IFD-LP64-NEXT:    fmv.d.x fa5, a0
504; RV64IFD-LP64-NEXT:    fcvt.l.d a0, fa5, rmm
505; RV64IFD-LP64-NEXT:    ret
506;
507; RV64I-LP64-LABEL: llround_f64:
508; RV64I-LP64:       # %bb.0:
509; RV64I-LP64-NEXT:    addi sp, sp, -16
510; RV64I-LP64-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
511; RV64I-LP64-NEXT:    call llround
512; RV64I-LP64-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
513; RV64I-LP64-NEXT:    addi sp, sp, 16
514; RV64I-LP64-NEXT:    ret
515  %1 = call i64 @llvm.llround.i64.f64(double %a)
516  ret i64 %1
517}
518
519; Atomics libcalls:
520
521define i8 @atomic_load_i8_unordered(ptr %a) nounwind {
522; RV32-ALL-LABEL: atomic_load_i8_unordered:
523; RV32-ALL:       # %bb.0:
524; RV32-ALL-NEXT:    addi sp, sp, -16
525; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
526; RV32-ALL-NEXT:    li a1, 0
527; RV32-ALL-NEXT:    call __atomic_load_1
528; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
529; RV32-ALL-NEXT:    addi sp, sp, 16
530; RV32-ALL-NEXT:    ret
531;
532; RV64-ALL-LABEL: atomic_load_i8_unordered:
533; RV64-ALL:       # %bb.0:
534; RV64-ALL-NEXT:    addi sp, sp, -16
535; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
536; RV64-ALL-NEXT:    li a1, 0
537; RV64-ALL-NEXT:    call __atomic_load_1
538; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
539; RV64-ALL-NEXT:    addi sp, sp, 16
540; RV64-ALL-NEXT:    ret
541  %1 = load atomic i8, ptr %a unordered, align 1
542  ret i8 %1
543}
544
545define i16 @atomicrmw_add_i16_release(ptr %a, i16 %b) nounwind {
546; RV32-ALL-LABEL: atomicrmw_add_i16_release:
547; RV32-ALL:       # %bb.0:
548; RV32-ALL-NEXT:    addi sp, sp, -16
549; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
550; RV32-ALL-NEXT:    li a2, 3
551; RV32-ALL-NEXT:    call __atomic_fetch_add_2
552; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
553; RV32-ALL-NEXT:    addi sp, sp, 16
554; RV32-ALL-NEXT:    ret
555;
556; RV64-ALL-LABEL: atomicrmw_add_i16_release:
557; RV64-ALL:       # %bb.0:
558; RV64-ALL-NEXT:    addi sp, sp, -16
559; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
560; RV64-ALL-NEXT:    li a2, 3
561; RV64-ALL-NEXT:    call __atomic_fetch_add_2
562; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
563; RV64-ALL-NEXT:    addi sp, sp, 16
564; RV64-ALL-NEXT:    ret
565  %1 = atomicrmw add ptr %a, i16 %b release
566  ret i16 %1
567}
568
569define i32 @atomicrmw_xor_i32_acq_rel(ptr %a, i32 %b) nounwind {
570; RV32-ALL-LABEL: atomicrmw_xor_i32_acq_rel:
571; RV32-ALL:       # %bb.0:
572; RV32-ALL-NEXT:    addi sp, sp, -16
573; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
574; RV32-ALL-NEXT:    li a2, 4
575; RV32-ALL-NEXT:    call __atomic_fetch_xor_4
576; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
577; RV32-ALL-NEXT:    addi sp, sp, 16
578; RV32-ALL-NEXT:    ret
579;
580; RV64-ALL-LABEL: atomicrmw_xor_i32_acq_rel:
581; RV64-ALL:       # %bb.0:
582; RV64-ALL-NEXT:    addi sp, sp, -16
583; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
584; RV64-ALL-NEXT:    li a2, 4
585; RV64-ALL-NEXT:    call __atomic_fetch_xor_4
586; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
587; RV64-ALL-NEXT:    addi sp, sp, 16
588; RV64-ALL-NEXT:    ret
589  %1 = atomicrmw xor ptr %a, i32 %b acq_rel
590  ret i32 %1
591}
592
593define i64 @atomicrmw_nand_i64_seq_cst(ptr %a, i64 %b) nounwind {
594; RV32-ALL-LABEL: atomicrmw_nand_i64_seq_cst:
595; RV32-ALL:       # %bb.0:
596; RV32-ALL-NEXT:    addi sp, sp, -16
597; RV32-ALL-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
598; RV32-ALL-NEXT:    li a3, 5
599; RV32-ALL-NEXT:    call __atomic_fetch_nand_8
600; RV32-ALL-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
601; RV32-ALL-NEXT:    addi sp, sp, 16
602; RV32-ALL-NEXT:    ret
603;
604; RV64-ALL-LABEL: atomicrmw_nand_i64_seq_cst:
605; RV64-ALL:       # %bb.0:
606; RV64-ALL-NEXT:    addi sp, sp, -16
607; RV64-ALL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
608; RV64-ALL-NEXT:    li a2, 5
609; RV64-ALL-NEXT:    call __atomic_fetch_nand_8
610; RV64-ALL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
611; RV64-ALL-NEXT:    addi sp, sp, 16
612; RV64-ALL-NEXT:    ret
613  %1 = atomicrmw nand ptr %a, i64 %b seq_cst
614  ret i64 %1
615}
616