blob: cd3a1d963783236718f29b951806ee289ea4725a [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
89declare double @llvm.sqrt.f32(double)
90
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
104 %1 = call double @llvm.sqrt.f32(double %a)
105 ret double %1
106}
107
108declare double @llvm.copysign.f32(double, double)
109
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
126 %1 = call double @llvm.copysign.f32(double %a, double %b)
127 ret double %1
128}
129
130define double @fneg_d(double %a) nounwind {
131; RV32IFD-LABEL: fneg_d:
132; RV32IFD: # %bb.0:
133; RV32IFD-NEXT: addi sp, sp, -16
134; RV32IFD-NEXT: sw a0, 8(sp)
135; RV32IFD-NEXT: sw a1, 12(sp)
136; RV32IFD-NEXT: fld ft0, 8(sp)
137; RV32IFD-NEXT: fneg.d ft0, ft0
138; RV32IFD-NEXT: fsd ft0, 8(sp)
139; RV32IFD-NEXT: lw a0, 8(sp)
140; RV32IFD-NEXT: lw a1, 12(sp)
141; RV32IFD-NEXT: addi sp, sp, 16
142; RV32IFD-NEXT: ret
143 %1 = fsub double -0.0, %a
144 ret double %1
145}
146
147define double @fsgnjn_d(double %a, double %b) nounwind {
148; RV32IFD-LABEL: fsgnjn_d:
149; RV32IFD: # %bb.0:
150; RV32IFD-NEXT: addi sp, sp, -16
151; RV32IFD-NEXT: sw a2, 8(sp)
152; RV32IFD-NEXT: sw a3, 12(sp)
153; RV32IFD-NEXT: fld ft0, 8(sp)
154; RV32IFD-NEXT: sw a0, 8(sp)
155; RV32IFD-NEXT: sw a1, 12(sp)
156; RV32IFD-NEXT: fld ft1, 8(sp)
157; RV32IFD-NEXT: fsgnjn.d ft0, ft1, ft0
158; RV32IFD-NEXT: fsd ft0, 8(sp)
159; RV32IFD-NEXT: lw a0, 8(sp)
160; RV32IFD-NEXT: lw a1, 12(sp)
161; RV32IFD-NEXT: addi sp, sp, 16
162; RV32IFD-NEXT: ret
163 %1 = fsub double -0.0, %b
164 %2 = call double @llvm.copysign.f32(double %a, double %1)
165 ret double %2
166}
167
168declare double @llvm.fabs.f32(double)
169
170define double @fabs_d(double %a) nounwind {
171; RV32IFD-LABEL: fabs_d:
172; RV32IFD: # %bb.0:
173; RV32IFD-NEXT: addi sp, sp, -16
174; RV32IFD-NEXT: sw a0, 8(sp)
175; RV32IFD-NEXT: sw a1, 12(sp)
176; RV32IFD-NEXT: fld ft0, 8(sp)
177; RV32IFD-NEXT: fabs.d ft0, ft0
178; RV32IFD-NEXT: fsd ft0, 8(sp)
179; RV32IFD-NEXT: lw a0, 8(sp)
180; RV32IFD-NEXT: lw a1, 12(sp)
181; RV32IFD-NEXT: addi sp, sp, 16
182; RV32IFD-NEXT: ret
183 %1 = call double @llvm.fabs.f32(double %a)
184 ret double %1
185}
186
187declare double @llvm.minnum.f32(double, double)
188
189define double @fmin_d(double %a, double %b) nounwind {
190; RV32IFD-LABEL: fmin_d:
191; RV32IFD: # %bb.0:
192; RV32IFD-NEXT: addi sp, sp, -16
193; RV32IFD-NEXT: sw a2, 8(sp)
194; RV32IFD-NEXT: sw a3, 12(sp)
195; RV32IFD-NEXT: fld ft0, 8(sp)
196; RV32IFD-NEXT: sw a0, 8(sp)
197; RV32IFD-NEXT: sw a1, 12(sp)
198; RV32IFD-NEXT: fld ft1, 8(sp)
199; RV32IFD-NEXT: fmin.d ft0, ft1, ft0
200; RV32IFD-NEXT: fsd ft0, 8(sp)
201; RV32IFD-NEXT: lw a0, 8(sp)
202; RV32IFD-NEXT: lw a1, 12(sp)
203; RV32IFD-NEXT: addi sp, sp, 16
204; RV32IFD-NEXT: ret
205 %1 = call double @llvm.minnum.f32(double %a, double %b)
206 ret double %1
207}
208
209declare double @llvm.maxnum.f32(double, double)
210
211define double @fmax_d(double %a, double %b) nounwind {
212; RV32IFD-LABEL: fmax_d:
213; RV32IFD: # %bb.0:
214; RV32IFD-NEXT: addi sp, sp, -16
215; RV32IFD-NEXT: sw a2, 8(sp)
216; RV32IFD-NEXT: sw a3, 12(sp)
217; RV32IFD-NEXT: fld ft0, 8(sp)
218; RV32IFD-NEXT: sw a0, 8(sp)
219; RV32IFD-NEXT: sw a1, 12(sp)
220; RV32IFD-NEXT: fld ft1, 8(sp)
221; RV32IFD-NEXT: fmax.d ft0, ft1, ft0
222; RV32IFD-NEXT: fsd ft0, 8(sp)
223; RV32IFD-NEXT: lw a0, 8(sp)
224; RV32IFD-NEXT: lw a1, 12(sp)
225; RV32IFD-NEXT: addi sp, sp, 16
226; RV32IFD-NEXT: ret
227 %1 = call double @llvm.maxnum.f32(double %a, double %b)
228 ret double %1
229}
230
231define i32 @feq_d(double %a, double %b) nounwind {
232; RV32IFD-LABEL: feq_d:
233; RV32IFD: # %bb.0:
234; RV32IFD-NEXT: addi sp, sp, -16
235; RV32IFD-NEXT: sw a2, 8(sp)
236; RV32IFD-NEXT: sw a3, 12(sp)
237; RV32IFD-NEXT: fld ft0, 8(sp)
238; RV32IFD-NEXT: sw a0, 8(sp)
239; RV32IFD-NEXT: sw a1, 12(sp)
240; RV32IFD-NEXT: fld ft1, 8(sp)
241; RV32IFD-NEXT: feq.d a0, ft1, ft0
242; RV32IFD-NEXT: addi sp, sp, 16
243; RV32IFD-NEXT: ret
244 %1 = fcmp oeq double %a, %b
245 %2 = zext i1 %1 to i32
246 ret i32 %2
247}
248
249define i32 @flt_d(double %a, double %b) nounwind {
250; RV32IFD-LABEL: flt_d:
251; RV32IFD: # %bb.0:
252; RV32IFD-NEXT: addi sp, sp, -16
253; RV32IFD-NEXT: sw a2, 8(sp)
254; RV32IFD-NEXT: sw a3, 12(sp)
255; RV32IFD-NEXT: fld ft0, 8(sp)
256; RV32IFD-NEXT: sw a0, 8(sp)
257; RV32IFD-NEXT: sw a1, 12(sp)
258; RV32IFD-NEXT: fld ft1, 8(sp)
259; RV32IFD-NEXT: flt.d a0, ft1, ft0
260; RV32IFD-NEXT: addi sp, sp, 16
261; RV32IFD-NEXT: ret
262 %1 = fcmp olt double %a, %b
263 %2 = zext i1 %1 to i32
264 ret i32 %2
265}
266
267define i32 @fle_d(double %a, double %b) nounwind {
268; RV32IFD-LABEL: fle_d:
269; RV32IFD: # %bb.0:
270; RV32IFD-NEXT: addi sp, sp, -16
271; RV32IFD-NEXT: sw a2, 8(sp)
272; RV32IFD-NEXT: sw a3, 12(sp)
273; RV32IFD-NEXT: fld ft0, 8(sp)
274; RV32IFD-NEXT: sw a0, 8(sp)
275; RV32IFD-NEXT: sw a1, 12(sp)
276; RV32IFD-NEXT: fld ft1, 8(sp)
277; RV32IFD-NEXT: fle.d a0, ft1, ft0
278; RV32IFD-NEXT: addi sp, sp, 16
279; RV32IFD-NEXT: ret
280 %1 = fcmp ole double %a, %b
281 %2 = zext i1 %1 to i32
282 ret i32 %2
283}
Alex Bradbury919f5fb2018-12-13 10:49:05 +0000284
285declare double @llvm.fma.f64(double, double, double)
286
287define double @fmadd_d(double %a, double %b, double %c) nounwind {
288; RV32IFD-LABEL: fmadd_d:
289; RV32IFD: # %bb.0:
290; RV32IFD-NEXT: addi sp, sp, -16
291; RV32IFD-NEXT: sw a4, 8(sp)
292; RV32IFD-NEXT: sw a5, 12(sp)
293; RV32IFD-NEXT: fld ft0, 8(sp)
294; RV32IFD-NEXT: sw a2, 8(sp)
295; RV32IFD-NEXT: sw a3, 12(sp)
296; RV32IFD-NEXT: fld ft1, 8(sp)
297; RV32IFD-NEXT: sw a0, 8(sp)
298; RV32IFD-NEXT: sw a1, 12(sp)
299; RV32IFD-NEXT: fld ft2, 8(sp)
300; RV32IFD-NEXT: fmadd.d ft0, ft2, ft1, ft0
301; RV32IFD-NEXT: fsd ft0, 8(sp)
302; RV32IFD-NEXT: lw a0, 8(sp)
303; RV32IFD-NEXT: lw a1, 12(sp)
304; RV32IFD-NEXT: addi sp, sp, 16
305; RV32IFD-NEXT: ret
306 %1 = call double @llvm.fma.f64(double %a, double %b, double %c)
307 ret double %1
308}
309
310define double @fmsub_d(double %a, double %b, double %c) nounwind {
311; RV32IFD-LABEL: fmsub_d:
312; RV32IFD: # %bb.0:
313; RV32IFD-NEXT: addi sp, sp, -16
314; RV32IFD-NEXT: sw a2, 8(sp)
315; RV32IFD-NEXT: sw a3, 12(sp)
316; RV32IFD-NEXT: fld ft0, 8(sp)
317; RV32IFD-NEXT: sw a0, 8(sp)
318; RV32IFD-NEXT: sw a1, 12(sp)
319; RV32IFD-NEXT: fld ft1, 8(sp)
320; RV32IFD-NEXT: sw a4, 8(sp)
321; RV32IFD-NEXT: sw a5, 12(sp)
322; RV32IFD-NEXT: fld ft2, 8(sp)
323; RV32IFD-NEXT: lui a0, %hi(.LCPI15_0)
324; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI15_0)
325; RV32IFD-NEXT: fld ft3, 0(a0)
326; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
327; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2
328; RV32IFD-NEXT: fsd ft0, 8(sp)
329; RV32IFD-NEXT: lw a0, 8(sp)
330; RV32IFD-NEXT: lw a1, 12(sp)
331; RV32IFD-NEXT: addi sp, sp, 16
332; RV32IFD-NEXT: ret
333 %c_ = fadd double 0.0, %c ; avoid negation using xor
334 %negc = fsub double -0.0, %c_
335 %1 = call double @llvm.fma.f64(double %a, double %b, double %negc)
336 ret double %1
337}
338
339define double @fnmadd_d(double %a, double %b, double %c) nounwind {
340; RV32IFD-LABEL: fnmadd_d:
341; RV32IFD: # %bb.0:
342; RV32IFD-NEXT: addi sp, sp, -16
343; RV32IFD-NEXT: sw a2, 8(sp)
344; RV32IFD-NEXT: sw a3, 12(sp)
345; RV32IFD-NEXT: fld ft0, 8(sp)
346; RV32IFD-NEXT: sw a0, 8(sp)
347; RV32IFD-NEXT: sw a1, 12(sp)
348; RV32IFD-NEXT: fld ft1, 8(sp)
349; RV32IFD-NEXT: sw a4, 8(sp)
350; RV32IFD-NEXT: sw a5, 12(sp)
351; RV32IFD-NEXT: fld ft2, 8(sp)
352; RV32IFD-NEXT: lui a0, %hi(.LCPI16_0)
353; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI16_0)
354; RV32IFD-NEXT: fld ft3, 0(a0)
355; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
356; RV32IFD-NEXT: fadd.d ft1, ft1, ft3
357; RV32IFD-NEXT: fnmadd.d ft0, ft1, ft0, ft2
358; RV32IFD-NEXT: fsd ft0, 8(sp)
359; RV32IFD-NEXT: lw a0, 8(sp)
360; RV32IFD-NEXT: lw a1, 12(sp)
361; RV32IFD-NEXT: addi sp, sp, 16
362; RV32IFD-NEXT: ret
363 %a_ = fadd double 0.0, %a
364 %c_ = fadd double 0.0, %c
365 %nega = fsub double -0.0, %a_
366 %negc = fsub double -0.0, %c_
367 %1 = call double @llvm.fma.f64(double %nega, double %b, double %negc)
368 ret double %1
369}
370
371define double @fnmsub_d(double %a, double %b, double %c) nounwind {
372; RV32IFD-LABEL: fnmsub_d:
373; RV32IFD: # %bb.0:
374; RV32IFD-NEXT: addi sp, sp, -16
375; RV32IFD-NEXT: sw a4, 8(sp)
376; RV32IFD-NEXT: sw a5, 12(sp)
377; RV32IFD-NEXT: fld ft0, 8(sp)
378; RV32IFD-NEXT: sw a2, 8(sp)
379; RV32IFD-NEXT: sw a3, 12(sp)
380; RV32IFD-NEXT: fld ft1, 8(sp)
381; RV32IFD-NEXT: sw a0, 8(sp)
382; RV32IFD-NEXT: sw a1, 12(sp)
383; RV32IFD-NEXT: fld ft2, 8(sp)
384; RV32IFD-NEXT: lui a0, %hi(.LCPI17_0)
385; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI17_0)
386; RV32IFD-NEXT: fld ft3, 0(a0)
387; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
388; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0
389; RV32IFD-NEXT: fsd ft0, 8(sp)
390; RV32IFD-NEXT: lw a0, 8(sp)
391; RV32IFD-NEXT: lw a1, 12(sp)
392; RV32IFD-NEXT: addi sp, sp, 16
393; RV32IFD-NEXT: ret
394 %a_ = fadd double 0.0, %a
395 %nega = fsub double -0.0, %a_
396 %1 = call double @llvm.fma.f64(double %nega, double %b, double %c)
397 ret double %1
398}