Synthesize x86 max/min instructions also for vectors (i.e. produce
[oota-llvm.git] / test / CodeGen / X86 / sse-minmax.ll
1 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -promote-elements | FileCheck %s
2 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-unsafe-fp-math -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=UNSAFE %s
3 ; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=FINITE %s
4
5 ; Some of these patterns can be matched as SSE min or max. Some of
6 ; then can be matched provided that the operands are swapped.
7 ; Some of them can't be matched at all and require a comparison
8 ; and a conditional branch.
9
10 ; The naming convention is {,x_,y_}{o,u}{gt,lt,ge,le}{,_inverse}
11 ; x_ : use 0.0 instead of %y
12 ; y_ : use -0.0 instead of %y
13 ; _inverse : swap the arms of the select.
14
15 ; Some of these tests depend on -join-physregs commuting instructions to
16 ; eliminate copies.
17
18 ; CHECK:      ogt:
19 ; CHECK-NEXT: maxsd %xmm1, %xmm0
20 ; CHECK-NEXT: ret
21 ; UNSAFE:      ogt:
22 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0
23 ; UNSAFE-NEXT: ret
24 ; FINITE:      ogt:
25 ; FINITE-NEXT: maxsd %xmm1, %xmm0
26 ; FINITE-NEXT: ret
27 define double @ogt(double %x, double %y) nounwind {
28   %c = fcmp ogt double %x, %y
29   %d = select i1 %c, double %x, double %y
30   ret double %d
31 }
32
33 ; CHECK:      olt:
34 ; CHECK-NEXT: minsd %xmm1, %xmm0
35 ; CHECK-NEXT: ret
36 ; UNSAFE:      olt:
37 ; UNSAFE-NEXT: minsd %xmm1, %xmm0
38 ; UNSAFE-NEXT: ret
39 ; FINITE:      olt:
40 ; FINITE-NEXT: minsd %xmm1, %xmm0
41 ; FINITE-NEXT: ret
42 define double @olt(double %x, double %y) nounwind {
43   %c = fcmp olt double %x, %y
44   %d = select i1 %c, double %x, double %y
45   ret double %d
46 }
47
48 ; CHECK:      ogt_inverse:
49 ; CHECK-NEXT: minsd  %xmm0, %xmm1
50 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
51 ; CHECK-NEXT: ret
52 ; UNSAFE:      ogt_inverse:
53 ; UNSAFE-NEXT: minsd  %xmm0, %xmm1
54 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
55 ; UNSAFE-NEXT: ret
56 ; FINITE:      ogt_inverse:
57 ; FINITE-NEXT: minsd  %xmm0, %xmm1
58 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
59 ; FINITE-NEXT: ret
60 define double @ogt_inverse(double %x, double %y) nounwind {
61   %c = fcmp ogt double %x, %y
62   %d = select i1 %c, double %y, double %x
63   ret double %d
64 }
65
66 ; CHECK:      olt_inverse:
67 ; CHECK-NEXT: maxsd  %xmm0, %xmm1
68 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
69 ; CHECK-NEXT: ret
70 ; UNSAFE:      olt_inverse:
71 ; UNSAFE-NEXT: maxsd  %xmm0, %xmm1
72 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
73 ; UNSAFE-NEXT: ret
74 ; FINITE:      olt_inverse:
75 ; FINITE-NEXT: maxsd  %xmm0, %xmm1
76 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
77 ; FINITE-NEXT: ret
78 define double @olt_inverse(double %x, double %y) nounwind {
79   %c = fcmp olt double %x, %y
80   %d = select i1 %c, double %y, double %x
81   ret double %d
82 }
83
84 ; CHECK:      oge:
85 ; CHECK-NEXT: ucomisd %xmm1, %xmm0
86 ; UNSAFE:      oge:
87 ; UNSAFE-NEXT: maxsd    %xmm1, %xmm0
88 ; UNSAFE-NEXT: ret
89 ; FINITE:      oge:
90 ; FINITE-NEXT: maxsd    %xmm1, %xmm0
91 ; FINITE-NEXT: ret
92 define double @oge(double %x, double %y) nounwind {
93   %c = fcmp oge double %x, %y
94   %d = select i1 %c, double %x, double %y
95   ret double %d
96 }
97
98 ; CHECK:      ole:
99 ; CHECK-NEXT: ucomisd %xmm0, %xmm1
100 ; UNSAFE:      ole:
101 ; UNSAFE-NEXT: minsd %xmm1, %xmm0
102 ; FINITE:      ole:
103 ; FINITE-NEXT: minsd %xmm1, %xmm0
104 define double @ole(double %x, double %y) nounwind {
105   %c = fcmp ole double %x, %y
106   %d = select i1 %c, double %x, double %y
107   ret double %d
108 }
109
110 ; CHECK:      oge_inverse:
111 ; CHECK-NEXT: ucomisd %xmm1, %xmm0
112 ; UNSAFE:      oge_inverse:
113 ; UNSAFE-NEXT: minsd %xmm0, %xmm1
114 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
115 ; UNSAFE-NEXT: ret
116 ; FINITE:      oge_inverse:
117 ; FINITE-NEXT: minsd %xmm0, %xmm1
118 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
119 ; FINITE-NEXT: ret
120 define double @oge_inverse(double %x, double %y) nounwind {
121   %c = fcmp oge double %x, %y
122   %d = select i1 %c, double %y, double %x
123   ret double %d
124 }
125
126 ; CHECK:      ole_inverse:
127 ; CHECK-NEXT: ucomisd %xmm0, %xmm1
128 ; UNSAFE:      ole_inverse:
129 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1
130 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
131 ; UNSAFE-NEXT: ret
132 ; FINITE:      ole_inverse:
133 ; FINITE-NEXT: maxsd %xmm0, %xmm1
134 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
135 ; FINITE-NEXT: ret
136 define double @ole_inverse(double %x, double %y) nounwind {
137   %c = fcmp ole double %x, %y
138   %d = select i1 %c, double %y, double %x
139   ret double %d
140 }
141
142 ; CHECK:      x_ogt:
143 ; CHECK-NEXT: pxor  %xmm1, %xmm1
144 ; CHECK-NEXT: maxsd %xmm1, %xmm0
145 ; CHECK-NEXT: ret
146 ; UNSAFE:      x_ogt:
147 ; UNSAFE-NEXT: pxor  %xmm1, %xmm1
148 ; UNSAFE-NEXT: maxsd %xmm1, %xmm0
149 ; UNSAFE-NEXT: ret
150 ; FINITE:      x_ogt:
151 ; FINITE-NEXT: pxor  %xmm1, %xmm1
152 ; FINITE-NEXT: maxsd %xmm1, %xmm0
153 ; FINITE-NEXT: ret
154 define double @x_ogt(double %x) nounwind {
155   %c = fcmp ogt double %x, 0.000000e+00
156   %d = select i1 %c, double %x, double 0.000000e+00
157   ret double %d
158 }
159
160 ; CHECK:      x_olt:
161 ; CHECK-NEXT: pxor  %xmm1, %xmm1
162 ; CHECK-NEXT: minsd %xmm1, %xmm0
163 ; CHECK-NEXT: ret
164 ; UNSAFE:      x_olt:
165 ; UNSAFE-NEXT: pxor  %xmm1, %xmm1
166 ; UNSAFE-NEXT: minsd %xmm1, %xmm0
167 ; UNSAFE-NEXT: ret
168 ; FINITE:      x_olt:
169 ; FINITE-NEXT: pxor  %xmm1, %xmm1
170 ; FINITE-NEXT: minsd %xmm1, %xmm0
171 ; FINITE-NEXT: ret
172 define double @x_olt(double %x) nounwind {
173   %c = fcmp olt double %x, 0.000000e+00
174   %d = select i1 %c, double %x, double 0.000000e+00
175   ret double %d
176 }
177
178 ; CHECK:      x_ogt_inverse:
179 ; CHECK-NEXT: pxor   %xmm1, %xmm1
180 ; CHECK-NEXT: minsd  %xmm0, %xmm1
181 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
182 ; CHECK-NEXT: ret
183 ; UNSAFE:      x_ogt_inverse:
184 ; UNSAFE-NEXT: pxor   %xmm1, %xmm1
185 ; UNSAFE-NEXT: minsd  %xmm0, %xmm1
186 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
187 ; UNSAFE-NEXT: ret
188 ; FINITE:      x_ogt_inverse:
189 ; FINITE-NEXT: pxor   %xmm1, %xmm1
190 ; FINITE-NEXT: minsd  %xmm0, %xmm1
191 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
192 ; FINITE-NEXT: ret
193 define double @x_ogt_inverse(double %x) nounwind {
194   %c = fcmp ogt double %x, 0.000000e+00
195   %d = select i1 %c, double 0.000000e+00, double %x
196   ret double %d
197 }
198
199 ; CHECK:      x_olt_inverse:
200 ; CHECK-NEXT: pxor   %xmm1, %xmm1
201 ; CHECK-NEXT: maxsd  %xmm0, %xmm1
202 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
203 ; CHECK-NEXT: ret
204 ; UNSAFE:      x_olt_inverse:
205 ; UNSAFE-NEXT: pxor   %xmm1, %xmm1
206 ; UNSAFE-NEXT: maxsd  %xmm0, %xmm1
207 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
208 ; UNSAFE-NEXT: ret
209 ; FINITE:      x_olt_inverse:
210 ; FINITE-NEXT: pxor   %xmm1, %xmm1
211 ; FINITE-NEXT: maxsd  %xmm0, %xmm1
212 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
213 ; FINITE-NEXT: ret
214 define double @x_olt_inverse(double %x) nounwind {
215   %c = fcmp olt double %x, 0.000000e+00
216   %d = select i1 %c, double 0.000000e+00, double %x
217   ret double %d
218 }
219
220 ; CHECK:      x_oge:
221 ; CHECK:      ucomisd %xmm1, %xmm0
222 ; UNSAFE:      x_oge:
223 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
224 ; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
225 ; UNSAFE-NEXT: ret
226 ; FINITE:      x_oge:
227 ; FINITE-NEXT: pxor    %xmm1, %xmm1
228 ; FINITE-NEXT: maxsd   %xmm1, %xmm0
229 ; FINITE-NEXT: ret
230 define double @x_oge(double %x) nounwind {
231   %c = fcmp oge double %x, 0.000000e+00
232   %d = select i1 %c, double %x, double 0.000000e+00
233   ret double %d
234 }
235
236 ; CHECK:      x_ole:
237 ; CHECK:      ucomisd %xmm0, %xmm1
238 ; UNSAFE:      x_ole:
239 ; UNSAFE-NEXT: pxor %xmm1, %xmm1
240 ; UNSAFE-NEXT: minsd %xmm1, %xmm0
241 ; UNSAFE-NEXT: ret
242 ; FINITE:      x_ole:
243 ; FINITE-NEXT: pxor %xmm1, %xmm1
244 ; FINITE-NEXT: minsd %xmm1, %xmm0
245 ; FINITE-NEXT: ret
246 define double @x_ole(double %x) nounwind {
247   %c = fcmp ole double %x, 0.000000e+00
248   %d = select i1 %c, double %x, double 0.000000e+00
249   ret double %d
250 }
251
252 ; CHECK:      x_oge_inverse:
253 ; CHECK:      ucomisd %xmm1, %xmm0
254 ; UNSAFE:      x_oge_inverse:
255 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
256 ; UNSAFE-NEXT: minsd   %xmm0, %xmm1
257 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
258 ; UNSAFE-NEXT: ret
259 ; FINITE:      x_oge_inverse:
260 ; FINITE-NEXT: pxor    %xmm1, %xmm1
261 ; FINITE-NEXT: minsd   %xmm0, %xmm1
262 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
263 ; FINITE-NEXT: ret
264 define double @x_oge_inverse(double %x) nounwind {
265   %c = fcmp oge double %x, 0.000000e+00
266   %d = select i1 %c, double 0.000000e+00, double %x
267   ret double %d
268 }
269
270 ; CHECK:      x_ole_inverse:
271 ; CHECK:      ucomisd %xmm0, %xmm1
272 ; UNSAFE:      x_ole_inverse:
273 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
274 ; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
275 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
276 ; UNSAFE-NEXT: ret
277 ; FINITE:      x_ole_inverse:
278 ; FINITE-NEXT: pxor    %xmm1, %xmm1
279 ; FINITE-NEXT: maxsd   %xmm0, %xmm1
280 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
281 ; FINITE-NEXT: ret
282 define double @x_ole_inverse(double %x) nounwind {
283   %c = fcmp ole double %x, 0.000000e+00
284   %d = select i1 %c, double 0.000000e+00, double %x
285   ret double %d
286 }
287
288 ; CHECK:      ugt:
289 ; CHECK:      ucomisd %xmm0, %xmm1
290 ; UNSAFE:      ugt:
291 ; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
292 ; UNSAFE-NEXT: ret
293 ; FINITE:      ugt:
294 ; FINITE-NEXT: maxsd   %xmm1, %xmm0
295 ; FINITE-NEXT: ret
296 define double @ugt(double %x, double %y) nounwind {
297   %c = fcmp ugt double %x, %y
298   %d = select i1 %c, double %x, double %y
299   ret double %d
300 }
301
302 ; CHECK:      ult:
303 ; CHECK:      ucomisd %xmm1, %xmm0
304 ; UNSAFE:      ult:
305 ; UNSAFE-NEXT: minsd   %xmm1, %xmm0
306 ; UNSAFE-NEXT: ret
307 ; FINITE:      ult:
308 ; FINITE-NEXT: minsd   %xmm1, %xmm0
309 ; FINITE-NEXT: ret
310 define double @ult(double %x, double %y) nounwind {
311   %c = fcmp ult double %x, %y
312   %d = select i1 %c, double %x, double %y
313   ret double %d
314 }
315
316 ; CHECK:      ugt_inverse:
317 ; CHECK:      ucomisd %xmm0, %xmm1
318 ; UNSAFE:      ugt_inverse:
319 ; UNSAFE-NEXT: minsd   %xmm0, %xmm1
320 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
321 ; UNSAFE-NEXT: ret
322 ; FINITE:      ugt_inverse:
323 ; FINITE-NEXT: minsd   %xmm0, %xmm1
324 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
325 ; FINITE-NEXT: ret
326 define double @ugt_inverse(double %x, double %y) nounwind {
327   %c = fcmp ugt double %x, %y
328   %d = select i1 %c, double %y, double %x
329   ret double %d
330 }
331
332 ; CHECK:      ult_inverse:
333 ; CHECK:      ucomisd %xmm1, %xmm0
334 ; UNSAFE:      ult_inverse:
335 ; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
336 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
337 ; UNSAFE-NEXT: ret
338 ; FINITE:      ult_inverse:
339 ; FINITE-NEXT: maxsd   %xmm0, %xmm1
340 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
341 ; FINITE-NEXT: ret
342 define double @ult_inverse(double %x, double %y) nounwind {
343   %c = fcmp ult double %x, %y
344   %d = select i1 %c, double %y, double %x
345   ret double %d
346 }
347
348 ; CHECK:      uge:
349 ; CHECK-NEXT: maxsd   %xmm0, %xmm1
350 ; CHECK-NEXT: movap{{[sd]}}  %xmm1, %xmm0
351 ; CHECK-NEXT: ret
352 ; UNSAFE:      uge:
353 ; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
354 ; UNSAFE-NEXT: ret
355 ; FINITE:      uge:
356 ; FINITE-NEXT: maxsd   %xmm1, %xmm0
357 ; FINITE-NEXT: ret
358 define double @uge(double %x, double %y) nounwind {
359   %c = fcmp uge double %x, %y
360   %d = select i1 %c, double %x, double %y
361   ret double %d
362 }
363
364 ; CHECK:      ule:
365 ; CHECK-NEXT: minsd  %xmm0, %xmm1
366 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
367 ; CHECK-NEXT: ret
368 ; UNSAFE:      ule:
369 ; UNSAFE-NEXT: minsd   %xmm1, %xmm0
370 ; UNSAFE-NEXT: ret
371 ; FINITE:      ule:
372 ; FINITE-NEXT: minsd   %xmm1, %xmm0
373 ; FINITE-NEXT: ret
374 define double @ule(double %x, double %y) nounwind {
375   %c = fcmp ule double %x, %y
376   %d = select i1 %c, double %x, double %y
377   ret double %d
378 }
379
380 ; CHECK:      uge_inverse:
381 ; CHECK-NEXT: minsd %xmm1, %xmm0
382 ; CHECK-NEXT: ret
383 ; UNSAFE:      uge_inverse:
384 ; UNSAFE-NEXT: minsd %xmm0, %xmm1
385 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
386 ; UNSAFE-NEXT: ret
387 ; FINITE:      uge_inverse:
388 ; FINITE-NEXT: minsd %xmm0, %xmm1
389 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
390 ; FINITE-NEXT: ret
391 define double @uge_inverse(double %x, double %y) nounwind {
392   %c = fcmp uge double %x, %y
393   %d = select i1 %c, double %y, double %x
394   ret double %d
395 }
396
397 ; CHECK:      ule_inverse:
398 ; CHECK-NEXT: maxsd %xmm1, %xmm0
399 ; CHECK-NEXT: ret
400 ; UNSAFE:      ule_inverse:
401 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1
402 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
403 ; UNSAFE-NEXT: ret
404 ; FINITE:      ule_inverse:
405 ; FINITE-NEXT: maxsd %xmm0, %xmm1
406 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
407 ; FINITE-NEXT: ret
408 define double @ule_inverse(double %x, double %y) nounwind {
409   %c = fcmp ule double %x, %y
410   %d = select i1 %c, double %y, double %x
411   ret double %d
412 }
413
414 ; CHECK:      x_ugt:
415 ; CHECK:      ucomisd %xmm0, %xmm1
416 ; UNSAFE:      x_ugt:
417 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
418 ; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
419 ; UNSAFE-NEXT: ret
420 ; FINITE:      x_ugt:
421 ; FINITE-NEXT: pxor    %xmm1, %xmm1
422 ; FINITE-NEXT: maxsd   %xmm1, %xmm0
423 ; FINITE-NEXT: ret
424 define double @x_ugt(double %x) nounwind {
425   %c = fcmp ugt double %x, 0.000000e+00
426   %d = select i1 %c, double %x, double 0.000000e+00
427   ret double %d
428 }
429
430 ; CHECK:      x_ult:
431 ; CHECK:      ucomisd %xmm1, %xmm0
432 ; UNSAFE:      x_ult:
433 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
434 ; UNSAFE-NEXT: minsd   %xmm1, %xmm0
435 ; UNSAFE-NEXT: ret
436 ; FINITE:      x_ult:
437 ; FINITE-NEXT: pxor    %xmm1, %xmm1
438 ; FINITE-NEXT: minsd   %xmm1, %xmm0
439 ; FINITE-NEXT: ret
440 define double @x_ult(double %x) nounwind {
441   %c = fcmp ult double %x, 0.000000e+00
442   %d = select i1 %c, double %x, double 0.000000e+00
443   ret double %d
444 }
445
446 ; CHECK:      x_ugt_inverse:
447 ; CHECK:      ucomisd %xmm0, %xmm1
448 ; UNSAFE:      x_ugt_inverse:
449 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
450 ; UNSAFE-NEXT: minsd   %xmm0, %xmm1
451 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
452 ; UNSAFE-NEXT: ret
453 ; FINITE:      x_ugt_inverse:
454 ; FINITE-NEXT: pxor    %xmm1, %xmm1
455 ; FINITE-NEXT: minsd   %xmm0, %xmm1
456 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
457 ; FINITE-NEXT: ret
458 define double @x_ugt_inverse(double %x) nounwind {
459   %c = fcmp ugt double %x, 0.000000e+00
460   %d = select i1 %c, double 0.000000e+00, double %x
461   ret double %d
462 }
463
464 ; CHECK:      x_ult_inverse:
465 ; CHECK:      ucomisd %xmm1, %xmm0
466 ; UNSAFE:      x_ult_inverse:
467 ; UNSAFE-NEXT: pxor    %xmm1, %xmm1
468 ; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
469 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
470 ; UNSAFE-NEXT: ret
471 ; FINITE:      x_ult_inverse:
472 ; FINITE-NEXT: pxor    %xmm1, %xmm1
473 ; FINITE-NEXT: maxsd   %xmm0, %xmm1
474 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
475 ; FINITE-NEXT: ret
476 define double @x_ult_inverse(double %x) nounwind {
477   %c = fcmp ult double %x, 0.000000e+00
478   %d = select i1 %c, double 0.000000e+00, double %x
479   ret double %d
480 }
481
482 ; CHECK:      x_uge:
483 ; CHECK-NEXT: pxor   %xmm1, %xmm1
484 ; CHECK-NEXT: maxsd  %xmm0, %xmm1
485 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
486 ; CHECK-NEXT: ret
487 ; UNSAFE:      x_uge:
488 ; UNSAFE-NEXT: pxor   %xmm1, %xmm1
489 ; UNSAFE-NEXT: maxsd  %xmm1, %xmm0
490 ; UNSAFE-NEXT: ret
491 ; FINITE:      x_uge:
492 ; FINITE-NEXT: pxor   %xmm1, %xmm1
493 ; FINITE-NEXT: maxsd  %xmm1, %xmm0
494 ; FINITE-NEXT: ret
495 define double @x_uge(double %x) nounwind {
496   %c = fcmp uge double %x, 0.000000e+00
497   %d = select i1 %c, double %x, double 0.000000e+00
498   ret double %d
499 }
500
501 ; CHECK:      x_ule:
502 ; CHECK-NEXT: pxor   %xmm1, %xmm1
503 ; CHECK-NEXT: minsd  %xmm0, %xmm1
504 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
505 ; CHECK-NEXT: ret
506 ; UNSAFE:      x_ule:
507 ; UNSAFE-NEXT: pxor   %xmm1, %xmm1
508 ; UNSAFE-NEXT: minsd  %xmm1, %xmm0
509 ; UNSAFE-NEXT: ret
510 ; FINITE:      x_ule:
511 ; FINITE-NEXT: pxor   %xmm1, %xmm1
512 ; FINITE-NEXT: minsd  %xmm1, %xmm0
513 ; FINITE-NEXT: ret
514 define double @x_ule(double %x) nounwind {
515   %c = fcmp ule double %x, 0.000000e+00
516   %d = select i1 %c, double %x, double 0.000000e+00
517   ret double %d
518 }
519
520 ; CHECK:      x_uge_inverse:
521 ; CHECK-NEXT: pxor  %xmm1, %xmm1
522 ; CHECK-NEXT: minsd %xmm1, %xmm0
523 ; CHECK-NEXT: ret
524 ; UNSAFE:      x_uge_inverse:
525 ; UNSAFE-NEXT: pxor  %xmm1, %xmm1
526 ; UNSAFE-NEXT: minsd %xmm0, %xmm1
527 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
528 ; UNSAFE-NEXT: ret
529 ; FINITE:      x_uge_inverse:
530 ; FINITE-NEXT: pxor  %xmm1, %xmm1
531 ; FINITE-NEXT: minsd %xmm0, %xmm1
532 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
533 ; FINITE-NEXT: ret
534 define double @x_uge_inverse(double %x) nounwind {
535   %c = fcmp uge double %x, 0.000000e+00
536   %d = select i1 %c, double 0.000000e+00, double %x
537   ret double %d
538 }
539
540 ; CHECK:      x_ule_inverse:
541 ; CHECK-NEXT: pxor  %xmm1, %xmm1
542 ; CHECK-NEXT: maxsd %xmm1, %xmm0
543 ; CHECK-NEXT: ret
544 ; UNSAFE:      x_ule_inverse:
545 ; UNSAFE-NEXT: pxor  %xmm1, %xmm1
546 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1
547 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
548 ; UNSAFE-NEXT: ret
549 ; FINITE:      x_ule_inverse:
550 ; FINITE-NEXT: pxor  %xmm1, %xmm1
551 ; FINITE-NEXT: maxsd %xmm0, %xmm1
552 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
553 ; FINITE-NEXT: ret
554 define double @x_ule_inverse(double %x) nounwind {
555   %c = fcmp ule double %x, 0.000000e+00
556   %d = select i1 %c, double 0.000000e+00, double %x
557   ret double %d
558 }
559
560 ; CHECK:      y_ogt:
561 ; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
562 ; CHECK-NEXT: ret
563 ; UNSAFE:      y_ogt:
564 ; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
565 ; UNSAFE-NEXT: ret
566 ; FINITE:      y_ogt:
567 ; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
568 ; FINITE-NEXT: ret
569 define double @y_ogt(double %x) nounwind {
570   %c = fcmp ogt double %x, -0.000000e+00
571   %d = select i1 %c, double %x, double -0.000000e+00
572   ret double %d
573 }
574
575 ; CHECK:      y_olt:
576 ; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
577 ; CHECK-NEXT: ret
578 ; UNSAFE:      y_olt:
579 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
580 ; UNSAFE-NEXT: ret
581 ; FINITE:      y_olt:
582 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
583 ; FINITE-NEXT: ret
584 define double @y_olt(double %x) nounwind {
585   %c = fcmp olt double %x, -0.000000e+00
586   %d = select i1 %c, double %x, double -0.000000e+00
587   ret double %d
588 }
589
590 ; CHECK:      y_ogt_inverse:
591 ; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
592 ; CHECK-NEXT: minsd  %xmm0, %xmm1
593 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
594 ; CHECK-NEXT: ret
595 ; UNSAFE:      y_ogt_inverse:
596 ; UNSAFE-NEXT: movsd  {{[^,]*}}, %xmm1
597 ; UNSAFE-NEXT: minsd  %xmm0, %xmm1
598 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
599 ; UNSAFE-NEXT: ret
600 ; FINITE:      y_ogt_inverse:
601 ; FINITE-NEXT: movsd  {{[^,]*}}, %xmm1
602 ; FINITE-NEXT: minsd  %xmm0, %xmm1
603 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
604 ; FINITE-NEXT: ret
605 define double @y_ogt_inverse(double %x) nounwind {
606   %c = fcmp ogt double %x, -0.000000e+00
607   %d = select i1 %c, double -0.000000e+00, double %x
608   ret double %d
609 }
610
611 ; CHECK:      y_olt_inverse:
612 ; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
613 ; CHECK-NEXT: maxsd  %xmm0, %xmm1
614 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
615 ; CHECK-NEXT: ret
616 ; UNSAFE:      y_olt_inverse:
617 ; UNSAFE-NEXT: movsd  {{[^,]*}}, %xmm1
618 ; UNSAFE-NEXT: maxsd  %xmm0, %xmm1
619 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
620 ; UNSAFE-NEXT: ret
621 ; FINITE:      y_olt_inverse:
622 ; FINITE-NEXT: movsd  {{[^,]*}}, %xmm1
623 ; FINITE-NEXT: maxsd  %xmm0, %xmm1
624 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
625 ; FINITE-NEXT: ret
626 define double @y_olt_inverse(double %x) nounwind {
627   %c = fcmp olt double %x, -0.000000e+00
628   %d = select i1 %c, double -0.000000e+00, double %x
629   ret double %d
630 }
631
632 ; CHECK:      y_oge:
633 ; CHECK:      ucomisd %xmm1, %xmm0
634 ; UNSAFE:      y_oge:
635 ; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
636 ; UNSAFE-NEXT: ret
637 ; FINITE:      y_oge:
638 ; FINITE-NEXT: maxsd   {{[^,]*}}, %xmm0
639 ; FINITE-NEXT: ret
640 define double @y_oge(double %x) nounwind {
641   %c = fcmp oge double %x, -0.000000e+00
642   %d = select i1 %c, double %x, double -0.000000e+00
643   ret double %d
644 }
645
646 ; CHECK:      y_ole:
647 ; CHECK:      ucomisd %xmm0, %xmm1
648 ; UNSAFE:      y_ole:
649 ; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
650 ; UNSAFE-NEXT: ret
651 ; FINITE:      y_ole:
652 ; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
653 ; FINITE-NEXT: ret
654 define double @y_ole(double %x) nounwind {
655   %c = fcmp ole double %x, -0.000000e+00
656   %d = select i1 %c, double %x, double -0.000000e+00
657   ret double %d
658 }
659
660 ; CHECK:      y_oge_inverse:
661 ; CHECK:      ucomisd %xmm1, %xmm0
662 ; UNSAFE:      y_oge_inverse:
663 ; UNSAFE-NEXT: movsd   {{[^,]*}}, %xmm1
664 ; UNSAFE-NEXT: minsd   %xmm0, %xmm1
665 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
666 ; UNSAFE-NEXT: ret
667 ; FINITE:      y_oge_inverse:
668 ; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
669 ; FINITE-NEXT: minsd   %xmm0, %xmm1
670 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
671 ; FINITE-NEXT: ret
672 define double @y_oge_inverse(double %x) nounwind {
673   %c = fcmp oge double %x, -0.000000e+00
674   %d = select i1 %c, double -0.000000e+00, double %x
675   ret double %d
676 }
677
678 ; CHECK:      y_ole_inverse:
679 ; CHECK:      ucomisd %xmm0, %xmm1
680 ; UNSAFE:      y_ole_inverse:
681 ; UNSAFE-NEXT: movsd   {{[^,]*}}, %xmm1
682 ; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
683 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
684 ; UNSAFE-NEXT: ret
685 ; FINITE:      y_ole_inverse:
686 ; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
687 ; FINITE-NEXT: maxsd   %xmm0, %xmm1
688 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
689 ; FINITE-NEXT: ret
690 define double @y_ole_inverse(double %x) nounwind {
691   %c = fcmp ole double %x, -0.000000e+00
692   %d = select i1 %c, double -0.000000e+00, double %x
693   ret double %d
694 }
695
696 ; CHECK:      y_ugt:
697 ; CHECK:      ucomisd %xmm0, %xmm1
698 ; UNSAFE:      y_ugt:
699 ; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
700 ; UNSAFE-NEXT: ret
701 ; FINITE:      y_ugt:
702 ; FINITE-NEXT: maxsd   {{[^,]*}}, %xmm0
703 ; FINITE-NEXT: ret
704 define double @y_ugt(double %x) nounwind {
705   %c = fcmp ugt double %x, -0.000000e+00
706   %d = select i1 %c, double %x, double -0.000000e+00
707   ret double %d
708 }
709
710 ; CHECK:      y_ult:
711 ; CHECK:      ucomisd %xmm1, %xmm0
712 ; UNSAFE:      y_ult:
713 ; UNSAFE-NEXT: minsd   {{[^,]*}}, %xmm0
714 ; UNSAFE-NEXT: ret
715 ; FINITE:      y_ult:
716 ; FINITE-NEXT: minsd   {{[^,]*}}, %xmm0
717 ; FINITE-NEXT: ret
718 define double @y_ult(double %x) nounwind {
719   %c = fcmp ult double %x, -0.000000e+00
720   %d = select i1 %c, double %x, double -0.000000e+00
721   ret double %d
722 }
723
724 ; CHECK:      y_ugt_inverse:
725 ; CHECK:      ucomisd %xmm0, %xmm1
726 ; UNSAFE:      y_ugt_inverse:
727 ; UNSAFE-NEXT: movsd   {{[^,]*}}, %xmm1
728 ; UNSAFE-NEXT: minsd   %xmm0, %xmm1
729 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
730 ; UNSAFE-NEXT: ret
731 ; FINITE:      y_ugt_inverse:
732 ; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
733 ; FINITE-NEXT: minsd   %xmm0, %xmm1
734 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
735 ; FINITE-NEXT: ret
736 define double @y_ugt_inverse(double %x) nounwind {
737   %c = fcmp ugt double %x, -0.000000e+00
738   %d = select i1 %c, double -0.000000e+00, double %x
739   ret double %d
740 }
741
742 ; CHECK:      y_ult_inverse:
743 ; CHECK:      ucomisd %xmm1, %xmm0
744 ; UNSAFE:      y_ult_inverse:
745 ; UNSAFE-NEXT: movsd   {{[^,]*}}, %xmm1
746 ; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
747 ; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
748 ; UNSAFE-NEXT: ret
749 ; FINITE:      y_ult_inverse:
750 ; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
751 ; FINITE-NEXT: maxsd   %xmm0, %xmm1
752 ; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
753 ; FINITE-NEXT: ret
754 define double @y_ult_inverse(double %x) nounwind {
755   %c = fcmp ult double %x, -0.000000e+00
756   %d = select i1 %c, double -0.000000e+00, double %x
757   ret double %d
758 }
759
760 ; CHECK:      y_uge:
761 ; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
762 ; CHECK-NEXT: maxsd  %xmm0, %xmm1
763 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
764 ; CHECK-NEXT: ret
765 ; UNSAFE:      y_uge:
766 ; UNSAFE-NEXT: maxsd  {{[^,]*}}, %xmm0
767 ; UNSAFE-NEXT: ret
768 ; FINITE:      y_uge:
769 ; FINITE-NEXT: maxsd  {{[^,]*}}, %xmm0
770 ; FINITE-NEXT: ret
771 define double @y_uge(double %x) nounwind {
772   %c = fcmp uge double %x, -0.000000e+00
773   %d = select i1 %c, double %x, double -0.000000e+00
774   ret double %d
775 }
776
777 ; CHECK:      y_ule:
778 ; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
779 ; CHECK-NEXT: minsd  %xmm0, %xmm1
780 ; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
781 ; CHECK-NEXT: ret
782 ; UNSAFE:      y_ule:
783 ; UNSAFE-NEXT: minsd  {{[^,]*}}, %xmm0
784 ; UNSAFE-NEXT: ret
785 ; FINITE:      y_ule:
786 ; FINITE-NEXT: minsd  {{[^,]*}}, %xmm0
787 ; FINITE-NEXT: ret
788 define double @y_ule(double %x) nounwind {
789   %c = fcmp ule double %x, -0.000000e+00
790   %d = select i1 %c, double %x, double -0.000000e+00
791   ret double %d
792 }
793
794 ; CHECK:      y_uge_inverse:
795 ; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
796 ; CHECK-NEXT: ret
797 ; UNSAFE:      y_uge_inverse:
798 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
799 ; UNSAFE-NEXT: minsd %xmm0, %xmm1
800 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
801 ; UNSAFE-NEXT: ret
802 ; FINITE:      y_uge_inverse:
803 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
804 ; FINITE-NEXT: minsd %xmm0, %xmm1
805 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
806 ; FINITE-NEXT: ret
807 define double @y_uge_inverse(double %x) nounwind {
808   %c = fcmp uge double %x, -0.000000e+00
809   %d = select i1 %c, double -0.000000e+00, double %x
810   ret double %d
811 }
812
813 ; CHECK:      y_ule_inverse:
814 ; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
815 ; CHECK-NEXT: ret
816 ; UNSAFE:      y_ule_inverse:
817 ; UNSAFE-NEXT: movsd {{[^,]*}}, %xmm1
818 ; UNSAFE-NEXT: maxsd %xmm0, %xmm1
819 ; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
820 ; UNSAFE-NEXT: ret
821 ; FINITE:      y_ule_inverse:
822 ; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
823 ; FINITE-NEXT: maxsd %xmm0, %xmm1
824 ; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
825 ; FINITE-NEXT: ret
826 define double @y_ule_inverse(double %x) nounwind {
827   %c = fcmp ule double %x, -0.000000e+00
828   %d = select i1 %c, double -0.000000e+00, double %x
829   ret double %d
830 }
831 ; Test a few more misc. cases.
832
833 ; CHECK: clampTo3k_a:
834 ; CHECK: minsd
835 ; UNSAFE: clampTo3k_a:
836 ; UNSAFE: minsd
837 ; FINITE: clampTo3k_a:
838 ; FINITE: minsd
839 define double @clampTo3k_a(double %x) nounwind readnone {
840 entry:
841   %0 = fcmp ogt double %x, 3.000000e+03           ; <i1> [#uses=1]
842   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
843   ret double %x_addr.0
844 }
845
846 ; CHECK: clampTo3k_b:
847 ; CHECK: minsd
848 ; UNSAFE: clampTo3k_b:
849 ; UNSAFE: minsd
850 ; FINITE: clampTo3k_b:
851 ; FINITE: minsd
852 define double @clampTo3k_b(double %x) nounwind readnone {
853 entry:
854   %0 = fcmp uge double %x, 3.000000e+03           ; <i1> [#uses=1]
855   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
856   ret double %x_addr.0
857 }
858
859 ; CHECK: clampTo3k_c:
860 ; CHECK: maxsd
861 ; UNSAFE: clampTo3k_c:
862 ; UNSAFE: maxsd
863 ; FINITE: clampTo3k_c:
864 ; FINITE: maxsd
865 define double @clampTo3k_c(double %x) nounwind readnone {
866 entry:
867   %0 = fcmp olt double %x, 3.000000e+03           ; <i1> [#uses=1]
868   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
869   ret double %x_addr.0
870 }
871
872 ; CHECK: clampTo3k_d:
873 ; CHECK: maxsd
874 ; UNSAFE: clampTo3k_d:
875 ; UNSAFE: maxsd
876 ; FINITE: clampTo3k_d:
877 ; FINITE: maxsd
878 define double @clampTo3k_d(double %x) nounwind readnone {
879 entry:
880   %0 = fcmp ule double %x, 3.000000e+03           ; <i1> [#uses=1]
881   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
882   ret double %x_addr.0
883 }
884
885 ; CHECK: clampTo3k_e:
886 ; CHECK: maxsd
887 ; UNSAFE: clampTo3k_e:
888 ; UNSAFE: maxsd
889 ; FINITE: clampTo3k_e:
890 ; FINITE: maxsd
891 define double @clampTo3k_e(double %x) nounwind readnone {
892 entry:
893   %0 = fcmp olt double %x, 3.000000e+03           ; <i1> [#uses=1]
894   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
895   ret double %x_addr.0
896 }
897
898 ; CHECK: clampTo3k_f:
899 ; CHECK: maxsd
900 ; UNSAFE: clampTo3k_f:
901 ; UNSAFE: maxsd
902 ; FINITE: clampTo3k_f:
903 ; FINITE: maxsd
904 define double @clampTo3k_f(double %x) nounwind readnone {
905 entry:
906   %0 = fcmp ule double %x, 3.000000e+03           ; <i1> [#uses=1]
907   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
908   ret double %x_addr.0
909 }
910
911 ; CHECK: clampTo3k_g:
912 ; CHECK: minsd
913 ; UNSAFE: clampTo3k_g:
914 ; UNSAFE: minsd
915 ; FINITE: clampTo3k_g:
916 ; FINITE: minsd
917 define double @clampTo3k_g(double %x) nounwind readnone {
918 entry:
919   %0 = fcmp ogt double %x, 3.000000e+03           ; <i1> [#uses=1]
920   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
921   ret double %x_addr.0
922 }
923
924 ; CHECK: clampTo3k_h:
925 ; CHECK: minsd
926 ; UNSAFE: clampTo3k_h:
927 ; UNSAFE: minsd
928 ; FINITE: clampTo3k_h:
929 ; FINITE: minsd
930 define double @clampTo3k_h(double %x) nounwind readnone {
931 entry:
932   %0 = fcmp uge double %x, 3.000000e+03           ; <i1> [#uses=1]
933   %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
934   ret double %x_addr.0
935 }
936
937 ; UNSAFE: maxpd:
938 ; UNSAFE: maxpd
939 define <2 x double> @maxpd(<2 x double> %x, <2 x double> %y) {
940   %max_is_x = fcmp oge <2 x double> %x, %y
941   %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
942   ret <2 x double> %max
943 }
944
945 ; UNSAFE: minpd:
946 ; UNSAFE: minpd
947 define <2 x double> @minpd(<2 x double> %x, <2 x double> %y) {
948   %min_is_x = fcmp ole <2 x double> %x, %y
949   %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
950   ret <2 x double> %min
951 }
952
953 ; UNSAFE: maxps:
954 ; UNSAFE: maxps
955 define <4 x float> @maxps(<4 x float> %x, <4 x float> %y) {
956   %max_is_x = fcmp oge <4 x float> %x, %y
957   %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y
958   ret <4 x float> %max
959 }
960
961 ; UNSAFE: minps:
962 ; UNSAFE: minps
963 define <4 x float> @minps(<4 x float> %x, <4 x float> %y) {
964   %min_is_x = fcmp ole <4 x float> %x, %y
965   %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y
966   ret <4 x float> %min
967 }