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