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