blob: a5243ea18ab14b090472fbaefe251d2e9f223b55 [file] [log] [blame]
Alex Bradbury8f296472018-04-12 05:36:44 +00001; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=riscv32 -mattr=+d -verify-machineinstrs < %s \
3; RUN: | FileCheck -check-prefix=RV32IFD %s
4
Alex Bradbury919f5fb2018-12-13 10:49:05 +00005; These tests are each targeted at a particular RISC-V FPU instruction. Most
6; other files in this folder exercise LLVM IR instructions that don't directly
7; match a RISC-V instruction.
8
Alex Bradbury8f296472018-04-12 05:36:44 +00009define double @fadd_d(double %a, double %b) nounwind {
10; RV32IFD-LABEL: fadd_d:
11; RV32IFD: # %bb.0:
12; RV32IFD-NEXT: addi sp, sp, -16
13; RV32IFD-NEXT: sw a2, 8(sp)
14; RV32IFD-NEXT: sw a3, 12(sp)
15; RV32IFD-NEXT: fld ft0, 8(sp)
16; RV32IFD-NEXT: sw a0, 8(sp)
17; RV32IFD-NEXT: sw a1, 12(sp)
18; RV32IFD-NEXT: fld ft1, 8(sp)
19; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
20; RV32IFD-NEXT: fsd ft0, 8(sp)
21; RV32IFD-NEXT: lw a0, 8(sp)
22; RV32IFD-NEXT: lw a1, 12(sp)
23; RV32IFD-NEXT: addi sp, sp, 16
24; RV32IFD-NEXT: ret
25 %1 = fadd double %a, %b
26 ret double %1
27}
Alex Bradbury5d0dfa52018-04-12 05:42:42 +000028
29define double @fsub_d(double %a, double %b) nounwind {
30; RV32IFD-LABEL: fsub_d:
31; RV32IFD: # %bb.0:
32; RV32IFD-NEXT: addi sp, sp, -16
33; RV32IFD-NEXT: sw a2, 8(sp)
34; RV32IFD-NEXT: sw a3, 12(sp)
35; RV32IFD-NEXT: fld ft0, 8(sp)
36; RV32IFD-NEXT: sw a0, 8(sp)
37; RV32IFD-NEXT: sw a1, 12(sp)
38; RV32IFD-NEXT: fld ft1, 8(sp)
39; RV32IFD-NEXT: fsub.d ft0, ft1, ft0
40; RV32IFD-NEXT: fsd ft0, 8(sp)
41; RV32IFD-NEXT: lw a0, 8(sp)
42; RV32IFD-NEXT: lw a1, 12(sp)
43; RV32IFD-NEXT: addi sp, sp, 16
44; RV32IFD-NEXT: ret
45 %1 = fsub double %a, %b
46 ret double %1
47}
48
49define double @fmul_d(double %a, double %b) nounwind {
50; RV32IFD-LABEL: fmul_d:
51; RV32IFD: # %bb.0:
52; RV32IFD-NEXT: addi sp, sp, -16
53; RV32IFD-NEXT: sw a2, 8(sp)
54; RV32IFD-NEXT: sw a3, 12(sp)
55; RV32IFD-NEXT: fld ft0, 8(sp)
56; RV32IFD-NEXT: sw a0, 8(sp)
57; RV32IFD-NEXT: sw a1, 12(sp)
58; RV32IFD-NEXT: fld ft1, 8(sp)
59; RV32IFD-NEXT: fmul.d ft0, ft1, ft0
60; RV32IFD-NEXT: fsd ft0, 8(sp)
61; RV32IFD-NEXT: lw a0, 8(sp)
62; RV32IFD-NEXT: lw a1, 12(sp)
63; RV32IFD-NEXT: addi sp, sp, 16
64; RV32IFD-NEXT: ret
65 %1 = fmul double %a, %b
66 ret double %1
67}
68
69define double @fdiv_d(double %a, double %b) nounwind {
70; RV32IFD-LABEL: fdiv_d:
71; RV32IFD: # %bb.0:
72; RV32IFD-NEXT: addi sp, sp, -16
73; RV32IFD-NEXT: sw a2, 8(sp)
74; RV32IFD-NEXT: sw a3, 12(sp)
75; RV32IFD-NEXT: fld ft0, 8(sp)
76; RV32IFD-NEXT: sw a0, 8(sp)
77; RV32IFD-NEXT: sw a1, 12(sp)
78; RV32IFD-NEXT: fld ft1, 8(sp)
79; RV32IFD-NEXT: fdiv.d ft0, ft1, ft0
80; RV32IFD-NEXT: fsd ft0, 8(sp)
81; RV32IFD-NEXT: lw a0, 8(sp)
82; RV32IFD-NEXT: lw a1, 12(sp)
83; RV32IFD-NEXT: addi sp, sp, 16
84; RV32IFD-NEXT: ret
85 %1 = fdiv double %a, %b
86 ret double %1
87}
88
Alex Bradburyc67515d2019-01-25 16:04:04 +000089declare double @llvm.sqrt.f64(double)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +000090
91define double @fsqrt_d(double %a) nounwind {
92; RV32IFD-LABEL: fsqrt_d:
93; RV32IFD: # %bb.0:
94; RV32IFD-NEXT: addi sp, sp, -16
95; RV32IFD-NEXT: sw a0, 8(sp)
96; RV32IFD-NEXT: sw a1, 12(sp)
97; RV32IFD-NEXT: fld ft0, 8(sp)
98; RV32IFD-NEXT: fsqrt.d ft0, ft0
99; RV32IFD-NEXT: fsd ft0, 8(sp)
100; RV32IFD-NEXT: lw a0, 8(sp)
101; RV32IFD-NEXT: lw a1, 12(sp)
102; RV32IFD-NEXT: addi sp, sp, 16
103; RV32IFD-NEXT: ret
Alex Bradburyc67515d2019-01-25 16:04:04 +0000104 %1 = call double @llvm.sqrt.f64(double %a)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000105 ret double %1
106}
107
Alex Bradburyc67515d2019-01-25 16:04:04 +0000108declare double @llvm.copysign.f64(double, double)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000109
110define double @fsgnj_d(double %a, double %b) nounwind {
111; RV32IFD-LABEL: fsgnj_d:
112; RV32IFD: # %bb.0:
113; RV32IFD-NEXT: addi sp, sp, -16
114; RV32IFD-NEXT: sw a2, 8(sp)
115; RV32IFD-NEXT: sw a3, 12(sp)
116; RV32IFD-NEXT: fld ft0, 8(sp)
117; RV32IFD-NEXT: sw a0, 8(sp)
118; RV32IFD-NEXT: sw a1, 12(sp)
119; RV32IFD-NEXT: fld ft1, 8(sp)
120; RV32IFD-NEXT: fsgnj.d ft0, ft1, ft0
121; RV32IFD-NEXT: fsd ft0, 8(sp)
122; RV32IFD-NEXT: lw a0, 8(sp)
123; RV32IFD-NEXT: lw a1, 12(sp)
124; RV32IFD-NEXT: addi sp, sp, 16
125; RV32IFD-NEXT: ret
Alex Bradburyc67515d2019-01-25 16:04:04 +0000126 %1 = call double @llvm.copysign.f64(double %a, double %b)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000127 ret double %1
128}
129
Alex Bradbury0092df02019-01-25 21:55:48 +0000130; This function performs extra work to ensure that
131; DAGCombiner::visitBITCAST doesn't replace the fneg with an xor.
132define i32 @fneg_d(double %a, double %b) nounwind {
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000133; RV32IFD-LABEL: fneg_d:
134; RV32IFD: # %bb.0:
135; RV32IFD-NEXT: addi sp, sp, -16
136; RV32IFD-NEXT: sw a0, 8(sp)
137; RV32IFD-NEXT: sw a1, 12(sp)
138; RV32IFD-NEXT: fld ft0, 8(sp)
Alex Bradbury0092df02019-01-25 21:55:48 +0000139; RV32IFD-NEXT: fadd.d ft0, ft0, ft0
140; RV32IFD-NEXT: fneg.d ft1, ft0
141; RV32IFD-NEXT: feq.d a0, ft0, ft1
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000142; RV32IFD-NEXT: addi sp, sp, 16
143; RV32IFD-NEXT: ret
Alex Bradbury0092df02019-01-25 21:55:48 +0000144 %1 = fadd double %a, %a
145 %2 = fneg double %1
146 %3 = fcmp oeq double %1, %2
147 %4 = zext i1 %3 to i32
148 ret i32 %4
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000149}
150
151define double @fsgnjn_d(double %a, double %b) nounwind {
152; RV32IFD-LABEL: fsgnjn_d:
153; RV32IFD: # %bb.0:
154; RV32IFD-NEXT: addi sp, sp, -16
155; RV32IFD-NEXT: sw a2, 8(sp)
156; RV32IFD-NEXT: sw a3, 12(sp)
157; RV32IFD-NEXT: fld ft0, 8(sp)
158; RV32IFD-NEXT: sw a0, 8(sp)
159; RV32IFD-NEXT: sw a1, 12(sp)
160; RV32IFD-NEXT: fld ft1, 8(sp)
161; RV32IFD-NEXT: fsgnjn.d ft0, ft1, ft0
162; RV32IFD-NEXT: fsd ft0, 8(sp)
163; RV32IFD-NEXT: lw a0, 8(sp)
164; RV32IFD-NEXT: lw a1, 12(sp)
165; RV32IFD-NEXT: addi sp, sp, 16
166; RV32IFD-NEXT: ret
167 %1 = fsub double -0.0, %b
Alex Bradburyc67515d2019-01-25 16:04:04 +0000168 %2 = call double @llvm.copysign.f64(double %a, double %1)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000169 ret double %2
170}
171
Alex Bradburyc67515d2019-01-25 16:04:04 +0000172declare double @llvm.fabs.f64(double)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000173
Alex Bradbury0092df02019-01-25 21:55:48 +0000174; This function performs extra work to ensure that
175; DAGCombiner::visitBITCAST doesn't replace the fabs with an and.
176define double @fabs_d(double %a, double %b) nounwind {
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000177; RV32IFD-LABEL: fabs_d:
178; RV32IFD: # %bb.0:
179; RV32IFD-NEXT: addi sp, sp, -16
Alex Bradbury0092df02019-01-25 21:55:48 +0000180; RV32IFD-NEXT: sw a2, 8(sp)
181; RV32IFD-NEXT: sw a3, 12(sp)
182; RV32IFD-NEXT: fld ft0, 8(sp)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000183; RV32IFD-NEXT: sw a0, 8(sp)
184; RV32IFD-NEXT: sw a1, 12(sp)
Alex Bradbury0092df02019-01-25 21:55:48 +0000185; RV32IFD-NEXT: fld ft1, 8(sp)
186; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
187; RV32IFD-NEXT: fabs.d ft1, ft0
188; RV32IFD-NEXT: fadd.d ft0, ft1, ft0
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000189; RV32IFD-NEXT: fsd ft0, 8(sp)
190; RV32IFD-NEXT: lw a0, 8(sp)
191; RV32IFD-NEXT: lw a1, 12(sp)
192; RV32IFD-NEXT: addi sp, sp, 16
193; RV32IFD-NEXT: ret
Alex Bradbury0092df02019-01-25 21:55:48 +0000194 %1 = fadd double %a, %b
195 %2 = call double @llvm.fabs.f64(double %1)
196 %3 = fadd double %2, %1
197 ret double %3
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000198}
199
Alex Bradburyc67515d2019-01-25 16:04:04 +0000200declare double @llvm.minnum.f64(double, double)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000201
202define double @fmin_d(double %a, double %b) nounwind {
203; RV32IFD-LABEL: fmin_d:
204; RV32IFD: # %bb.0:
205; RV32IFD-NEXT: addi sp, sp, -16
206; RV32IFD-NEXT: sw a2, 8(sp)
207; RV32IFD-NEXT: sw a3, 12(sp)
208; RV32IFD-NEXT: fld ft0, 8(sp)
209; RV32IFD-NEXT: sw a0, 8(sp)
210; RV32IFD-NEXT: sw a1, 12(sp)
211; RV32IFD-NEXT: fld ft1, 8(sp)
212; RV32IFD-NEXT: fmin.d ft0, ft1, ft0
213; RV32IFD-NEXT: fsd ft0, 8(sp)
214; RV32IFD-NEXT: lw a0, 8(sp)
215; RV32IFD-NEXT: lw a1, 12(sp)
216; RV32IFD-NEXT: addi sp, sp, 16
217; RV32IFD-NEXT: ret
Alex Bradburyc67515d2019-01-25 16:04:04 +0000218 %1 = call double @llvm.minnum.f64(double %a, double %b)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000219 ret double %1
220}
221
Alex Bradburyc67515d2019-01-25 16:04:04 +0000222declare double @llvm.maxnum.f64(double, double)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000223
224define double @fmax_d(double %a, double %b) nounwind {
225; RV32IFD-LABEL: fmax_d:
226; RV32IFD: # %bb.0:
227; RV32IFD-NEXT: addi sp, sp, -16
228; RV32IFD-NEXT: sw a2, 8(sp)
229; RV32IFD-NEXT: sw a3, 12(sp)
230; RV32IFD-NEXT: fld ft0, 8(sp)
231; RV32IFD-NEXT: sw a0, 8(sp)
232; RV32IFD-NEXT: sw a1, 12(sp)
233; RV32IFD-NEXT: fld ft1, 8(sp)
234; RV32IFD-NEXT: fmax.d ft0, ft1, ft0
235; RV32IFD-NEXT: fsd ft0, 8(sp)
236; RV32IFD-NEXT: lw a0, 8(sp)
237; RV32IFD-NEXT: lw a1, 12(sp)
238; RV32IFD-NEXT: addi sp, sp, 16
239; RV32IFD-NEXT: ret
Alex Bradburyc67515d2019-01-25 16:04:04 +0000240 %1 = call double @llvm.maxnum.f64(double %a, double %b)
Alex Bradbury5d0dfa52018-04-12 05:42:42 +0000241 ret double %1
242}
243
244define i32 @feq_d(double %a, double %b) nounwind {
245; RV32IFD-LABEL: feq_d:
246; RV32IFD: # %bb.0:
247; RV32IFD-NEXT: addi sp, sp, -16
248; RV32IFD-NEXT: sw a2, 8(sp)
249; RV32IFD-NEXT: sw a3, 12(sp)
250; RV32IFD-NEXT: fld ft0, 8(sp)
251; RV32IFD-NEXT: sw a0, 8(sp)
252; RV32IFD-NEXT: sw a1, 12(sp)
253; RV32IFD-NEXT: fld ft1, 8(sp)
254; RV32IFD-NEXT: feq.d a0, ft1, ft0
255; RV32IFD-NEXT: addi sp, sp, 16
256; RV32IFD-NEXT: ret
257 %1 = fcmp oeq double %a, %b
258 %2 = zext i1 %1 to i32
259 ret i32 %2
260}
261
262define i32 @flt_d(double %a, double %b) nounwind {
263; RV32IFD-LABEL: flt_d:
264; RV32IFD: # %bb.0:
265; RV32IFD-NEXT: addi sp, sp, -16
266; RV32IFD-NEXT: sw a2, 8(sp)
267; RV32IFD-NEXT: sw a3, 12(sp)
268; RV32IFD-NEXT: fld ft0, 8(sp)
269; RV32IFD-NEXT: sw a0, 8(sp)
270; RV32IFD-NEXT: sw a1, 12(sp)
271; RV32IFD-NEXT: fld ft1, 8(sp)
272; RV32IFD-NEXT: flt.d a0, ft1, ft0
273; RV32IFD-NEXT: addi sp, sp, 16
274; RV32IFD-NEXT: ret
275 %1 = fcmp olt double %a, %b
276 %2 = zext i1 %1 to i32
277 ret i32 %2
278}
279
280define i32 @fle_d(double %a, double %b) nounwind {
281; RV32IFD-LABEL: fle_d:
282; RV32IFD: # %bb.0:
283; RV32IFD-NEXT: addi sp, sp, -16
284; RV32IFD-NEXT: sw a2, 8(sp)
285; RV32IFD-NEXT: sw a3, 12(sp)
286; RV32IFD-NEXT: fld ft0, 8(sp)
287; RV32IFD-NEXT: sw a0, 8(sp)
288; RV32IFD-NEXT: sw a1, 12(sp)
289; RV32IFD-NEXT: fld ft1, 8(sp)
290; RV32IFD-NEXT: fle.d a0, ft1, ft0
291; RV32IFD-NEXT: addi sp, sp, 16
292; RV32IFD-NEXT: ret
293 %1 = fcmp ole double %a, %b
294 %2 = zext i1 %1 to i32
295 ret i32 %2
296}
Alex Bradbury919f5fb2018-12-13 10:49:05 +0000297
298declare double @llvm.fma.f64(double, double, double)
299
300define double @fmadd_d(double %a, double %b, double %c) nounwind {
301; RV32IFD-LABEL: fmadd_d:
302; RV32IFD: # %bb.0:
303; RV32IFD-NEXT: addi sp, sp, -16
304; RV32IFD-NEXT: sw a4, 8(sp)
305; RV32IFD-NEXT: sw a5, 12(sp)
306; RV32IFD-NEXT: fld ft0, 8(sp)
307; RV32IFD-NEXT: sw a2, 8(sp)
308; RV32IFD-NEXT: sw a3, 12(sp)
309; RV32IFD-NEXT: fld ft1, 8(sp)
310; RV32IFD-NEXT: sw a0, 8(sp)
311; RV32IFD-NEXT: sw a1, 12(sp)
312; RV32IFD-NEXT: fld ft2, 8(sp)
313; RV32IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0
314; RV32IFD-NEXT: fsd ft0, 8(sp)
315; RV32IFD-NEXT: lw a0, 8(sp)
316; RV32IFD-NEXT: lw a1, 12(sp)
317; RV32IFD-NEXT: addi sp, sp, 16
318; RV32IFD-NEXT: ret
319 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
320 ret double %1
321}
322
323define double @fmsub_d(double %a, double %b, double %c) nounwind {
324; RV32IFD-LABEL: fmsub_d:
325; RV32IFD: # %bb.0:
326; RV32IFD-NEXT: addi sp, sp, -16
327; RV32IFD-NEXT: sw a2, 8(sp)
328; RV32IFD-NEXT: sw a3, 12(sp)
329; RV32IFD-NEXT: fld ft0, 8(sp)
330; RV32IFD-NEXT: sw a0, 8(sp)
331; RV32IFD-NEXT: sw a1, 12(sp)
332; RV32IFD-NEXT: fld ft1, 8(sp)
333; RV32IFD-NEXT: sw a4, 8(sp)
334; RV32IFD-NEXT: sw a5, 12(sp)
335; RV32IFD-NEXT: fld ft2, 8(sp)
336; RV32IFD-NEXT: lui a0, %hi(.LCPI15_0)
337; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI15_0)
338; RV32IFD-NEXT: fld ft3, 0(a0)
339; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
340; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2
341; RV32IFD-NEXT: fsd ft0, 8(sp)
342; RV32IFD-NEXT: lw a0, 8(sp)
343; RV32IFD-NEXT: lw a1, 12(sp)
344; RV32IFD-NEXT: addi sp, sp, 16
345; RV32IFD-NEXT: ret
346 %c_ = fadd double 0.0, %c ; avoid negation using xor
347 %negc = fsub double -0.0, %c_
348 %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
349 ret double %1
350}
351
352define double @fnmadd_d(double %a, double %b, double %c) nounwind {
353; RV32IFD-LABEL: fnmadd_d:
354; RV32IFD: # %bb.0:
355; RV32IFD-NEXT: addi sp, sp, -16
356; RV32IFD-NEXT: sw a2, 8(sp)
357; RV32IFD-NEXT: sw a3, 12(sp)
358; RV32IFD-NEXT: fld ft0, 8(sp)
359; RV32IFD-NEXT: sw a0, 8(sp)
360; RV32IFD-NEXT: sw a1, 12(sp)
361; RV32IFD-NEXT: fld ft1, 8(sp)
362; RV32IFD-NEXT: sw a4, 8(sp)
363; RV32IFD-NEXT: sw a5, 12(sp)
364; RV32IFD-NEXT: fld ft2, 8(sp)
365; RV32IFD-NEXT: lui a0, %hi(.LCPI16_0)
366; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI16_0)
367; RV32IFD-NEXT: fld ft3, 0(a0)
368; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
369; RV32IFD-NEXT: fadd.d ft1, ft1, ft3
370; RV32IFD-NEXT: fnmadd.d ft0, ft1, ft0, ft2
371; RV32IFD-NEXT: fsd ft0, 8(sp)
372; RV32IFD-NEXT: lw a0, 8(sp)
373; RV32IFD-NEXT: lw a1, 12(sp)
374; RV32IFD-NEXT: addi sp, sp, 16
375; RV32IFD-NEXT: ret
376 %a_ = fadd double 0.0, %a
377 %c_ = fadd double 0.0, %c
378 %nega = fsub double -0.0, %a_
379 %negc = fsub double -0.0, %c_
380 %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
381 ret double %1
382}
383
384define double @fnmsub_d(double %a, double %b, double %c) nounwind {
385; RV32IFD-LABEL: fnmsub_d:
386; RV32IFD: # %bb.0:
387; RV32IFD-NEXT: addi sp, sp, -16
388; RV32IFD-NEXT: sw a4, 8(sp)
389; RV32IFD-NEXT: sw a5, 12(sp)
390; RV32IFD-NEXT: fld ft0, 8(sp)
391; RV32IFD-NEXT: sw a2, 8(sp)
392; RV32IFD-NEXT: sw a3, 12(sp)
393; RV32IFD-NEXT: fld ft1, 8(sp)
394; RV32IFD-NEXT: sw a0, 8(sp)
395; RV32IFD-NEXT: sw a1, 12(sp)
396; RV32IFD-NEXT: fld ft2, 8(sp)
397; RV32IFD-NEXT: lui a0, %hi(.LCPI17_0)
398; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI17_0)
399; RV32IFD-NEXT: fld ft3, 0(a0)
400; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
401; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0
402; RV32IFD-NEXT: fsd ft0, 8(sp)
403; RV32IFD-NEXT: lw a0, 8(sp)
404; RV32IFD-NEXT: lw a1, 12(sp)
405; RV32IFD-NEXT: addi sp, sp, 16
406; RV32IFD-NEXT: ret
407 %a_ = fadd double 0.0, %a
408 %nega = fsub double -0.0, %a_
409 %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
410 ret double %1
411}