xref: /llvm-project/llvm/test/CodeGen/RISCV/float-maximum-minimum.ll (revision 048458f94c60fc9c200c9dcbcccd4a54ed84b8f9)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+f \
3; RUN:   -verify-machineinstrs -target-abi=ilp32f \
4; RUN:   | FileCheck -check-prefix=RV32IF %s
5; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+zfinx \
6; RUN:   -verify-machineinstrs -target-abi=ilp32 \
7; RUN:   | FileCheck -check-prefix=RV32IZFINX %s
8; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+d \
9; RUN:   -verify-machineinstrs -target-abi=ilp32f \
10; RUN:   | FileCheck -check-prefix=RV32IF %s
11; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+f \
12; RUN:   -verify-machineinstrs -target-abi=lp64f \
13; RUN:   | FileCheck -check-prefix=RV64IF %s
14; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zfinx \
15; RUN:   -verify-machineinstrs -target-abi=lp64 \
16; RUN:   | FileCheck -check-prefix=RV64IZFINX %s
17; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+d \
18; RUN:   -verify-machineinstrs -target-abi=lp64d \
19; RUN:   | FileCheck -check-prefix=RV64IF %s
20
21declare float @llvm.minimum.f32(float, float)
22
23define float @fminimum_f32(float %a, float %b) nounwind {
24; RV32IF-LABEL: fminimum_f32:
25; RV32IF:       # %bb.0:
26; RV32IF-NEXT:    feq.s a0, fa0, fa0
27; RV32IF-NEXT:    fmv.s fa5, fa1
28; RV32IF-NEXT:    beqz a0, .LBB0_3
29; RV32IF-NEXT:  # %bb.1:
30; RV32IF-NEXT:    feq.s a0, fa1, fa1
31; RV32IF-NEXT:    beqz a0, .LBB0_4
32; RV32IF-NEXT:  .LBB0_2:
33; RV32IF-NEXT:    fmin.s fa0, fa0, fa5
34; RV32IF-NEXT:    ret
35; RV32IF-NEXT:  .LBB0_3:
36; RV32IF-NEXT:    fmv.s fa5, fa0
37; RV32IF-NEXT:    feq.s a0, fa1, fa1
38; RV32IF-NEXT:    bnez a0, .LBB0_2
39; RV32IF-NEXT:  .LBB0_4:
40; RV32IF-NEXT:    fmin.s fa0, fa1, fa5
41; RV32IF-NEXT:    ret
42;
43; RV32IZFINX-LABEL: fminimum_f32:
44; RV32IZFINX:       # %bb.0:
45; RV32IZFINX-NEXT:    feq.s a3, a0, a0
46; RV32IZFINX-NEXT:    mv a2, a1
47; RV32IZFINX-NEXT:    beqz a3, .LBB0_3
48; RV32IZFINX-NEXT:  # %bb.1:
49; RV32IZFINX-NEXT:    feq.s a3, a1, a1
50; RV32IZFINX-NEXT:    beqz a3, .LBB0_4
51; RV32IZFINX-NEXT:  .LBB0_2:
52; RV32IZFINX-NEXT:    fmin.s a0, a0, a2
53; RV32IZFINX-NEXT:    ret
54; RV32IZFINX-NEXT:  .LBB0_3:
55; RV32IZFINX-NEXT:    mv a2, a0
56; RV32IZFINX-NEXT:    feq.s a3, a1, a1
57; RV32IZFINX-NEXT:    bnez a3, .LBB0_2
58; RV32IZFINX-NEXT:  .LBB0_4:
59; RV32IZFINX-NEXT:    fmin.s a0, a1, a2
60; RV32IZFINX-NEXT:    ret
61;
62; RV64IF-LABEL: fminimum_f32:
63; RV64IF:       # %bb.0:
64; RV64IF-NEXT:    feq.s a0, fa0, fa0
65; RV64IF-NEXT:    fmv.s fa5, fa1
66; RV64IF-NEXT:    beqz a0, .LBB0_3
67; RV64IF-NEXT:  # %bb.1:
68; RV64IF-NEXT:    feq.s a0, fa1, fa1
69; RV64IF-NEXT:    beqz a0, .LBB0_4
70; RV64IF-NEXT:  .LBB0_2:
71; RV64IF-NEXT:    fmin.s fa0, fa0, fa5
72; RV64IF-NEXT:    ret
73; RV64IF-NEXT:  .LBB0_3:
74; RV64IF-NEXT:    fmv.s fa5, fa0
75; RV64IF-NEXT:    feq.s a0, fa1, fa1
76; RV64IF-NEXT:    bnez a0, .LBB0_2
77; RV64IF-NEXT:  .LBB0_4:
78; RV64IF-NEXT:    fmin.s fa0, fa1, fa5
79; RV64IF-NEXT:    ret
80;
81; RV64IZFINX-LABEL: fminimum_f32:
82; RV64IZFINX:       # %bb.0:
83; RV64IZFINX-NEXT:    feq.s a3, a0, a0
84; RV64IZFINX-NEXT:    mv a2, a1
85; RV64IZFINX-NEXT:    beqz a3, .LBB0_3
86; RV64IZFINX-NEXT:  # %bb.1:
87; RV64IZFINX-NEXT:    feq.s a3, a1, a1
88; RV64IZFINX-NEXT:    beqz a3, .LBB0_4
89; RV64IZFINX-NEXT:  .LBB0_2:
90; RV64IZFINX-NEXT:    fmin.s a0, a0, a2
91; RV64IZFINX-NEXT:    ret
92; RV64IZFINX-NEXT:  .LBB0_3:
93; RV64IZFINX-NEXT:    mv a2, a0
94; RV64IZFINX-NEXT:    feq.s a3, a1, a1
95; RV64IZFINX-NEXT:    bnez a3, .LBB0_2
96; RV64IZFINX-NEXT:  .LBB0_4:
97; RV64IZFINX-NEXT:    fmin.s a0, a1, a2
98; RV64IZFINX-NEXT:    ret
99  %1 = call float @llvm.minimum.f32(float %a, float %b)
100  ret float %1
101}
102
103declare float @llvm.maximum.f32(float, float)
104
105define float @fmaximum_f32(float %a, float %b) nounwind {
106; RV32IF-LABEL: fmaximum_f32:
107; RV32IF:       # %bb.0:
108; RV32IF-NEXT:    feq.s a0, fa0, fa0
109; RV32IF-NEXT:    fmv.s fa5, fa1
110; RV32IF-NEXT:    beqz a0, .LBB1_3
111; RV32IF-NEXT:  # %bb.1:
112; RV32IF-NEXT:    feq.s a0, fa1, fa1
113; RV32IF-NEXT:    beqz a0, .LBB1_4
114; RV32IF-NEXT:  .LBB1_2:
115; RV32IF-NEXT:    fmax.s fa0, fa0, fa5
116; RV32IF-NEXT:    ret
117; RV32IF-NEXT:  .LBB1_3:
118; RV32IF-NEXT:    fmv.s fa5, fa0
119; RV32IF-NEXT:    feq.s a0, fa1, fa1
120; RV32IF-NEXT:    bnez a0, .LBB1_2
121; RV32IF-NEXT:  .LBB1_4:
122; RV32IF-NEXT:    fmax.s fa0, fa1, fa5
123; RV32IF-NEXT:    ret
124;
125; RV32IZFINX-LABEL: fmaximum_f32:
126; RV32IZFINX:       # %bb.0:
127; RV32IZFINX-NEXT:    feq.s a3, a0, a0
128; RV32IZFINX-NEXT:    mv a2, a1
129; RV32IZFINX-NEXT:    beqz a3, .LBB1_3
130; RV32IZFINX-NEXT:  # %bb.1:
131; RV32IZFINX-NEXT:    feq.s a3, a1, a1
132; RV32IZFINX-NEXT:    beqz a3, .LBB1_4
133; RV32IZFINX-NEXT:  .LBB1_2:
134; RV32IZFINX-NEXT:    fmax.s a0, a0, a2
135; RV32IZFINX-NEXT:    ret
136; RV32IZFINX-NEXT:  .LBB1_3:
137; RV32IZFINX-NEXT:    mv a2, a0
138; RV32IZFINX-NEXT:    feq.s a3, a1, a1
139; RV32IZFINX-NEXT:    bnez a3, .LBB1_2
140; RV32IZFINX-NEXT:  .LBB1_4:
141; RV32IZFINX-NEXT:    fmax.s a0, a1, a2
142; RV32IZFINX-NEXT:    ret
143;
144; RV64IF-LABEL: fmaximum_f32:
145; RV64IF:       # %bb.0:
146; RV64IF-NEXT:    feq.s a0, fa0, fa0
147; RV64IF-NEXT:    fmv.s fa5, fa1
148; RV64IF-NEXT:    beqz a0, .LBB1_3
149; RV64IF-NEXT:  # %bb.1:
150; RV64IF-NEXT:    feq.s a0, fa1, fa1
151; RV64IF-NEXT:    beqz a0, .LBB1_4
152; RV64IF-NEXT:  .LBB1_2:
153; RV64IF-NEXT:    fmax.s fa0, fa0, fa5
154; RV64IF-NEXT:    ret
155; RV64IF-NEXT:  .LBB1_3:
156; RV64IF-NEXT:    fmv.s fa5, fa0
157; RV64IF-NEXT:    feq.s a0, fa1, fa1
158; RV64IF-NEXT:    bnez a0, .LBB1_2
159; RV64IF-NEXT:  .LBB1_4:
160; RV64IF-NEXT:    fmax.s fa0, fa1, fa5
161; RV64IF-NEXT:    ret
162;
163; RV64IZFINX-LABEL: fmaximum_f32:
164; RV64IZFINX:       # %bb.0:
165; RV64IZFINX-NEXT:    feq.s a3, a0, a0
166; RV64IZFINX-NEXT:    mv a2, a1
167; RV64IZFINX-NEXT:    beqz a3, .LBB1_3
168; RV64IZFINX-NEXT:  # %bb.1:
169; RV64IZFINX-NEXT:    feq.s a3, a1, a1
170; RV64IZFINX-NEXT:    beqz a3, .LBB1_4
171; RV64IZFINX-NEXT:  .LBB1_2:
172; RV64IZFINX-NEXT:    fmax.s a0, a0, a2
173; RV64IZFINX-NEXT:    ret
174; RV64IZFINX-NEXT:  .LBB1_3:
175; RV64IZFINX-NEXT:    mv a2, a0
176; RV64IZFINX-NEXT:    feq.s a3, a1, a1
177; RV64IZFINX-NEXT:    bnez a3, .LBB1_2
178; RV64IZFINX-NEXT:  .LBB1_4:
179; RV64IZFINX-NEXT:    fmax.s a0, a1, a2
180; RV64IZFINX-NEXT:    ret
181  %1 = call float @llvm.maximum.f32(float %a, float %b)
182  ret float %1
183}
184
185define float @fminimum_nnan_f32(float %a, float %b) nounwind {
186; RV32IF-LABEL: fminimum_nnan_f32:
187; RV32IF:       # %bb.0:
188; RV32IF-NEXT:    fmin.s fa0, fa0, fa1
189; RV32IF-NEXT:    ret
190;
191; RV32IZFINX-LABEL: fminimum_nnan_f32:
192; RV32IZFINX:       # %bb.0:
193; RV32IZFINX-NEXT:    fmin.s a0, a0, a1
194; RV32IZFINX-NEXT:    ret
195;
196; RV64IF-LABEL: fminimum_nnan_f32:
197; RV64IF:       # %bb.0:
198; RV64IF-NEXT:    fmin.s fa0, fa0, fa1
199; RV64IF-NEXT:    ret
200;
201; RV64IZFINX-LABEL: fminimum_nnan_f32:
202; RV64IZFINX:       # %bb.0:
203; RV64IZFINX-NEXT:    fmin.s a0, a0, a1
204; RV64IZFINX-NEXT:    ret
205  %1 = call nnan float @llvm.minimum.f32(float %a, float %b)
206  ret float %1
207}
208
209define float @fmaximum_nnan_f32(float %a, float %b) nounwind {
210; RV32IF-LABEL: fmaximum_nnan_f32:
211; RV32IF:       # %bb.0:
212; RV32IF-NEXT:    fmax.s fa0, fa0, fa1
213; RV32IF-NEXT:    ret
214;
215; RV32IZFINX-LABEL: fmaximum_nnan_f32:
216; RV32IZFINX:       # %bb.0:
217; RV32IZFINX-NEXT:    fmax.s a0, a0, a1
218; RV32IZFINX-NEXT:    ret
219;
220; RV64IF-LABEL: fmaximum_nnan_f32:
221; RV64IF:       # %bb.0:
222; RV64IF-NEXT:    fmax.s fa0, fa0, fa1
223; RV64IF-NEXT:    ret
224;
225; RV64IZFINX-LABEL: fmaximum_nnan_f32:
226; RV64IZFINX:       # %bb.0:
227; RV64IZFINX-NEXT:    fmax.s a0, a0, a1
228; RV64IZFINX-NEXT:    ret
229  %1 = call nnan float @llvm.maximum.f32(float %a, float %b)
230  ret float %1
231}
232
233define float @fminimum_nnan_attr_f32(float %a, float %b) nounwind "no-nans-fp-math"="true" {
234; RV32IF-LABEL: fminimum_nnan_attr_f32:
235; RV32IF:       # %bb.0:
236; RV32IF-NEXT:    fmin.s fa0, fa0, fa1
237; RV32IF-NEXT:    ret
238;
239; RV32IZFINX-LABEL: fminimum_nnan_attr_f32:
240; RV32IZFINX:       # %bb.0:
241; RV32IZFINX-NEXT:    fmin.s a0, a0, a1
242; RV32IZFINX-NEXT:    ret
243;
244; RV64IF-LABEL: fminimum_nnan_attr_f32:
245; RV64IF:       # %bb.0:
246; RV64IF-NEXT:    fmin.s fa0, fa0, fa1
247; RV64IF-NEXT:    ret
248;
249; RV64IZFINX-LABEL: fminimum_nnan_attr_f32:
250; RV64IZFINX:       # %bb.0:
251; RV64IZFINX-NEXT:    fmin.s a0, a0, a1
252; RV64IZFINX-NEXT:    ret
253  %1 = call float @llvm.minimum.f32(float %a, float %b)
254  ret float %1
255}
256
257define float @fminimum_nnan_op_f32(float %a, float %b) nounwind {
258; RV32IF-LABEL: fminimum_nnan_op_f32:
259; RV32IF:       # %bb.0:
260; RV32IF-NEXT:    feq.s a0, fa0, fa0
261; RV32IF-NEXT:    bnez a0, .LBB5_2
262; RV32IF-NEXT:  # %bb.1:
263; RV32IF-NEXT:    fmin.s fa0, fa0, fa0
264; RV32IF-NEXT:    ret
265; RV32IF-NEXT:  .LBB5_2:
266; RV32IF-NEXT:    fadd.s fa5, fa0, fa0
267; RV32IF-NEXT:    fmin.s fa0, fa0, fa5
268; RV32IF-NEXT:    ret
269;
270; RV32IZFINX-LABEL: fminimum_nnan_op_f32:
271; RV32IZFINX:       # %bb.0:
272; RV32IZFINX-NEXT:    feq.s a1, a0, a0
273; RV32IZFINX-NEXT:    bnez a1, .LBB5_2
274; RV32IZFINX-NEXT:  # %bb.1:
275; RV32IZFINX-NEXT:    fmin.s a0, a0, a0
276; RV32IZFINX-NEXT:    ret
277; RV32IZFINX-NEXT:  .LBB5_2:
278; RV32IZFINX-NEXT:    fadd.s a1, a0, a0
279; RV32IZFINX-NEXT:    fmin.s a0, a0, a1
280; RV32IZFINX-NEXT:    ret
281;
282; RV64IF-LABEL: fminimum_nnan_op_f32:
283; RV64IF:       # %bb.0:
284; RV64IF-NEXT:    feq.s a0, fa0, fa0
285; RV64IF-NEXT:    bnez a0, .LBB5_2
286; RV64IF-NEXT:  # %bb.1:
287; RV64IF-NEXT:    fmin.s fa0, fa0, fa0
288; RV64IF-NEXT:    ret
289; RV64IF-NEXT:  .LBB5_2:
290; RV64IF-NEXT:    fadd.s fa5, fa0, fa0
291; RV64IF-NEXT:    fmin.s fa0, fa0, fa5
292; RV64IF-NEXT:    ret
293;
294; RV64IZFINX-LABEL: fminimum_nnan_op_f32:
295; RV64IZFINX:       # %bb.0:
296; RV64IZFINX-NEXT:    feq.s a1, a0, a0
297; RV64IZFINX-NEXT:    bnez a1, .LBB5_2
298; RV64IZFINX-NEXT:  # %bb.1:
299; RV64IZFINX-NEXT:    fmin.s a0, a0, a0
300; RV64IZFINX-NEXT:    ret
301; RV64IZFINX-NEXT:  .LBB5_2:
302; RV64IZFINX-NEXT:    fadd.s a1, a0, a0
303; RV64IZFINX-NEXT:    fmin.s a0, a0, a1
304; RV64IZFINX-NEXT:    ret
305  %c = fadd nnan float %a, %a
306  %1 = call float @llvm.minimum.f32(float %a, float %c)
307  ret float %1
308}
309
310define float @fmaximum_nnan_op_f32(float %a, float %b) nounwind {
311; RV32IF-LABEL: fmaximum_nnan_op_f32:
312; RV32IF:       # %bb.0:
313; RV32IF-NEXT:    fadd.s fa5, fa0, fa1
314; RV32IF-NEXT:    fsub.s fa4, fa0, fa1
315; RV32IF-NEXT:    fmax.s fa0, fa5, fa4
316; RV32IF-NEXT:    ret
317;
318; RV32IZFINX-LABEL: fmaximum_nnan_op_f32:
319; RV32IZFINX:       # %bb.0:
320; RV32IZFINX-NEXT:    fadd.s a2, a0, a1
321; RV32IZFINX-NEXT:    fsub.s a0, a0, a1
322; RV32IZFINX-NEXT:    fmax.s a0, a2, a0
323; RV32IZFINX-NEXT:    ret
324;
325; RV64IF-LABEL: fmaximum_nnan_op_f32:
326; RV64IF:       # %bb.0:
327; RV64IF-NEXT:    fadd.s fa5, fa0, fa1
328; RV64IF-NEXT:    fsub.s fa4, fa0, fa1
329; RV64IF-NEXT:    fmax.s fa0, fa5, fa4
330; RV64IF-NEXT:    ret
331;
332; RV64IZFINX-LABEL: fmaximum_nnan_op_f32:
333; RV64IZFINX:       # %bb.0:
334; RV64IZFINX-NEXT:    fadd.s a2, a0, a1
335; RV64IZFINX-NEXT:    fsub.s a0, a0, a1
336; RV64IZFINX-NEXT:    fmax.s a0, a2, a0
337; RV64IZFINX-NEXT:    ret
338  %c = fadd nnan float %a, %b
339  %d = fsub nnan float %a, %b
340  %1 = call float @llvm.maximum.f32(float %c, float %d)
341  ret float %1
342}
343