Generate FMINNAN/FMINNUM/FMAXNAN/FMAXNUM from SDAGBuilder.
[oota-llvm.git] / test / CodeGen / ARM / vminmaxnm.ll
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
5 define 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
14 define 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
23 define 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
32 define 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
41 define 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
50 define 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
59 define 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
68 define 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
77 define 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
86 define 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
95 define 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
104 define 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
113 define 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
122 define 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
131 define 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
140 define 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
151 define 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
162 define 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
173 define 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
184 define 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
195 define 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
206 define 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
217 define 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
228 define 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
239 define 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
250 define 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
261 define 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
272 define 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
283 define 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
294 define 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
305 define 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
316 define 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
327 define 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
339 define 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
351 define 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
363 define 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
375 declare <4 x float> @llvm.arm.neon.vminnm.v4f32(<4 x float>, <4 x float>) nounwind readnone
376 declare <2 x float> @llvm.arm.neon.vminnm.v2f32(<2 x float>, <2 x float>) nounwind readnone
377 declare <4 x float> @llvm.arm.neon.vmaxnm.v4f32(<4 x float>, <4 x float>) nounwind readnone
378 declare <2 x float> @llvm.arm.neon.vmaxnm.v2f32(<2 x float>, <2 x float>) nounwind readnone