1; RUN: llc < %s -mtriple armv8 -mattr=+neon,+fp-armv8 -enable-unsafe-fp-math -enable-no-nans-fp-math | FileCheck %s
2
3; scalars
4
5define float @fp-armv8_vminnm_o(float %a, float %b) {
6; CHECK-LABEL: "fp-armv8_vminnm_o":
7; CHECK-NOT: vcmp
8; CHECK: vminnm.f32
9  %cmp = fcmp fast olt float %a, %b
10  %cond = select i1 %cmp, float %a, float %b
11  ret float %cond
12}
13
14define double @fp-armv8_vminnm_ole(double %a, double %b) {
15; CHECK-LABEL: "fp-armv8_vminnm_ole":
16; CHECK-NOT: vcmp
17; CHECK: vminnm.f64
18  %cmp = fcmp fast ole double %a, %b
19  %cond = select i1 %cmp, double %a, double %b
20  ret double %cond
21}
22
23define float @fp-armv8_vminnm_o_rev(float %a, float %b) {
24; CHECK-LABEL: "fp-armv8_vminnm_o_rev":
25; CHECK-NOT: vcmp
26; CHECK: vminnm.f32
27  %cmp = fcmp fast ogt float %a, %b
28  %cond = select i1 %cmp, float %b, float %a
29  ret float %cond
30}
31
32define double @fp-armv8_vminnm_oge_rev(double %a, double %b) {
33; CHECK-LABEL: "fp-armv8_vminnm_oge_rev":
34; CHECK-NOT: vcmp
35; CHECK: vminnm.f64
36  %cmp = fcmp fast oge double %a, %b
37  %cond = select i1 %cmp, double %b, double %a
38  ret double %cond
39}
40
41define float @fp-armv8_vminnm_u(float %a, float %b) {
42; CHECK-LABEL: "fp-armv8_vminnm_u":
43; CHECK-NOT: vcmp
44; CHECK: vminnm.f32
45  %cmp = fcmp fast ult float %a, %b
46  %cond = select i1 %cmp, float %a, float %b
47  ret float %cond
48}
49
50define float @fp-armv8_vminnm_ule(float %a, float %b) {
51; CHECK-LABEL: "fp-armv8_vminnm_ule":
52; CHECK-NOT: vcmp
53; CHECK: vminnm.f32
54  %cmp = fcmp fast ule float %a, %b
55  %cond = select i1 %cmp, float %a, float %b
56  ret float %cond
57}
58
59define float @fp-armv8_vminnm_u_rev(float %a, float %b) {
60; CHECK-LABEL: "fp-armv8_vminnm_u_rev":
61; CHECK-NOT: vcmp
62; CHECK: vminnm.f32
63  %cmp = fcmp fast ugt float %a, %b
64  %cond = select i1 %cmp, float %b, float %a
65  ret float %cond
66}
67
68define double @fp-armv8_vminnm_uge_rev(double %a, double %b) {
69; CHECK-LABEL: "fp-armv8_vminnm_uge_rev":
70; CHECK-NOT: vcmp
71; CHECK: vminnm.f64
72  %cmp = fcmp fast uge double %a, %b
73  %cond = select i1 %cmp, double %b, double %a
74  ret double %cond
75}
76
77define float @fp-armv8_vmaxnm_o(float %a, float %b) {
78; CHECK-LABEL: "fp-armv8_vmaxnm_o":
79; CHECK-NOT: vcmp
80; CHECK: vmaxnm.f32
81  %cmp = fcmp fast ogt float %a, %b
82  %cond = select i1 %cmp, float %a, float %b
83  ret float %cond
84}
85
86define float @fp-armv8_vmaxnm_oge(float %a, float %b) {
87; CHECK-LABEL: "fp-armv8_vmaxnm_oge":
88; CHECK-NOT: vcmp
89; CHECK: vmaxnm.f32
90  %cmp = fcmp fast oge float %a, %b
91  %cond = select i1 %cmp, float %a, float %b
92  ret float %cond
93}
94
95define float @fp-armv8_vmaxnm_o_rev(float %a, float %b) {
96; CHECK-LABEL: "fp-armv8_vmaxnm_o_rev":
97; CHECK-NOT: vcmp
98; CHECK: vmaxnm.f32
99  %cmp = fcmp fast olt float %a, %b
100  %cond = select i1 %cmp, float %b, float %a
101  ret float %cond
102}
103
104define float @fp-armv8_vmaxnm_ole_rev(float %a, float %b) {
105; CHECK-LABEL: "fp-armv8_vmaxnm_ole_rev":
106; CHECK-NOT: vcmp
107; CHECK: vmaxnm.f32
108  %cmp = fcmp fast ole float %a, %b
109  %cond = select i1 %cmp, float %b, float %a
110  ret float %cond
111}
112
113define float @fp-armv8_vmaxnm_u(float %a, float %b) {
114; CHECK-LABEL: "fp-armv8_vmaxnm_u":
115; CHECK-NOT: vcmp
116; CHECK: vmaxnm.f32
117  %cmp = fcmp fast ugt float %a, %b
118  %cond = select i1 %cmp, float %a, float %b
119  ret float %cond
120}
121
122define float @fp-armv8_vmaxnm_uge(float %a, float %b) {
123; CHECK-LABEL: "fp-armv8_vmaxnm_uge":
124; CHECK-NOT: vcmp
125; CHECK: vmaxnm.f32
126  %cmp = fcmp fast uge float %a, %b
127  %cond = select i1 %cmp, float %a, float %b
128  ret float %cond
129}
130
131define float @fp-armv8_vmaxnm_u_rev(float %a, float %b) {
132; CHECK-LABEL: "fp-armv8_vmaxnm_u_rev":
133; CHECK-NOT: vcmp
134; CHECK: vmaxnm.f32
135  %cmp = fcmp fast ult float %a, %b
136  %cond = select i1 %cmp, float %b, float %a
137  ret float %cond
138}
139
140define double @fp-armv8_vmaxnm_ule_rev(double %a, double %b) {
141; CHECK-LABEL: "fp-armv8_vmaxnm_ule_rev":
142; CHECK-NOT: vcmp
143; CHECK: vmaxnm.f64
144  %cmp = fcmp fast ule double %a, %b
145  %cond = select i1 %cmp, double %b, double %a
146  ret double %cond
147}
148
149; known non-NaNs
150
151define float @fp-armv8_vminnm_NNNo(float %a) {
152; CHECK-LABEL: "fp-armv8_vminnm_NNNo":
153; CHECK: vminnm.f32
154; CHECK: vminnm.f32
155  %cmp1 = fcmp fast olt float %a, 12.
156  %cond1 = select i1 %cmp1, float %a, float 12.
157  %cmp2 = fcmp fast olt float 34., %cond1
158  %cond2 = select i1 %cmp2, float 34., float %cond1
159  ret float %cond2
160}
161
162define double @fp-armv8_vminnm_NNNole(double %a) {
163; CHECK-LABEL: "fp-armv8_vminnm_NNNole":
164; CHECK: vminnm.f64
165; CHECK: vminnm.f64
166  %cmp1 = fcmp fast ole double %a, 34.
167  %cond1 = select i1 %cmp1, double %a, double 34.
168  %cmp2 = fcmp fast ole double 56., %cond1
169  %cond2 = select i1 %cmp2, double 56., double %cond1
170  ret double %cond2
171}
172
173define float @fp-armv8_vminnm_NNNo_rev(float %a) {
174; CHECK-LABEL: "fp-armv8_vminnm_NNNo_rev":
175; CHECK: vminnm.f32
176; CHECK: vminnm.f32
177  %cmp1 = fcmp fast ogt float %a, 56.
178  %cond1 = select i1 %cmp1, float 56., float %a
179  %cmp2 = fcmp fast ogt float 78., %cond1
180  %cond2 = select i1 %cmp2, float %cond1, float 78.
181  ret float %cond2
182}
183
184define double @fp-armv8_vminnm_NNNoge_rev(double %a) {
185; CHECK-LABEL: "fp-armv8_vminnm_NNNoge_rev":
186; CHECK: vminnm.f64
187; CHECK: vminnm.f64
188  %cmp1 = fcmp fast oge double %a, 78.
189  %cond1 = select i1 %cmp1, double 78., double %a
190  %cmp2 = fcmp fast oge double 90., %cond1
191  %cond2 = select i1 %cmp2, double %cond1, double 90.
192  ret double %cond2
193}
194
195define float @fp-armv8_vminnm_NNNu(float %b) {
196; CHECK-LABEL: "fp-armv8_vminnm_NNNu":
197; CHECK: vminnm.f32
198; CHECK: vminnm.f32
199  %cmp1 = fcmp fast ult float 12., %b
200  %cond1 = select i1 %cmp1, float 12., float %b
201  %cmp2 = fcmp fast ult float %cond1, 34.
202  %cond2 = select i1 %cmp2, float %cond1, float 34.
203  ret float %cond2
204}
205
206define float @fp-armv8_vminnm_NNNule(float %b) {
207; CHECK-LABEL: "fp-armv8_vminnm_NNNule":
208; CHECK: vminnm.f32
209; CHECK: vminnm.f32
210  %cmp1 = fcmp fast ule float 34., %b
211  %cond1 = select i1 %cmp1, float 34., float %b
212  %cmp2 = fcmp fast ule float %cond1, 56.
213  %cond2 = select i1 %cmp2, float %cond1, float 56.
214  ret float %cond2
215}
216
217define float @fp-armv8_vminnm_NNNu_rev(float %b) {
218; CHECK-LABEL: "fp-armv8_vminnm_NNNu_rev":
219; CHECK: vminnm.f32
220; CHECK: vminnm.f32
221  %cmp1 = fcmp fast ugt float 56., %b
222  %cond1 = select i1 %cmp1, float %b, float 56.
223  %cmp2 = fcmp fast ugt float %cond1, 78.
224  %cond2 = select i1 %cmp2, float 78., float %cond1
225  ret float %cond2
226}
227
228define double @fp-armv8_vminnm_NNNuge_rev(double %b) {
229; CHECK-LABEL: "fp-armv8_vminnm_NNNuge_rev":
230; CHECK: vminnm.f64
231; CHECK: vminnm.f64
232  %cmp1 = fcmp fast uge double 78., %b
233  %cond1 = select i1 %cmp1, double %b, double 78.
234  %cmp2 = fcmp fast uge double %cond1, 90.
235  %cond2 = select i1 %cmp2, double 90., double %cond1
236  ret double %cond2
237}
238
239define float @fp-armv8_vmaxnm_NNNo(float %a) {
240; CHECK-LABEL: "fp-armv8_vmaxnm_NNNo":
241; CHECK: vmaxnm.f32
242; CHECK: vmaxnm.f32
243  %cmp1 = fcmp fast ogt float %a, 12.
244  %cond1 = select i1 %cmp1, float %a, float 12.
245  %cmp2 = fcmp fast ogt float 34., %cond1
246  %cond2 = select i1 %cmp2, float 34., float %cond1
247  ret float %cond2
248}
249
250define float @fp-armv8_vmaxnm_NNNoge(float %a) {
251; CHECK-LABEL: "fp-armv8_vmaxnm_NNNoge":
252; CHECK: vmaxnm.f32
253; CHECK: vmaxnm.f32
254  %cmp1 = fcmp fast oge float %a, 34.
255  %cond1 = select i1 %cmp1, float %a, float 34.
256  %cmp2 = fcmp fast oge float 56., %cond1
257  %cond2 = select i1 %cmp2, float 56., float %cond1
258  ret float %cond2
259}
260
261define float @fp-armv8_vmaxnm_NNNo_rev(float %a) {
262; CHECK-LABEL: "fp-armv8_vmaxnm_NNNo_rev":
263; CHECK: vmaxnm.f32
264; CHECK: vmaxnm.f32
265  %cmp1 = fcmp fast olt float %a, 56.
266  %cond1 = select i1 %cmp1, float 56., float %a
267  %cmp2 = fcmp fast olt float 78., %cond1
268  %cond2 = select i1 %cmp2, float %cond1, float 78.
269  ret float %cond2
270}
271
272define float @fp-armv8_vmaxnm_NNNole_rev(float %a) {
273; CHECK-LABEL: "fp-armv8_vmaxnm_NNNole_rev":
274; CHECK: vmaxnm.f32
275; CHECK: vmaxnm.f32
276  %cmp1 = fcmp fast ole float %a, 78.
277  %cond1 = select i1 %cmp1, float 78., float %a
278  %cmp2 = fcmp fast ole float 90., %cond1
279  %cond2 = select i1 %cmp2, float %cond1, float 90.
280  ret float %cond2
281}
282
283define float @fp-armv8_vmaxnm_NNNu(float %b) {
284; CHECK-LABEL: "fp-armv8_vmaxnm_NNNu":
285; CHECK: vmaxnm.f32
286; CHECK: vmaxnm.f32
287  %cmp1 = fcmp fast ugt float 12., %b
288  %cond1 = select i1 %cmp1, float 12., float %b
289  %cmp2 = fcmp fast ugt float %cond1, 34.
290  %cond2 = select i1 %cmp2, float %cond1, float 34.
291  ret float %cond2
292}
293
294define float @fp-armv8_vmaxnm_NNNuge(float %b) {
295; CHECK-LABEL: "fp-armv8_vmaxnm_NNNuge":
296; CHECK: vmaxnm.f32
297; CHECK: vmaxnm.f32
298  %cmp1 = fcmp fast uge float 34., %b
299  %cond1 = select i1 %cmp1, float 34., float %b
300  %cmp2 = fcmp fast uge float %cond1, 56.
301  %cond2 = select i1 %cmp2, float %cond1, float 56.
302  ret float %cond2
303}
304
305define float @fp-armv8_vmaxnm_NNNu_rev(float %b) {
306; CHECK-LABEL: "fp-armv8_vmaxnm_NNNu_rev":
307; CHECK: vmaxnm.f32
308; CHECK: vmaxnm.f32
309  %cmp1 = fcmp fast ult float 56., %b
310  %cond1 = select i1 %cmp1, float %b, float 56.
311  %cmp2 = fcmp fast ult float %cond1, 78.
312  %cond2 = select i1 %cmp2, float 78., float %cond1
313  ret float %cond2
314}
315
316define double @fp-armv8_vmaxnm_NNNule_rev( double %b) {
317; CHECK-LABEL: "fp-armv8_vmaxnm_NNNule_rev":
318; CHECK: vmaxnm.f64
319; CHECK: vmaxnm.f64
320  %cmp1 = fcmp fast ule double 78., %b
321  %cond1 = select i1 %cmp1, double %b, double 78.
322  %cmp2 = fcmp fast ule double %cond1, 90.
323  %cond2 = select i1 %cmp2, double 90., double %cond1
324  ret double %cond2
325}
326
327define float @fp-armv8_vminmaxnm_0(float %a) {
328; CHECK-LABEL: "fp-armv8_vminmaxnm_0":
329; CHECK-NOT: vcmp
330; CHECK: vminnm.f32
331; CHECK: vmaxnm.f32
332  %cmp1 = fcmp fast olt float %a, 0.
333  %cond1 = select i1 %cmp1, float %a, float 0.
334  %cmp2 = fcmp fast ogt float %cond1, 0.
335  %cond2 = select i1 %cmp2, float %cond1, float 0.
336  ret float %cond2
337}
338
339define float @fp-armv8_vminmaxnm_neg0(float %a) {
340; CHECK-LABEL: "fp-armv8_vminmaxnm_neg0":
341; CHECK-NOT: vcmp
342; CHECK: vminnm.f32
343; CHECK: vmaxnm.f32
344  %cmp1 = fcmp fast olt float %a, -0.
345  %cond1 = select i1 %cmp1, float %a, float -0.
346  %cmp2 = fcmp fast ugt float %cond1, -0.
347  %cond2 = select i1 %cmp2, float %cond1, float -0.
348  ret float %cond2
349}
350
351define float @fp-armv8_vminmaxnm_e_0(float %a) {
352; CHECK-LABEL: "fp-armv8_vminmaxnm_e_0":
353; CHECK-NOT: vcmp
354; CHECK: vminnm.f32
355; CHECK: vmaxnm.f32
356  %cmp1 = fcmp fast ule float 0., %a
357  %cond1 = select i1 %cmp1, float 0., float %a
358  %cmp2 = fcmp fast uge float 0., %cond1
359  %cond2 = select i1 %cmp2, float 0., float %cond1
360  ret float %cond2
361}
362
363define float @fp-armv8_vminmaxnm_e_neg0(float %a) {
364; CHECK-LABEL: "fp-armv8_vminmaxnm_e_neg0":
365; CHECK-NOT: vcmp
366; CHECK: vminnm.f32
367; CHECK: vmaxnm.f32
368  %cmp1 = fcmp fast ule float -0., %a
369  %cond1 = select i1 %cmp1, float -0., float %a
370  %cmp2 = fcmp fast oge float -0., %cond1
371  %cond2 = select i1 %cmp2, float -0., float %cond1
372  ret float %cond2
373}
374
375declare <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float>, <4 x float>) nounwind readnone
376declare <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float>, <2 x float>) nounwind readnone
377declare <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float>, <4 x float>) nounwind readnone
378declare <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float>, <2 x float>) nounwind readnone
379