xref: /llvm-project/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll (revision 576d81baa5cf1801bae0fd05892be34acde33c6a)
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=+d \
3; RUN:   -verify-machineinstrs -target-abi=ilp32d \
4; RUN:   | FileCheck -check-prefixes=CHECKIFD,RV32IFD %s
5; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+d \
6; RUN:   -verify-machineinstrs -target-abi=lp64d \
7; RUN:   | FileCheck -check-prefixes=CHECKIFD,RV64IFD %s
8; RUN: sed 's/iXLen/i32/g' %s | llc -mtriple=riscv32 -mattr=+zdinx \
9; RUN:   -verify-machineinstrs -target-abi=ilp32 \
10; RUN:   | FileCheck -check-prefix=RV32IZFINXZDINX %s
11; RUN: sed 's/iXLen/i64/g' %s | llc -mtriple=riscv64 -mattr=+zdinx \
12; RUN:   -verify-machineinstrs -target-abi=lp64 \
13; RUN:   | FileCheck -check-prefix=RV64IZFINXZDINX %s
14
15declare double @llvm.minimum.f64(double, double)
16
17define double @fminimum_f64(double %a, double %b) nounwind {
18; CHECKIFD-LABEL: fminimum_f64:
19; CHECKIFD:       # %bb.0:
20; CHECKIFD-NEXT:    feq.d a0, fa0, fa0
21; CHECKIFD-NEXT:    fmv.d fa5, fa1
22; CHECKIFD-NEXT:    beqz a0, .LBB0_3
23; CHECKIFD-NEXT:  # %bb.1:
24; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
25; CHECKIFD-NEXT:    beqz a0, .LBB0_4
26; CHECKIFD-NEXT:  .LBB0_2:
27; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa5
28; CHECKIFD-NEXT:    ret
29; CHECKIFD-NEXT:  .LBB0_3:
30; CHECKIFD-NEXT:    fmv.d fa5, fa0
31; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
32; CHECKIFD-NEXT:    bnez a0, .LBB0_2
33; CHECKIFD-NEXT:  .LBB0_4:
34; CHECKIFD-NEXT:    fmin.d fa0, fa1, fa5
35; CHECKIFD-NEXT:    ret
36;
37; RV32IZFINXZDINX-LABEL: fminimum_f64:
38; RV32IZFINXZDINX:       # %bb.0:
39; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
40; RV32IZFINXZDINX-NEXT:    mv a4, a2
41; RV32IZFINXZDINX-NEXT:    mv a5, a3
42; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB0_3
43; RV32IZFINXZDINX-NEXT:  # %bb.1:
44; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
45; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB0_4
46; RV32IZFINXZDINX-NEXT:  .LBB0_2:
47; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
48; RV32IZFINXZDINX-NEXT:    ret
49; RV32IZFINXZDINX-NEXT:  .LBB0_3:
50; RV32IZFINXZDINX-NEXT:    mv a4, a0
51; RV32IZFINXZDINX-NEXT:    mv a5, a1
52; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
53; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB0_2
54; RV32IZFINXZDINX-NEXT:  .LBB0_4:
55; RV32IZFINXZDINX-NEXT:    mv a0, a2
56; RV32IZFINXZDINX-NEXT:    mv a1, a3
57; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
58; RV32IZFINXZDINX-NEXT:    ret
59;
60; RV64IZFINXZDINX-LABEL: fminimum_f64:
61; RV64IZFINXZDINX:       # %bb.0:
62; RV64IZFINXZDINX-NEXT:    feq.d a3, a0, a0
63; RV64IZFINXZDINX-NEXT:    mv a2, a1
64; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB0_3
65; RV64IZFINXZDINX-NEXT:  # %bb.1:
66; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
67; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB0_4
68; RV64IZFINXZDINX-NEXT:  .LBB0_2:
69; RV64IZFINXZDINX-NEXT:    fmin.d a0, a0, a2
70; RV64IZFINXZDINX-NEXT:    ret
71; RV64IZFINXZDINX-NEXT:  .LBB0_3:
72; RV64IZFINXZDINX-NEXT:    mv a2, a0
73; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
74; RV64IZFINXZDINX-NEXT:    bnez a3, .LBB0_2
75; RV64IZFINXZDINX-NEXT:  .LBB0_4:
76; RV64IZFINXZDINX-NEXT:    fmin.d a0, a1, a2
77; RV64IZFINXZDINX-NEXT:    ret
78  %1 = call double @llvm.minimum.f64(double %a, double %b)
79  ret double %1
80}
81
82declare double @llvm.maximum.f64(double, double)
83
84define double @fmaximum_f64(double %a, double %b) nounwind {
85; CHECKIFD-LABEL: fmaximum_f64:
86; CHECKIFD:       # %bb.0:
87; CHECKIFD-NEXT:    feq.d a0, fa0, fa0
88; CHECKIFD-NEXT:    fmv.d fa5, fa1
89; CHECKIFD-NEXT:    beqz a0, .LBB1_3
90; CHECKIFD-NEXT:  # %bb.1:
91; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
92; CHECKIFD-NEXT:    beqz a0, .LBB1_4
93; CHECKIFD-NEXT:  .LBB1_2:
94; CHECKIFD-NEXT:    fmax.d fa0, fa0, fa5
95; CHECKIFD-NEXT:    ret
96; CHECKIFD-NEXT:  .LBB1_3:
97; CHECKIFD-NEXT:    fmv.d fa5, fa0
98; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
99; CHECKIFD-NEXT:    bnez a0, .LBB1_2
100; CHECKIFD-NEXT:  .LBB1_4:
101; CHECKIFD-NEXT:    fmax.d fa0, fa1, fa5
102; CHECKIFD-NEXT:    ret
103;
104; RV32IZFINXZDINX-LABEL: fmaximum_f64:
105; RV32IZFINXZDINX:       # %bb.0:
106; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
107; RV32IZFINXZDINX-NEXT:    mv a4, a2
108; RV32IZFINXZDINX-NEXT:    mv a5, a3
109; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB1_3
110; RV32IZFINXZDINX-NEXT:  # %bb.1:
111; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
112; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB1_4
113; RV32IZFINXZDINX-NEXT:  .LBB1_2:
114; RV32IZFINXZDINX-NEXT:    fmax.d a0, a0, a4
115; RV32IZFINXZDINX-NEXT:    ret
116; RV32IZFINXZDINX-NEXT:  .LBB1_3:
117; RV32IZFINXZDINX-NEXT:    mv a4, a0
118; RV32IZFINXZDINX-NEXT:    mv a5, a1
119; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
120; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB1_2
121; RV32IZFINXZDINX-NEXT:  .LBB1_4:
122; RV32IZFINXZDINX-NEXT:    mv a0, a2
123; RV32IZFINXZDINX-NEXT:    mv a1, a3
124; RV32IZFINXZDINX-NEXT:    fmax.d a0, a0, a4
125; RV32IZFINXZDINX-NEXT:    ret
126;
127; RV64IZFINXZDINX-LABEL: fmaximum_f64:
128; RV64IZFINXZDINX:       # %bb.0:
129; RV64IZFINXZDINX-NEXT:    feq.d a3, a0, a0
130; RV64IZFINXZDINX-NEXT:    mv a2, a1
131; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB1_3
132; RV64IZFINXZDINX-NEXT:  # %bb.1:
133; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
134; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB1_4
135; RV64IZFINXZDINX-NEXT:  .LBB1_2:
136; RV64IZFINXZDINX-NEXT:    fmax.d a0, a0, a2
137; RV64IZFINXZDINX-NEXT:    ret
138; RV64IZFINXZDINX-NEXT:  .LBB1_3:
139; RV64IZFINXZDINX-NEXT:    mv a2, a0
140; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
141; RV64IZFINXZDINX-NEXT:    bnez a3, .LBB1_2
142; RV64IZFINXZDINX-NEXT:  .LBB1_4:
143; RV64IZFINXZDINX-NEXT:    fmax.d a0, a1, a2
144; RV64IZFINXZDINX-NEXT:    ret
145  %1 = call double @llvm.maximum.f64(double %a, double %b)
146  ret double %1
147}
148
149define double @fminimum_nnan_f64(double %a, double %b) nounwind {
150; CHECKIFD-LABEL: fminimum_nnan_f64:
151; CHECKIFD:       # %bb.0:
152; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa1
153; CHECKIFD-NEXT:    ret
154;
155; RV32IZFINXZDINX-LABEL: fminimum_nnan_f64:
156; RV32IZFINXZDINX:       # %bb.0:
157; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a2
158; RV32IZFINXZDINX-NEXT:    ret
159;
160; RV64IZFINXZDINX-LABEL: fminimum_nnan_f64:
161; RV64IZFINXZDINX:       # %bb.0:
162; RV64IZFINXZDINX-NEXT:    fmin.d a0, a0, a1
163; RV64IZFINXZDINX-NEXT:    ret
164  %1 = call nnan double @llvm.minimum.f64(double %a, double %b)
165  ret double %1
166}
167
168define double @fmaximum_nnan_f64(double %a, double %b) nounwind {
169; CHECKIFD-LABEL: fmaximum_nnan_f64:
170; CHECKIFD:       # %bb.0:
171; CHECKIFD-NEXT:    feq.d a0, fa0, fa0
172; CHECKIFD-NEXT:    fmv.d fa5, fa1
173; CHECKIFD-NEXT:    beqz a0, .LBB3_3
174; CHECKIFD-NEXT:  # %bb.1:
175; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
176; CHECKIFD-NEXT:    beqz a0, .LBB3_4
177; CHECKIFD-NEXT:  .LBB3_2:
178; CHECKIFD-NEXT:    fmin.d fa0, fa0, fa5
179; CHECKIFD-NEXT:    ret
180; CHECKIFD-NEXT:  .LBB3_3:
181; CHECKIFD-NEXT:    fmv.d fa5, fa0
182; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
183; CHECKIFD-NEXT:    bnez a0, .LBB3_2
184; CHECKIFD-NEXT:  .LBB3_4:
185; CHECKIFD-NEXT:    fmin.d fa0, fa1, fa5
186; CHECKIFD-NEXT:    ret
187;
188; RV32IZFINXZDINX-LABEL: fmaximum_nnan_f64:
189; RV32IZFINXZDINX:       # %bb.0:
190; RV32IZFINXZDINX-NEXT:    feq.d a6, a0, a0
191; RV32IZFINXZDINX-NEXT:    mv a4, a2
192; RV32IZFINXZDINX-NEXT:    mv a5, a3
193; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB3_3
194; RV32IZFINXZDINX-NEXT:  # %bb.1:
195; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
196; RV32IZFINXZDINX-NEXT:    beqz a6, .LBB3_4
197; RV32IZFINXZDINX-NEXT:  .LBB3_2:
198; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
199; RV32IZFINXZDINX-NEXT:    ret
200; RV32IZFINXZDINX-NEXT:  .LBB3_3:
201; RV32IZFINXZDINX-NEXT:    mv a4, a0
202; RV32IZFINXZDINX-NEXT:    mv a5, a1
203; RV32IZFINXZDINX-NEXT:    feq.d a6, a2, a2
204; RV32IZFINXZDINX-NEXT:    bnez a6, .LBB3_2
205; RV32IZFINXZDINX-NEXT:  .LBB3_4:
206; RV32IZFINXZDINX-NEXT:    mv a0, a2
207; RV32IZFINXZDINX-NEXT:    mv a1, a3
208; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a4
209; RV32IZFINXZDINX-NEXT:    ret
210;
211; RV64IZFINXZDINX-LABEL: fmaximum_nnan_f64:
212; RV64IZFINXZDINX:       # %bb.0:
213; RV64IZFINXZDINX-NEXT:    feq.d a3, a0, a0
214; RV64IZFINXZDINX-NEXT:    mv a2, a1
215; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB3_3
216; RV64IZFINXZDINX-NEXT:  # %bb.1:
217; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
218; RV64IZFINXZDINX-NEXT:    beqz a3, .LBB3_4
219; RV64IZFINXZDINX-NEXT:  .LBB3_2:
220; RV64IZFINXZDINX-NEXT:    fmin.d a0, a0, a2
221; RV64IZFINXZDINX-NEXT:    ret
222; RV64IZFINXZDINX-NEXT:  .LBB3_3:
223; RV64IZFINXZDINX-NEXT:    mv a2, a0
224; RV64IZFINXZDINX-NEXT:    feq.d a3, a1, a1
225; RV64IZFINXZDINX-NEXT:    bnez a3, .LBB3_2
226; RV64IZFINXZDINX-NEXT:  .LBB3_4:
227; RV64IZFINXZDINX-NEXT:    fmin.d a0, a1, a2
228; RV64IZFINXZDINX-NEXT:    ret
229  %1 = call double @llvm.minimum.f64(double %a, double %b)
230  ret double %1
231}
232
233define double @fminimum_nnan_op_f64(double %a, double %b) nounwind {
234; CHECKIFD-LABEL: fminimum_nnan_op_f64:
235; CHECKIFD:       # %bb.0:
236; CHECKIFD-NEXT:    feq.d a0, fa1, fa1
237; CHECKIFD-NEXT:    bnez a0, .LBB4_2
238; CHECKIFD-NEXT:  # %bb.1:
239; CHECKIFD-NEXT:    fmin.d fa0, fa1, fa1
240; CHECKIFD-NEXT:    ret
241; CHECKIFD-NEXT:  .LBB4_2:
242; CHECKIFD-NEXT:    fadd.d fa5, fa0, fa0
243; CHECKIFD-NEXT:    fmin.d fa0, fa5, fa1
244; CHECKIFD-NEXT:    ret
245;
246; RV32IZFINXZDINX-LABEL: fminimum_nnan_op_f64:
247; RV32IZFINXZDINX:       # %bb.0:
248; RV32IZFINXZDINX-NEXT:    feq.d a4, a2, a2
249; RV32IZFINXZDINX-NEXT:    bnez a4, .LBB4_2
250; RV32IZFINXZDINX-NEXT:  # %bb.1:
251; RV32IZFINXZDINX-NEXT:    fmin.d a0, a2, a2
252; RV32IZFINXZDINX-NEXT:    ret
253; RV32IZFINXZDINX-NEXT:  .LBB4_2:
254; RV32IZFINXZDINX-NEXT:    fadd.d a0, a0, a0
255; RV32IZFINXZDINX-NEXT:    fmin.d a0, a0, a2
256; RV32IZFINXZDINX-NEXT:    ret
257;
258; RV64IZFINXZDINX-LABEL: fminimum_nnan_op_f64:
259; RV64IZFINXZDINX:       # %bb.0:
260; RV64IZFINXZDINX-NEXT:    feq.d a2, a1, a1
261; RV64IZFINXZDINX-NEXT:    bnez a2, .LBB4_2
262; RV64IZFINXZDINX-NEXT:  # %bb.1:
263; RV64IZFINXZDINX-NEXT:    fmin.d a0, a1, a1
264; RV64IZFINXZDINX-NEXT:    ret
265; RV64IZFINXZDINX-NEXT:  .LBB4_2:
266; RV64IZFINXZDINX-NEXT:    fadd.d a0, a0, a0
267; RV64IZFINXZDINX-NEXT:    fmin.d a0, a0, a1
268; RV64IZFINXZDINX-NEXT:    ret
269  %c = fadd nnan double %a, %a
270  %1 = call double @llvm.minimum.f64(double %c, double %b)
271  ret double %1
272}
273
274define double @fmaximum_nnan_op_f64(double %a, double %b) nounwind {
275; CHECKIFD-LABEL: fmaximum_nnan_op_f64:
276; CHECKIFD:       # %bb.0:
277; CHECKIFD-NEXT:    fadd.d fa5, fa0, fa1
278; CHECKIFD-NEXT:    fsub.d fa4, fa0, fa1
279; CHECKIFD-NEXT:    fmax.d fa0, fa5, fa4
280; CHECKIFD-NEXT:    ret
281;
282; RV32IZFINXZDINX-LABEL: fmaximum_nnan_op_f64:
283; RV32IZFINXZDINX:       # %bb.0:
284; RV32IZFINXZDINX-NEXT:    fadd.d a4, a0, a2
285; RV32IZFINXZDINX-NEXT:    fsub.d a0, a0, a2
286; RV32IZFINXZDINX-NEXT:    fmax.d a0, a4, a0
287; RV32IZFINXZDINX-NEXT:    ret
288;
289; RV64IZFINXZDINX-LABEL: fmaximum_nnan_op_f64:
290; RV64IZFINXZDINX:       # %bb.0:
291; RV64IZFINXZDINX-NEXT:    fadd.d a2, a0, a1
292; RV64IZFINXZDINX-NEXT:    fsub.d a0, a0, a1
293; RV64IZFINXZDINX-NEXT:    fmax.d a0, a2, a0
294; RV64IZFINXZDINX-NEXT:    ret
295  %c = fadd nnan double %a, %b
296  %d = fsub nnan double %a, %b
297  %1 = call double @llvm.maximum.f64(double %c, double %d)
298  ret double %1
299}
300
301;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
302; RV32IFD: {{.*}}
303; RV64IFD: {{.*}}
304