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-LABEL:      ogt:
16; CHECK-NEXT: maxsd %xmm1, %xmm0
17; CHECK-NEXT: ret
18; UNSAFE-LABEL:      ogt:
19; UNSAFE-NEXT: maxsd %xmm1, %xmm0
20; UNSAFE-NEXT: ret
21; FINITE-LABEL:      ogt:
22; FINITE-NEXT: maxsd %xmm1, %xmm0
23; FINITE-NEXT: ret
24define 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-LABEL:      olt:
31; CHECK-NEXT: minsd %xmm1, %xmm0
32; CHECK-NEXT: ret
33; UNSAFE-LABEL:      olt:
34; UNSAFE-NEXT: minsd %xmm1, %xmm0
35; UNSAFE-NEXT: ret
36; FINITE-LABEL:      olt:
37; FINITE-NEXT: minsd %xmm1, %xmm0
38; FINITE-NEXT: ret
39define 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-LABEL:      ogt_inverse:
46; CHECK-NEXT: minsd  %xmm0, %xmm1
47; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
48; CHECK-NEXT: ret
49; UNSAFE-LABEL:      ogt_inverse:
50; UNSAFE-NEXT: minsd  %xmm1, %xmm0
51; UNSAFE-NEXT: ret
52; FINITE-LABEL:      ogt_inverse:
53; FINITE-NEXT: minsd  %xmm0, %xmm1
54; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
55; FINITE-NEXT: ret
56define 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-LABEL:      olt_inverse:
63; CHECK-NEXT: maxsd  %xmm0, %xmm1
64; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
65; CHECK-NEXT: ret
66; UNSAFE-LABEL:      olt_inverse:
67; UNSAFE-NEXT: maxsd  %xmm1, %xmm0
68; UNSAFE-NEXT: ret
69; FINITE-LABEL:      olt_inverse:
70; FINITE-NEXT: maxsd  %xmm0, %xmm1
71; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
72; FINITE-NEXT: ret
73define 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-LABEL:      oge:
80; CHECK: cmplesd %xmm0
81; UNSAFE-LABEL:      oge:
82; UNSAFE-NEXT: maxsd	%xmm1, %xmm0
83; UNSAFE-NEXT: ret
84; FINITE-LABEL:      oge:
85; FINITE-NEXT: maxsd	%xmm1, %xmm0
86; FINITE-NEXT: ret
87define 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-LABEL:      ole:
94; CHECK: cmplesd %xmm1
95; UNSAFE-LABEL:      ole:
96; UNSAFE-NEXT: minsd %xmm1, %xmm0
97; FINITE-LABEL:      ole:
98; FINITE-NEXT: minsd %xmm1, %xmm0
99define 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-LABEL:      oge_inverse:
106; CHECK: cmplesd %xmm0
107; UNSAFE-LABEL:      oge_inverse:
108; UNSAFE-NEXT: minsd %xmm1, %xmm0
109; UNSAFE-NEXT: ret
110; FINITE-LABEL:      oge_inverse:
111; FINITE-NEXT: minsd %xmm0, %xmm1
112; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
113; FINITE-NEXT: ret
114define 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-LABEL:      ole_inverse:
121; CHECK: cmplesd %xmm1
122; UNSAFE-LABEL:      ole_inverse:
123; UNSAFE-NEXT: maxsd %xmm1, %xmm0
124; UNSAFE-NEXT: ret
125; FINITE-LABEL:      ole_inverse:
126; FINITE-NEXT: maxsd %xmm0, %xmm1
127; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
128; FINITE-NEXT: ret
129define 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-LABEL:      ogt_x:
136; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1
137; CHECK-NEXT: maxsd %xmm1, %xmm0
138; CHECK-NEXT: ret
139; UNSAFE-LABEL:      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-LABEL:      ogt_x:
145; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
146; FINITE-NEXT: maxsd %xmm1, %xmm0
147; FINITE-NEXT: ret
148define 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-LABEL:      olt_x:
155; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1
156; CHECK-NEXT: minsd %xmm1, %xmm0
157; CHECK-NEXT: ret
158; UNSAFE-LABEL:      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-LABEL:      olt_x:
164; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
165; FINITE-NEXT: minsd %xmm1, %xmm0
166; FINITE-NEXT: ret
167define 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-LABEL:      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-LABEL:      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-LABEL:      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
188define 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-LABEL:      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-LABEL:      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-LABEL:      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
209define 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-LABEL:      oge_x:
216; CHECK:      cmplesd %xmm
217; CHECK-NEXT: andpd
218; UNSAFE-LABEL:      oge_x:
219; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
220; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
221; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
222; UNSAFE-NEXT: ret
223; FINITE-LABEL:      oge_x:
224; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
225; FINITE-NEXT: maxsd   %xmm1, %xmm0
226; FINITE-NEXT: ret
227define double @oge_x(double %x) nounwind {
228  %c = fcmp oge double %x, 0.000000e+00
229  %d = select i1 %c, double %x, double 0.000000e+00
230  ret double %d
231}
232
233; CHECK-LABEL:      ole_x:
234; CHECK:      cmplesd %xmm
235; CHECK-NEXT: andpd
236; UNSAFE-LABEL:      ole_x:
237; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
238; UNSAFE-NEXT: minsd %xmm0, %xmm1
239; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
240; UNSAFE-NEXT: ret
241; FINITE-LABEL:      ole_x:
242; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
243; FINITE-NEXT: minsd %xmm1, %xmm0
244; FINITE-NEXT: ret
245define double @ole_x(double %x) nounwind {
246  %c = fcmp ole double %x, 0.000000e+00
247  %d = select i1 %c, double %x, double 0.000000e+00
248  ret double %d
249}
250
251; CHECK-LABEL:      oge_inverse_x:
252; CHECK:      cmplesd %xmm
253; CHECK-NEXT: andnpd
254; UNSAFE-LABEL:      oge_inverse_x:
255; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
256; UNSAFE-NEXT: minsd   %xmm0, %xmm1
257; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
258; UNSAFE-NEXT: ret
259; FINITE-LABEL:      oge_inverse_x:
260; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
261; FINITE-NEXT: minsd   %xmm0, %xmm1
262; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
263; FINITE-NEXT: ret
264define double @oge_inverse_x(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-LABEL:      ole_inverse_x:
271; CHECK:      cmplesd %xmm
272; UNSAFE-LABEL:      ole_inverse_x:
273; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
274; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
275; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
276; UNSAFE-NEXT: ret
277; FINITE-LABEL:      ole_inverse_x:
278; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
279; FINITE-NEXT: maxsd   %xmm0, %xmm1
280; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
281; FINITE-NEXT: ret
282define double @ole_inverse_x(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-LABEL:      ugt:
289; CHECK:      cmpnlesd %xmm1
290; UNSAFE-LABEL:      ugt:
291; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
292; UNSAFE-NEXT: ret
293; FINITE-LABEL:      ugt:
294; FINITE-NEXT: maxsd   %xmm1, %xmm0
295; FINITE-NEXT: ret
296define 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-LABEL:      ult:
303; CHECK:      cmpnlesd %xmm0
304; UNSAFE-LABEL:      ult:
305; UNSAFE-NEXT: minsd   %xmm1, %xmm0
306; UNSAFE-NEXT: ret
307; FINITE-LABEL:      ult:
308; FINITE-NEXT: minsd   %xmm1, %xmm0
309; FINITE-NEXT: ret
310define 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-LABEL:      ugt_inverse:
317; CHECK:      cmpnlesd %xmm1
318; UNSAFE-LABEL:      ugt_inverse:
319; UNSAFE-NEXT: minsd   %xmm1, %xmm0
320; UNSAFE-NEXT: ret
321; FINITE-LABEL:      ugt_inverse:
322; FINITE-NEXT: minsd   %xmm0, %xmm1
323; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
324; FINITE-NEXT: ret
325define double @ugt_inverse(double %x, double %y) nounwind {
326  %c = fcmp ugt double %x, %y
327  %d = select i1 %c, double %y, double %x
328  ret double %d
329}
330
331; CHECK-LABEL:      ult_inverse:
332; CHECK:      cmpnlesd %xmm0
333; UNSAFE-LABEL:      ult_inverse:
334; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
335; UNSAFE-NEXT: ret
336; FINITE-LABEL:      ult_inverse:
337; FINITE-NEXT: maxsd   %xmm0, %xmm1
338; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
339; FINITE-NEXT: ret
340define double @ult_inverse(double %x, double %y) nounwind {
341  %c = fcmp ult double %x, %y
342  %d = select i1 %c, double %y, double %x
343  ret double %d
344}
345
346; CHECK-LABEL:      uge:
347; CHECK-NEXT: maxsd   %xmm0, %xmm1
348; CHECK-NEXT: movap{{[sd]}}  %xmm1, %xmm0
349; CHECK-NEXT: ret
350; UNSAFE-LABEL:      uge:
351; UNSAFE-NEXT: maxsd   %xmm1, %xmm0
352; UNSAFE-NEXT: ret
353; FINITE-LABEL:      uge:
354; FINITE-NEXT: maxsd   %xmm1, %xmm0
355; FINITE-NEXT: ret
356define double @uge(double %x, double %y) nounwind {
357  %c = fcmp uge double %x, %y
358  %d = select i1 %c, double %x, double %y
359  ret double %d
360}
361
362; CHECK-LABEL:      ule:
363; CHECK-NEXT: minsd  %xmm0, %xmm1
364; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
365; CHECK-NEXT: ret
366; UNSAFE-LABEL:      ule:
367; UNSAFE-NEXT: minsd   %xmm1, %xmm0
368; UNSAFE-NEXT: ret
369; FINITE-LABEL:      ule:
370; FINITE-NEXT: minsd   %xmm1, %xmm0
371; FINITE-NEXT: ret
372define double @ule(double %x, double %y) nounwind {
373  %c = fcmp ule double %x, %y
374  %d = select i1 %c, double %x, double %y
375  ret double %d
376}
377
378; CHECK-LABEL:      uge_inverse:
379; CHECK-NEXT: minsd %xmm1, %xmm0
380; CHECK-NEXT: ret
381; UNSAFE-LABEL:      uge_inverse:
382; UNSAFE-NEXT: minsd %xmm1, %xmm0
383; UNSAFE-NEXT: ret
384; FINITE-LABEL:      uge_inverse:
385; FINITE-NEXT: minsd %xmm0, %xmm1
386; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
387; FINITE-NEXT: ret
388define double @uge_inverse(double %x, double %y) nounwind {
389  %c = fcmp uge double %x, %y
390  %d = select i1 %c, double %y, double %x
391  ret double %d
392}
393
394; CHECK-LABEL:      ule_inverse:
395; CHECK-NEXT: maxsd %xmm1, %xmm0
396; CHECK-NEXT: ret
397; UNSAFE-LABEL:      ule_inverse:
398; UNSAFE-NEXT: maxsd %xmm1, %xmm0
399; UNSAFE-NEXT: ret
400; FINITE-LABEL:      ule_inverse:
401; FINITE-NEXT: maxsd %xmm0, %xmm1
402; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
403; FINITE-NEXT: ret
404define double @ule_inverse(double %x, double %y) nounwind {
405  %c = fcmp ule double %x, %y
406  %d = select i1 %c, double %y, double %x
407  ret double %d
408}
409
410; CHECK-LABEL:      ugt_x:
411; CHECK:      cmpnlesd %xmm
412; CHECK-NEXT: andpd
413; UNSAFE-LABEL:      ugt_x:
414; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
415; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
416; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
417; UNSAFE-NEXT: ret
418; FINITE-LABEL:      ugt_x:
419; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
420; FINITE-NEXT: maxsd   %xmm1, %xmm0
421; FINITE-NEXT: ret
422define double @ugt_x(double %x) nounwind {
423  %c = fcmp ugt double %x, 0.000000e+00
424  %d = select i1 %c, double %x, double 0.000000e+00
425  ret double %d
426}
427
428; CHECK-LABEL:      ult_x:
429; CHECK:      cmpnlesd %xmm
430; CHECK-NEXT: andpd
431; UNSAFE-LABEL:      ult_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-LABEL:      ult_x:
437; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
438; FINITE-NEXT: minsd   %xmm1, %xmm0
439; FINITE-NEXT: ret
440define double @ult_x(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-LABEL:      ugt_inverse_x:
447; CHECK:      cmpnlesd %xmm
448; CHECK-NEXT: andnpd
449; UNSAFE-LABEL:      ugt_inverse_x:
450; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
451; UNSAFE-NEXT: minsd   %xmm0, %xmm1
452; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
453; UNSAFE-NEXT: ret
454; FINITE-LABEL:      ugt_inverse_x:
455; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
456; FINITE-NEXT: minsd   %xmm0, %xmm1
457; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
458; FINITE-NEXT: ret
459define double @ugt_inverse_x(double %x) nounwind {
460  %c = fcmp ugt double %x, 0.000000e+00
461  %d = select i1 %c, double 0.000000e+00, double %x
462  ret double %d
463}
464
465; CHECK-LABEL:      ult_inverse_x:
466; CHECK:      cmpnlesd %xmm
467; CHECK-NEXT: andnpd
468; UNSAFE-LABEL:      ult_inverse_x:
469; UNSAFE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
470; UNSAFE-NEXT: maxsd   %xmm0, %xmm1
471; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
472; UNSAFE-NEXT: ret
473; FINITE-LABEL:      ult_inverse_x:
474; FINITE-NEXT: xorp{{[sd]}}   %xmm1, %xmm1
475; FINITE-NEXT: maxsd   %xmm0, %xmm1
476; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
477; FINITE-NEXT: ret
478define double @ult_inverse_x(double %x) nounwind {
479  %c = fcmp ult double %x, 0.000000e+00
480  %d = select i1 %c, double 0.000000e+00, double %x
481  ret double %d
482}
483
484; CHECK-LABEL:      uge_x:
485; CHECK-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
486; CHECK-NEXT: maxsd  %xmm0, %xmm1
487; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
488; CHECK-NEXT: ret
489; UNSAFE-LABEL:      uge_x:
490; UNSAFE-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
491; UNSAFE-NEXT: maxsd  %xmm0, %xmm1
492; UNSAFE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
493; UNSAFE-NEXT: ret
494; FINITE-LABEL:      uge_x:
495; FINITE-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
496; FINITE-NEXT: maxsd  %xmm1, %xmm0
497; FINITE-NEXT: ret
498define double @uge_x(double %x) nounwind {
499  %c = fcmp uge double %x, 0.000000e+00
500  %d = select i1 %c, double %x, double 0.000000e+00
501  ret double %d
502}
503
504; CHECK-LABEL:      ule_x:
505; CHECK-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
506; CHECK-NEXT: minsd  %xmm0, %xmm1
507; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
508; CHECK-NEXT: ret
509; UNSAFE-LABEL:      ule_x:
510; UNSAFE-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
511; UNSAFE-NEXT: minsd  %xmm0, %xmm1
512; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
513; UNSAFE-NEXT: ret
514; FINITE-LABEL:      ule_x:
515; FINITE-NEXT: xorp{{[sd]}}  %xmm1, %xmm1
516; FINITE-NEXT: minsd  %xmm1, %xmm0
517; FINITE-NEXT: ret
518define double @ule_x(double %x) nounwind {
519  %c = fcmp ule double %x, 0.000000e+00
520  %d = select i1 %c, double %x, double 0.000000e+00
521  ret double %d
522}
523
524; CHECK-LABEL:      uge_inverse_x:
525; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1
526; CHECK-NEXT: minsd %xmm1, %xmm0
527; CHECK-NEXT: ret
528; UNSAFE-LABEL:      uge_inverse_x:
529; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
530; UNSAFE-NEXT: minsd %xmm0, %xmm1
531; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
532; UNSAFE-NEXT: ret
533; FINITE-LABEL:      uge_inverse_x:
534; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
535; FINITE-NEXT: minsd %xmm0, %xmm1
536; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
537; FINITE-NEXT: ret
538define double @uge_inverse_x(double %x) nounwind {
539  %c = fcmp uge double %x, 0.000000e+00
540  %d = select i1 %c, double 0.000000e+00, double %x
541  ret double %d
542}
543
544; CHECK-LABEL:      ule_inverse_x:
545; CHECK-NEXT: xorp{{[sd]}} %xmm1, %xmm1
546; CHECK-NEXT: maxsd %xmm1, %xmm0
547; CHECK-NEXT: ret
548; UNSAFE-LABEL:      ule_inverse_x:
549; UNSAFE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
550; UNSAFE-NEXT: maxsd %xmm0, %xmm1
551; UNSAFE-NEXT: movap{{[sd]}} %xmm1, %xmm0
552; UNSAFE-NEXT: ret
553; FINITE-LABEL:      ule_inverse_x:
554; FINITE-NEXT: xorp{{[sd]}} %xmm1, %xmm1
555; FINITE-NEXT: maxsd %xmm0, %xmm1
556; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
557; FINITE-NEXT: ret
558define double @ule_inverse_x(double %x) nounwind {
559  %c = fcmp ule double %x, 0.000000e+00
560  %d = select i1 %c, double 0.000000e+00, double %x
561  ret double %d
562}
563
564; CHECK-LABEL:      ogt_y:
565; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
566; CHECK-NEXT: ret
567; UNSAFE-LABEL:      ogt_y:
568; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
569; UNSAFE-NEXT: ret
570; FINITE-LABEL:      ogt_y:
571; FINITE-NEXT: maxsd {{[^,]*}}, %xmm0
572; FINITE-NEXT: ret
573define double @ogt_y(double %x) nounwind {
574  %c = fcmp ogt double %x, -0.000000e+00
575  %d = select i1 %c, double %x, double -0.000000e+00
576  ret double %d
577}
578
579; CHECK-LABEL:      olt_y:
580; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
581; CHECK-NEXT: ret
582; UNSAFE-LABEL:      olt_y:
583; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
584; UNSAFE-NEXT: ret
585; FINITE-LABEL:      olt_y:
586; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
587; FINITE-NEXT: ret
588define double @olt_y(double %x) nounwind {
589  %c = fcmp olt double %x, -0.000000e+00
590  %d = select i1 %c, double %x, double -0.000000e+00
591  ret double %d
592}
593
594; CHECK-LABEL:      ogt_inverse_y:
595; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
596; CHECK-NEXT: minsd  %xmm0, %xmm1
597; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
598; CHECK-NEXT: ret
599; UNSAFE-LABEL:      ogt_inverse_y:
600; UNSAFE-NEXT: minsd  {{[^,]*}}, %xmm0
601; UNSAFE-NEXT: ret
602; FINITE-LABEL:      ogt_inverse_y:
603; FINITE-NEXT: movsd  {{[^,]*}}, %xmm1
604; FINITE-NEXT: minsd  %xmm0, %xmm1
605; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
606; FINITE-NEXT: ret
607define double @ogt_inverse_y(double %x) nounwind {
608  %c = fcmp ogt double %x, -0.000000e+00
609  %d = select i1 %c, double -0.000000e+00, double %x
610  ret double %d
611}
612
613; CHECK-LABEL:      olt_inverse_y:
614; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
615; CHECK-NEXT: maxsd  %xmm0, %xmm1
616; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
617; CHECK-NEXT: ret
618; UNSAFE-LABEL:      olt_inverse_y:
619; UNSAFE-NEXT: maxsd  {{[^,]*}}, %xmm0
620; UNSAFE-NEXT: ret
621; FINITE-LABEL:      olt_inverse_y:
622; FINITE-NEXT: movsd  {{[^,]*}}, %xmm1
623; FINITE-NEXT: maxsd  %xmm0, %xmm1
624; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
625; FINITE-NEXT: ret
626define double @olt_inverse_y(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-LABEL:      oge_y:
633; CHECK:      cmplesd %xmm0
634; UNSAFE-LABEL:      oge_y:
635; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
636; UNSAFE-NEXT: ret
637; FINITE-LABEL:      oge_y:
638; FINITE-NEXT: maxsd   {{[^,]*}}, %xmm0
639; FINITE-NEXT: ret
640define double @oge_y(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-LABEL:      ole_y:
647; CHECK:      cmplesd %xmm
648; UNSAFE-LABEL:      ole_y:
649; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
650; UNSAFE-NEXT: ret
651; FINITE-LABEL:      ole_y:
652; FINITE-NEXT: minsd {{[^,]*}}, %xmm0
653; FINITE-NEXT: ret
654define double @ole_y(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-LABEL:      oge_inverse_y:
661; CHECK:      cmplesd %xmm0
662; UNSAFE-LABEL:      oge_inverse_y:
663; UNSAFE-NEXT: minsd   {{[^,]*}}, %xmm0
664; UNSAFE-NEXT: ret
665; FINITE-LABEL:      oge_inverse_y:
666; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
667; FINITE-NEXT: minsd   %xmm0, %xmm1
668; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
669; FINITE-NEXT: ret
670define double @oge_inverse_y(double %x) nounwind {
671  %c = fcmp oge double %x, -0.000000e+00
672  %d = select i1 %c, double -0.000000e+00, double %x
673  ret double %d
674}
675
676; CHECK-LABEL:      ole_inverse_y:
677; CHECK:      cmplesd %xmm
678; UNSAFE-LABEL:      ole_inverse_y:
679; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
680; UNSAFE-NEXT: ret
681; FINITE-LABEL:      ole_inverse_y:
682; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
683; FINITE-NEXT: maxsd   %xmm0, %xmm1
684; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
685; FINITE-NEXT: ret
686define double @ole_inverse_y(double %x) nounwind {
687  %c = fcmp ole double %x, -0.000000e+00
688  %d = select i1 %c, double -0.000000e+00, double %x
689  ret double %d
690}
691
692; CHECK-LABEL:      ugt_y:
693; CHECK:      cmpnlesd %xmm
694; UNSAFE-LABEL:      ugt_y:
695; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
696; UNSAFE-NEXT: ret
697; FINITE-LABEL:      ugt_y:
698; FINITE-NEXT: maxsd   {{[^,]*}}, %xmm0
699; FINITE-NEXT: ret
700define double @ugt_y(double %x) nounwind {
701  %c = fcmp ugt double %x, -0.000000e+00
702  %d = select i1 %c, double %x, double -0.000000e+00
703  ret double %d
704}
705
706; CHECK-LABEL:      ult_y:
707; CHECK:      cmpnlesd %xmm0
708; UNSAFE-LABEL:      ult_y:
709; UNSAFE-NEXT: minsd   {{[^,]*}}, %xmm0
710; UNSAFE-NEXT: ret
711; FINITE-LABEL:      ult_y:
712; FINITE-NEXT: minsd   {{[^,]*}}, %xmm0
713; FINITE-NEXT: ret
714define double @ult_y(double %x) nounwind {
715  %c = fcmp ult double %x, -0.000000e+00
716  %d = select i1 %c, double %x, double -0.000000e+00
717  ret double %d
718}
719
720; CHECK-LABEL:      ugt_inverse_y:
721; CHECK:      cmpnlesd %xmm
722; UNSAFE-LABEL:      ugt_inverse_y:
723; UNSAFE-NEXT: minsd   {{[^,]*}}, %xmm0
724; UNSAFE-NEXT: ret
725; FINITE-LABEL:      ugt_inverse_y:
726; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
727; FINITE-NEXT: minsd   %xmm0, %xmm1
728; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
729; FINITE-NEXT: ret
730define double @ugt_inverse_y(double %x) nounwind {
731  %c = fcmp ugt double %x, -0.000000e+00
732  %d = select i1 %c, double -0.000000e+00, double %x
733  ret double %d
734}
735
736; CHECK-LABEL:      ult_inverse_y:
737; CHECK:      cmpnlesd %xmm
738; UNSAFE-LABEL:      ult_inverse_y:
739; UNSAFE-NEXT: maxsd   {{[^,]*}}, %xmm0
740; UNSAFE-NEXT: ret
741; FINITE-LABEL:      ult_inverse_y:
742; FINITE-NEXT: movsd   {{[^,]*}}, %xmm1
743; FINITE-NEXT: maxsd   %xmm0, %xmm1
744; FINITE-NEXT: movap{{[sd]}}  %xmm1, %xmm0
745; FINITE-NEXT: ret
746define double @ult_inverse_y(double %x) nounwind {
747  %c = fcmp ult double %x, -0.000000e+00
748  %d = select i1 %c, double -0.000000e+00, double %x
749  ret double %d
750}
751
752; CHECK-LABEL:      uge_y:
753; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
754; CHECK-NEXT: maxsd  %xmm0, %xmm1
755; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
756; CHECK-NEXT: ret
757; UNSAFE-LABEL:      uge_y:
758; UNSAFE-NEXT: maxsd  {{[^,]*}}, %xmm0
759; UNSAFE-NEXT: ret
760; FINITE-LABEL:      uge_y:
761; FINITE-NEXT: maxsd  {{[^,]*}}, %xmm0
762; FINITE-NEXT: ret
763define double @uge_y(double %x) nounwind {
764  %c = fcmp uge double %x, -0.000000e+00
765  %d = select i1 %c, double %x, double -0.000000e+00
766  ret double %d
767}
768
769; CHECK-LABEL:      ule_y:
770; CHECK-NEXT: movsd  {{[^,]*}}, %xmm1
771; CHECK-NEXT: minsd  %xmm0, %xmm1
772; CHECK-NEXT: movap{{[sd]}} %xmm1, %xmm0
773; CHECK-NEXT: ret
774; UNSAFE-LABEL:      ule_y:
775; UNSAFE-NEXT: minsd  {{[^,]*}}, %xmm0
776; UNSAFE-NEXT: ret
777; FINITE-LABEL:      ule_y:
778; FINITE-NEXT: minsd  {{[^,]*}}, %xmm0
779; FINITE-NEXT: ret
780define double @ule_y(double %x) nounwind {
781  %c = fcmp ule double %x, -0.000000e+00
782  %d = select i1 %c, double %x, double -0.000000e+00
783  ret double %d
784}
785
786; CHECK-LABEL:      uge_inverse_y:
787; CHECK-NEXT: minsd {{[^,]*}}, %xmm0
788; CHECK-NEXT: ret
789; UNSAFE-LABEL:      uge_inverse_y:
790; UNSAFE-NEXT: minsd {{[^,]*}}, %xmm0
791; UNSAFE-NEXT: ret
792; FINITE-LABEL:      uge_inverse_y:
793; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
794; FINITE-NEXT: minsd %xmm0, %xmm1
795; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
796; FINITE-NEXT: ret
797define double @uge_inverse_y(double %x) nounwind {
798  %c = fcmp uge double %x, -0.000000e+00
799  %d = select i1 %c, double -0.000000e+00, double %x
800  ret double %d
801}
802
803; CHECK-LABEL:      ule_inverse_y:
804; CHECK-NEXT: maxsd {{[^,]*}}, %xmm0
805; CHECK-NEXT: ret
806; UNSAFE-LABEL:      ule_inverse_y:
807; UNSAFE-NEXT: maxsd {{[^,]*}}, %xmm0
808; UNSAFE-NEXT: ret
809; FINITE-LABEL:      ule_inverse_y:
810; FINITE-NEXT: movsd {{[^,]*}}, %xmm1
811; FINITE-NEXT: maxsd %xmm0, %xmm1
812; FINITE-NEXT: movap{{[sd]}} %xmm1, %xmm0
813; FINITE-NEXT: ret
814define double @ule_inverse_y(double %x) nounwind {
815  %c = fcmp ule double %x, -0.000000e+00
816  %d = select i1 %c, double -0.000000e+00, double %x
817  ret double %d
818}
819; Test a few more misc. cases.
820
821; CHECK-LABEL: clampTo3k_a:
822; CHECK: minsd
823; UNSAFE-LABEL: clampTo3k_a:
824; UNSAFE: minsd
825; FINITE-LABEL: clampTo3k_a:
826; FINITE: minsd
827define double @clampTo3k_a(double %x) nounwind readnone {
828entry:
829  %0 = fcmp ogt double %x, 3.000000e+03           ; <i1> [#uses=1]
830  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
831  ret double %x_addr.0
832}
833
834; CHECK-LABEL: clampTo3k_b:
835; CHECK: minsd
836; UNSAFE-LABEL: clampTo3k_b:
837; UNSAFE: minsd
838; FINITE-LABEL: clampTo3k_b:
839; FINITE: minsd
840define double @clampTo3k_b(double %x) nounwind readnone {
841entry:
842  %0 = fcmp uge double %x, 3.000000e+03           ; <i1> [#uses=1]
843  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
844  ret double %x_addr.0
845}
846
847; CHECK-LABEL: clampTo3k_c:
848; CHECK: maxsd
849; UNSAFE-LABEL: clampTo3k_c:
850; UNSAFE: maxsd
851; FINITE-LABEL: clampTo3k_c:
852; FINITE: maxsd
853define double @clampTo3k_c(double %x) nounwind readnone {
854entry:
855  %0 = fcmp olt double %x, 3.000000e+03           ; <i1> [#uses=1]
856  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
857  ret double %x_addr.0
858}
859
860; CHECK-LABEL: clampTo3k_d:
861; CHECK: maxsd
862; UNSAFE-LABEL: clampTo3k_d:
863; UNSAFE: maxsd
864; FINITE-LABEL: clampTo3k_d:
865; FINITE: maxsd
866define double @clampTo3k_d(double %x) nounwind readnone {
867entry:
868  %0 = fcmp ule double %x, 3.000000e+03           ; <i1> [#uses=1]
869  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
870  ret double %x_addr.0
871}
872
873; CHECK-LABEL: clampTo3k_e:
874; CHECK: maxsd
875; UNSAFE-LABEL: clampTo3k_e:
876; UNSAFE: maxsd
877; FINITE-LABEL: clampTo3k_e:
878; FINITE: maxsd
879define double @clampTo3k_e(double %x) nounwind readnone {
880entry:
881  %0 = fcmp olt double %x, 3.000000e+03           ; <i1> [#uses=1]
882  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
883  ret double %x_addr.0
884}
885
886; CHECK-LABEL: clampTo3k_f:
887; CHECK: maxsd
888; UNSAFE-LABEL: clampTo3k_f:
889; UNSAFE: maxsd
890; FINITE-LABEL: clampTo3k_f:
891; FINITE: maxsd
892define double @clampTo3k_f(double %x) nounwind readnone {
893entry:
894  %0 = fcmp ule double %x, 3.000000e+03           ; <i1> [#uses=1]
895  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
896  ret double %x_addr.0
897}
898
899; CHECK-LABEL: clampTo3k_g:
900; CHECK: minsd
901; UNSAFE-LABEL: clampTo3k_g:
902; UNSAFE: minsd
903; FINITE-LABEL: clampTo3k_g:
904; FINITE: minsd
905define double @clampTo3k_g(double %x) nounwind readnone {
906entry:
907  %0 = fcmp ogt double %x, 3.000000e+03           ; <i1> [#uses=1]
908  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
909  ret double %x_addr.0
910}
911
912; CHECK-LABEL: clampTo3k_h:
913; CHECK: minsd
914; UNSAFE-LABEL: clampTo3k_h:
915; UNSAFE: minsd
916; FINITE-LABEL: clampTo3k_h:
917; FINITE: minsd
918define double @clampTo3k_h(double %x) nounwind readnone {
919entry:
920  %0 = fcmp uge double %x, 3.000000e+03           ; <i1> [#uses=1]
921  %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
922  ret double %x_addr.0
923}
924
925; UNSAFE-LABEL: test_maxpd:
926; UNSAFE: maxpd
927define <2 x double> @test_maxpd(<2 x double> %x, <2 x double> %y) {
928  %max_is_x = fcmp oge <2 x double> %x, %y
929  %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
930  ret <2 x double> %max
931}
932
933; UNSAFE-LABEL: test_minpd:
934; UNSAFE: minpd
935define <2 x double> @test_minpd(<2 x double> %x, <2 x double> %y) {
936  %min_is_x = fcmp ole <2 x double> %x, %y
937  %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
938  ret <2 x double> %min
939}
940
941; UNSAFE-LABEL: test_maxps:
942; UNSAFE: maxps
943define <4 x float> @test_maxps(<4 x float> %x, <4 x float> %y) {
944  %max_is_x = fcmp oge <4 x float> %x, %y
945  %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y
946  ret <4 x float> %max
947}
948
949; UNSAFE-LABEL: test_minps:
950; UNSAFE: minps
951define <4 x float> @test_minps(<4 x float> %x, <4 x float> %y) {
952  %min_is_x = fcmp ole <4 x float> %x, %y
953  %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y
954  ret <4 x float> %min
955}
956