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