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