1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2                                                 | FileCheck %s --check-prefix=ALL --check-prefix=STRICT
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 -enable-unsafe-fp-math -enable-no-nans-fp-math  | FileCheck %s --check-prefix=ALL --check-prefix=RELAX --check-prefix=UNSAFE
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=sse4.2 -enable-no-nans-fp-math                         | FileCheck %s --check-prefix=ALL --check-prefix=RELAX --check-prefix=FINITE
5
6; Some of these patterns can be matched as SSE min or max. Some of
7; them can be matched provided that the operands are swapped.
8; Some of them can't be matched at all and require a comparison
9; and a conditional branch.
10
11; The naming convention is {,x_,y_}{o,u}{gt,lt,ge,le}{,_inverse}
12;  _x: use 0.0 instead of %y
13;  _y: use -0.0 instead of %y
14; _inverse : swap the arms of the select.
15
16define double @ogt(double %x, double %y)  {
17; ALL-LABEL: ogt:
18; ALL:       # BB#0:
19; ALL-NEXT:    maxsd %xmm1, %xmm0
20; ALL-NEXT:    retq
21;
22  %c = fcmp ogt double %x, %y
23  %d = select i1 %c, double %x, double %y
24  ret double %d
25}
26
27define double @olt(double %x, double %y)  {
28; ALL-LABEL: olt:
29; ALL:       # BB#0:
30; ALL-NEXT:    minsd %xmm1, %xmm0
31; ALL-NEXT:    retq
32;
33  %c = fcmp olt double %x, %y
34  %d = select i1 %c, double %x, double %y
35  ret double %d
36}
37
38define double @ogt_inverse(double %x, double %y)  {
39; STRICT-LABEL: ogt_inverse:
40; STRICT:       # BB#0:
41; STRICT-NEXT:    minsd %xmm0, %xmm1
42; STRICT-NEXT:    movapd %xmm1, %xmm0
43; STRICT-NEXT:    retq
44;
45; UNSAFE-LABEL: ogt_inverse:
46; UNSAFE:       # BB#0:
47; UNSAFE-NEXT:    minsd %xmm1, %xmm0
48; UNSAFE-NEXT:    retq
49;
50; FINITE-LABEL: ogt_inverse:
51; FINITE:       # BB#0:
52; FINITE-NEXT:    minsd %xmm0, %xmm1
53; FINITE-NEXT:    movapd %xmm1, %xmm0
54; FINITE-NEXT:    retq
55;
56  %c = fcmp ogt double %x, %y
57  %d = select i1 %c, double %y, double %x
58  ret double %d
59}
60
61define double @olt_inverse(double %x, double %y)  {
62; STRICT-LABEL: olt_inverse:
63; STRICT:       # BB#0:
64; STRICT-NEXT:    maxsd %xmm0, %xmm1
65; STRICT-NEXT:    movapd %xmm1, %xmm0
66; STRICT-NEXT:    retq
67;
68; UNSAFE-LABEL: olt_inverse:
69; UNSAFE:       # BB#0:
70; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
71; UNSAFE-NEXT:    retq
72;
73; FINITE-LABEL: olt_inverse:
74; FINITE:       # BB#0:
75; FINITE-NEXT:    maxsd %xmm0, %xmm1
76; FINITE-NEXT:    movapd %xmm1, %xmm0
77; FINITE-NEXT:    retq
78;
79  %c = fcmp olt double %x, %y
80  %d = select i1 %c, double %y, double %x
81  ret double %d
82}
83
84define double @oge(double %x, double %y)  {
85; STRICT-LABEL: oge:
86; STRICT:       # BB#0:
87; STRICT-NEXT:    movaps %xmm1, %xmm2
88; STRICT-NEXT:    cmplesd %xmm0, %xmm2
89; STRICT-NEXT:    andps %xmm2, %xmm0
90; STRICT-NEXT:    andnps %xmm1, %xmm2
91; STRICT-NEXT:    orps %xmm2, %xmm0
92; STRICT-NEXT:    retq
93;
94; RELAX-LABEL: oge:
95; RELAX:       # BB#0:
96; RELAX-NEXT:    maxsd %xmm1, %xmm0
97; RELAX-NEXT:    retq
98;
99  %c = fcmp oge double %x, %y
100  %d = select i1 %c, double %x, double %y
101  ret double %d
102}
103
104define double @ole(double %x, double %y)  {
105; STRICT-LABEL: ole:
106; STRICT:       # BB#0:
107; STRICT-NEXT:    movaps %xmm0, %xmm2
108; STRICT-NEXT:    cmplesd %xmm1, %xmm2
109; STRICT-NEXT:    andps %xmm2, %xmm0
110; STRICT-NEXT:    andnps %xmm1, %xmm2
111; STRICT-NEXT:    orps %xmm0, %xmm2
112; STRICT-NEXT:    movaps %xmm2, %xmm0
113; STRICT-NEXT:    retq
114;
115; RELAX-LABEL: ole:
116; RELAX:       # BB#0:
117; RELAX-NEXT:    minsd %xmm1, %xmm0
118; RELAX-NEXT:    retq
119;
120  %c = fcmp ole double %x, %y
121  %d = select i1 %c, double %x, double %y
122  ret double %d
123}
124
125define double @oge_inverse(double %x, double %y)  {
126; STRICT-LABEL: oge_inverse:
127; STRICT:       # BB#0:
128; STRICT-NEXT:    movaps %xmm1, %xmm2
129; STRICT-NEXT:    cmplesd %xmm0, %xmm2
130; STRICT-NEXT:    andps %xmm2, %xmm1
131; STRICT-NEXT:    andnps %xmm0, %xmm2
132; STRICT-NEXT:    orps %xmm1, %xmm2
133; STRICT-NEXT:    movaps %xmm2, %xmm0
134; STRICT-NEXT:    retq
135;
136; UNSAFE-LABEL: oge_inverse:
137; UNSAFE:       # BB#0:
138; UNSAFE-NEXT:    minsd %xmm1, %xmm0
139; UNSAFE-NEXT:    retq
140;
141; FINITE-LABEL: oge_inverse:
142; FINITE:       # BB#0:
143; FINITE-NEXT:    minsd %xmm0, %xmm1
144; FINITE-NEXT:    movapd %xmm1, %xmm0
145; FINITE-NEXT:    retq
146;
147  %c = fcmp oge double %x, %y
148  %d = select i1 %c, double %y, double %x
149  ret double %d
150}
151
152define double @ole_inverse(double %x, double %y)  {
153; STRICT-LABEL: ole_inverse:
154; STRICT:       # BB#0:
155; STRICT-NEXT:    movaps %xmm0, %xmm2
156; STRICT-NEXT:    cmplesd %xmm1, %xmm2
157; STRICT-NEXT:    andps %xmm2, %xmm1
158; STRICT-NEXT:    andnps %xmm0, %xmm2
159; STRICT-NEXT:    orps %xmm1, %xmm2
160; STRICT-NEXT:    movaps %xmm2, %xmm0
161; STRICT-NEXT:    retq
162;
163; UNSAFE-LABEL: ole_inverse:
164; UNSAFE:       # BB#0:
165; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
166; UNSAFE-NEXT:    retq
167;
168; FINITE-LABEL: ole_inverse:
169; FINITE:       # BB#0:
170; FINITE-NEXT:    maxsd %xmm0, %xmm1
171; FINITE-NEXT:    movapd %xmm1, %xmm0
172; FINITE-NEXT:    retq
173;
174  %c = fcmp ole double %x, %y
175  %d = select i1 %c, double %y, double %x
176  ret double %d
177}
178
179define double @ogt_x(double %x)  {
180; ALL-LABEL: ogt_x:
181; ALL:       # BB#0:
182; ALL-NEXT:    xorpd %xmm1, %xmm1
183; ALL-NEXT:    maxsd %xmm1, %xmm0
184; ALL-NEXT:    retq
185;
186  %c = fcmp ogt double %x, 0.000000e+00
187  %d = select i1 %c, double %x, double 0.000000e+00
188  ret double %d
189}
190
191define double @olt_x(double %x)  {
192; ALL-LABEL: olt_x:
193; ALL:       # BB#0:
194; ALL-NEXT:    xorpd %xmm1, %xmm1
195; ALL-NEXT:    minsd %xmm1, %xmm0
196; ALL-NEXT:    retq
197;
198  %c = fcmp olt double %x, 0.000000e+00
199  %d = select i1 %c, double %x, double 0.000000e+00
200  ret double %d
201}
202
203define double @ogt_inverse_x(double %x)  {
204; STRICT-LABEL: ogt_inverse_x:
205; STRICT:       # BB#0:
206; STRICT-NEXT:    xorpd %xmm1, %xmm1
207; STRICT-NEXT:    minsd %xmm0, %xmm1
208; STRICT-NEXT:    movapd %xmm1, %xmm0
209; STRICT-NEXT:    retq
210;
211; UNSAFE-LABEL: ogt_inverse_x:
212; UNSAFE:       # BB#0:
213; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
214; UNSAFE-NEXT:    minsd %xmm1, %xmm0
215; UNSAFE-NEXT:    retq
216;
217; FINITE-LABEL: ogt_inverse_x:
218; FINITE:       # BB#0:
219; FINITE-NEXT:    xorpd %xmm1, %xmm1
220; FINITE-NEXT:    minsd %xmm0, %xmm1
221; FINITE-NEXT:    movapd %xmm1, %xmm0
222; FINITE-NEXT:    retq
223;
224  %c = fcmp ogt double %x, 0.000000e+00
225  %d = select i1 %c, double 0.000000e+00, double %x
226  ret double %d
227}
228
229define double @olt_inverse_x(double %x)  {
230; STRICT-LABEL: olt_inverse_x:
231; STRICT:       # BB#0:
232; STRICT-NEXT:    xorpd %xmm1, %xmm1
233; STRICT-NEXT:    maxsd %xmm0, %xmm1
234; STRICT-NEXT:    movapd %xmm1, %xmm0
235; STRICT-NEXT:    retq
236;
237; UNSAFE-LABEL: olt_inverse_x:
238; UNSAFE:       # BB#0:
239; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
240; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
241; UNSAFE-NEXT:    retq
242;
243; FINITE-LABEL: olt_inverse_x:
244; FINITE:       # BB#0:
245; FINITE-NEXT:    xorpd %xmm1, %xmm1
246; FINITE-NEXT:    maxsd %xmm0, %xmm1
247; FINITE-NEXT:    movapd %xmm1, %xmm0
248; FINITE-NEXT:    retq
249;
250  %c = fcmp olt double %x, 0.000000e+00
251  %d = select i1 %c, double 0.000000e+00, double %x
252  ret double %d
253}
254
255define double @oge_x(double %x)  {
256; STRICT-LABEL: oge_x:
257; STRICT:       # BB#0:
258; STRICT-NEXT:    xorps %xmm1, %xmm1
259; STRICT-NEXT:    cmplesd %xmm0, %xmm1
260; STRICT-NEXT:    andps %xmm1, %xmm0
261; STRICT-NEXT:    retq
262;
263; RELAX-LABEL: oge_x:
264; RELAX:       # BB#0:
265; RELAX-NEXT:    xorpd %xmm1, %xmm1
266; RELAX-NEXT:    maxsd %xmm1, %xmm0
267; RELAX-NEXT:    retq
268;
269  %c = fcmp oge double %x, 0.000000e+00
270  %d = select i1 %c, double %x, double 0.000000e+00
271  ret double %d
272}
273
274define double @ole_x(double %x)  {
275; STRICT-LABEL: ole_x:
276; STRICT:       # BB#0:
277; STRICT-NEXT:    xorps %xmm2, %xmm2
278; STRICT-NEXT:    movaps %xmm0, %xmm1
279; STRICT-NEXT:    cmplesd %xmm2, %xmm1
280; STRICT-NEXT:    andps %xmm0, %xmm1
281; STRICT-NEXT:    movaps %xmm1, %xmm0
282; STRICT-NEXT:    retq
283;
284; RELAX-LABEL: ole_x:
285; RELAX:       # BB#0:
286; RELAX-NEXT:    xorpd %xmm1, %xmm1
287; RELAX-NEXT:    minsd %xmm1, %xmm0
288; RELAX-NEXT:    retq
289;
290  %c = fcmp ole double %x, 0.000000e+00
291  %d = select i1 %c, double %x, double 0.000000e+00
292  ret double %d
293}
294
295define double @oge_inverse_x(double %x)  {
296; STRICT-LABEL: oge_inverse_x:
297; STRICT:       # BB#0:
298; STRICT-NEXT:    xorps %xmm1, %xmm1
299; STRICT-NEXT:    cmplesd %xmm0, %xmm1
300; STRICT-NEXT:    andnps %xmm0, %xmm1
301; STRICT-NEXT:    movaps %xmm1, %xmm0
302; STRICT-NEXT:    retq
303;
304; UNSAFE-LABEL: oge_inverse_x:
305; UNSAFE:       # BB#0:
306; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
307; UNSAFE-NEXT:    minsd %xmm1, %xmm0
308; UNSAFE-NEXT:    retq
309;
310; FINITE-LABEL: oge_inverse_x:
311; FINITE:       # BB#0:
312; FINITE-NEXT:    xorpd %xmm1, %xmm1
313; FINITE-NEXT:    minsd %xmm0, %xmm1
314; FINITE-NEXT:    movapd %xmm1, %xmm0
315; FINITE-NEXT:    retq
316;
317  %c = fcmp oge double %x, 0.000000e+00
318  %d = select i1 %c, double 0.000000e+00, double %x
319  ret double %d
320}
321
322define double @ole_inverse_x(double %x)  {
323; STRICT-LABEL: ole_inverse_x:
324; STRICT:       # BB#0:
325; STRICT-NEXT:    xorps %xmm2, %xmm2
326; STRICT-NEXT:    movaps %xmm0, %xmm1
327; STRICT-NEXT:    cmplesd %xmm2, %xmm1
328; STRICT-NEXT:    andnps %xmm0, %xmm1
329; STRICT-NEXT:    movaps %xmm1, %xmm0
330; STRICT-NEXT:    retq
331;
332; UNSAFE-LABEL: ole_inverse_x:
333; UNSAFE:       # BB#0:
334; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
335; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
336; UNSAFE-NEXT:    retq
337;
338; FINITE-LABEL: ole_inverse_x:
339; FINITE:       # BB#0:
340; FINITE-NEXT:    xorpd %xmm1, %xmm1
341; FINITE-NEXT:    maxsd %xmm0, %xmm1
342; FINITE-NEXT:    movapd %xmm1, %xmm0
343; FINITE-NEXT:    retq
344;
345  %c = fcmp ole double %x, 0.000000e+00
346  %d = select i1 %c, double 0.000000e+00, double %x
347  ret double %d
348}
349
350define double @ugt(double %x, double %y)  {
351; STRICT-LABEL: ugt:
352; STRICT:       # BB#0:
353; STRICT-NEXT:    movaps %xmm0, %xmm2
354; STRICT-NEXT:    cmpnlesd %xmm1, %xmm2
355; STRICT-NEXT:    andps %xmm2, %xmm0
356; STRICT-NEXT:    andnps %xmm1, %xmm2
357; STRICT-NEXT:    orps %xmm0, %xmm2
358; STRICT-NEXT:    movaps %xmm2, %xmm0
359; STRICT-NEXT:    retq
360;
361; RELAX-LABEL: ugt:
362; RELAX:       # BB#0:
363; RELAX-NEXT:    maxsd %xmm1, %xmm0
364; RELAX-NEXT:    retq
365;
366  %c = fcmp ugt double %x, %y
367  %d = select i1 %c, double %x, double %y
368  ret double %d
369}
370
371define double @ult(double %x, double %y)  {
372; STRICT-LABEL: ult:
373; STRICT:       # BB#0:
374; STRICT-NEXT:    movaps %xmm1, %xmm2
375; STRICT-NEXT:    cmpnlesd %xmm0, %xmm2
376; STRICT-NEXT:    andps %xmm2, %xmm0
377; STRICT-NEXT:    andnps %xmm1, %xmm2
378; STRICT-NEXT:    orps %xmm2, %xmm0
379; STRICT-NEXT:    retq
380;
381; RELAX-LABEL: ult:
382; RELAX:       # BB#0:
383; RELAX-NEXT:    minsd %xmm1, %xmm0
384; RELAX-NEXT:    retq
385;
386  %c = fcmp ult double %x, %y
387  %d = select i1 %c, double %x, double %y
388  ret double %d
389}
390
391define double @ugt_inverse(double %x, double %y)  {
392; STRICT-LABEL: ugt_inverse:
393; STRICT:       # BB#0:
394; STRICT-NEXT:    movaps %xmm0, %xmm2
395; STRICT-NEXT:    cmpnlesd %xmm1, %xmm2
396; STRICT-NEXT:    andps %xmm2, %xmm1
397; STRICT-NEXT:    andnps %xmm0, %xmm2
398; STRICT-NEXT:    orps %xmm1, %xmm2
399; STRICT-NEXT:    movaps %xmm2, %xmm0
400; STRICT-NEXT:    retq
401;
402; UNSAFE-LABEL: ugt_inverse:
403; UNSAFE:       # BB#0:
404; UNSAFE-NEXT:    minsd %xmm1, %xmm0
405; UNSAFE-NEXT:    retq
406;
407; FINITE-LABEL: ugt_inverse:
408; FINITE:       # BB#0:
409; FINITE-NEXT:    minsd %xmm0, %xmm1
410; FINITE-NEXT:    movapd %xmm1, %xmm0
411; FINITE-NEXT:    retq
412;
413  %c = fcmp ugt double %x, %y
414  %d = select i1 %c, double %y, double %x
415  ret double %d
416}
417
418define double @ult_inverse(double %x, double %y)  {
419; STRICT-LABEL: ult_inverse:
420; STRICT:       # BB#0:
421; STRICT-NEXT:    movaps %xmm1, %xmm2
422; STRICT-NEXT:    cmpnlesd %xmm0, %xmm2
423; STRICT-NEXT:    andps %xmm2, %xmm1
424; STRICT-NEXT:    andnps %xmm0, %xmm2
425; STRICT-NEXT:    orps %xmm1, %xmm2
426; STRICT-NEXT:    movaps %xmm2, %xmm0
427; STRICT-NEXT:    retq
428;
429; UNSAFE-LABEL: ult_inverse:
430; UNSAFE:       # BB#0:
431; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
432; UNSAFE-NEXT:    retq
433;
434; FINITE-LABEL: ult_inverse:
435; FINITE:       # BB#0:
436; FINITE-NEXT:    maxsd %xmm0, %xmm1
437; FINITE-NEXT:    movapd %xmm1, %xmm0
438; FINITE-NEXT:    retq
439;
440  %c = fcmp ult double %x, %y
441  %d = select i1 %c, double %y, double %x
442  ret double %d
443}
444
445define double @uge(double %x, double %y)  {
446; STRICT-LABEL: uge:
447; STRICT:       # BB#0:
448; STRICT-NEXT:    maxsd %xmm0, %xmm1
449; STRICT-NEXT:    movapd %xmm1, %xmm0
450; STRICT-NEXT:    retq
451;
452; RELAX-LABEL: uge:
453; RELAX:       # BB#0:
454; RELAX-NEXT:    maxsd %xmm1, %xmm0
455; RELAX-NEXT:    retq
456;
457  %c = fcmp uge double %x, %y
458  %d = select i1 %c, double %x, double %y
459  ret double %d
460}
461
462define double @ule(double %x, double %y)  {
463; STRICT-LABEL: ule:
464; STRICT:       # BB#0:
465; STRICT-NEXT:    minsd %xmm0, %xmm1
466; STRICT-NEXT:    movapd %xmm1, %xmm0
467; STRICT-NEXT:    retq
468;
469; RELAX-LABEL: ule:
470; RELAX:       # BB#0:
471; RELAX-NEXT:    minsd %xmm1, %xmm0
472; RELAX-NEXT:    retq
473;
474  %c = fcmp ule double %x, %y
475  %d = select i1 %c, double %x, double %y
476  ret double %d
477}
478
479define double @uge_inverse(double %x, double %y)  {
480; STRICT-LABEL: uge_inverse:
481; STRICT:       # BB#0:
482; STRICT-NEXT:    minsd %xmm1, %xmm0
483; STRICT-NEXT:    retq
484;
485; UNSAFE-LABEL: uge_inverse:
486; UNSAFE:       # BB#0:
487; UNSAFE-NEXT:    minsd %xmm1, %xmm0
488; UNSAFE-NEXT:    retq
489;
490; FINITE-LABEL: uge_inverse:
491; FINITE:       # BB#0:
492; FINITE-NEXT:    minsd %xmm0, %xmm1
493; FINITE-NEXT:    movapd %xmm1, %xmm0
494; FINITE-NEXT:    retq
495;
496  %c = fcmp uge double %x, %y
497  %d = select i1 %c, double %y, double %x
498  ret double %d
499}
500
501define double @ule_inverse(double %x, double %y)  {
502; STRICT-LABEL: ule_inverse:
503; STRICT:       # BB#0:
504; STRICT-NEXT:    maxsd %xmm1, %xmm0
505; STRICT-NEXT:    retq
506;
507; UNSAFE-LABEL: ule_inverse:
508; UNSAFE:       # BB#0:
509; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
510; UNSAFE-NEXT:    retq
511;
512; FINITE-LABEL: ule_inverse:
513; FINITE:       # BB#0:
514; FINITE-NEXT:    maxsd %xmm0, %xmm1
515; FINITE-NEXT:    movapd %xmm1, %xmm0
516; FINITE-NEXT:    retq
517;
518  %c = fcmp ule double %x, %y
519  %d = select i1 %c, double %y, double %x
520  ret double %d
521}
522
523define double @ugt_x(double %x)  {
524; STRICT-LABEL: ugt_x:
525; STRICT:       # BB#0:
526; STRICT-NEXT:    xorps %xmm2, %xmm2
527; STRICT-NEXT:    movaps %xmm0, %xmm1
528; STRICT-NEXT:    cmpnlesd %xmm2, %xmm1
529; STRICT-NEXT:    andps %xmm0, %xmm1
530; STRICT-NEXT:    movaps %xmm1, %xmm0
531; STRICT-NEXT:    retq
532;
533; RELAX-LABEL: ugt_x:
534; RELAX:       # BB#0:
535; RELAX-NEXT:    xorpd %xmm1, %xmm1
536; RELAX-NEXT:    maxsd %xmm1, %xmm0
537; RELAX-NEXT:    retq
538;
539  %c = fcmp ugt double %x, 0.000000e+00
540  %d = select i1 %c, double %x, double 0.000000e+00
541  ret double %d
542}
543
544define double @ult_x(double %x)  {
545; STRICT-LABEL: ult_x:
546; STRICT:       # BB#0:
547; STRICT-NEXT:    xorps %xmm1, %xmm1
548; STRICT-NEXT:    cmpnlesd %xmm0, %xmm1
549; STRICT-NEXT:    andps %xmm1, %xmm0
550; STRICT-NEXT:    retq
551;
552; RELAX-LABEL: ult_x:
553; RELAX:       # BB#0:
554; RELAX-NEXT:    xorpd %xmm1, %xmm1
555; RELAX-NEXT:    minsd %xmm1, %xmm0
556; RELAX-NEXT:    retq
557;
558  %c = fcmp ult double %x, 0.000000e+00
559  %d = select i1 %c, double %x, double 0.000000e+00
560  ret double %d
561}
562
563define double @ugt_inverse_x(double %x)  {
564; STRICT-LABEL: ugt_inverse_x:
565; STRICT:       # BB#0:
566; STRICT-NEXT:    xorps %xmm2, %xmm2
567; STRICT-NEXT:    movaps %xmm0, %xmm1
568; STRICT-NEXT:    cmpnlesd %xmm2, %xmm1
569; STRICT-NEXT:    andnps %xmm0, %xmm1
570; STRICT-NEXT:    movaps %xmm1, %xmm0
571; STRICT-NEXT:    retq
572;
573; UNSAFE-LABEL: ugt_inverse_x:
574; UNSAFE:       # BB#0:
575; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
576; UNSAFE-NEXT:    minsd %xmm1, %xmm0
577; UNSAFE-NEXT:    retq
578;
579; FINITE-LABEL: ugt_inverse_x:
580; FINITE:       # BB#0:
581; FINITE-NEXT:    xorpd %xmm1, %xmm1
582; FINITE-NEXT:    minsd %xmm0, %xmm1
583; FINITE-NEXT:    movapd %xmm1, %xmm0
584; FINITE-NEXT:    retq
585;
586  %c = fcmp ugt double %x, 0.000000e+00
587  %d = select i1 %c, double 0.000000e+00, double %x
588  ret double %d
589}
590
591define double @ult_inverse_x(double %x)  {
592; STRICT-LABEL: ult_inverse_x:
593; STRICT:       # BB#0:
594; STRICT-NEXT:    xorps %xmm1, %xmm1
595; STRICT-NEXT:    cmpnlesd %xmm0, %xmm1
596; STRICT-NEXT:    andnps %xmm0, %xmm1
597; STRICT-NEXT:    movaps %xmm1, %xmm0
598; STRICT-NEXT:    retq
599;
600; UNSAFE-LABEL: ult_inverse_x:
601; UNSAFE:       # BB#0:
602; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
603; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
604; UNSAFE-NEXT:    retq
605;
606; FINITE-LABEL: ult_inverse_x:
607; FINITE:       # BB#0:
608; FINITE-NEXT:    xorpd %xmm1, %xmm1
609; FINITE-NEXT:    maxsd %xmm0, %xmm1
610; FINITE-NEXT:    movapd %xmm1, %xmm0
611; FINITE-NEXT:    retq
612;
613  %c = fcmp ult double %x, 0.000000e+00
614  %d = select i1 %c, double 0.000000e+00, double %x
615  ret double %d
616}
617
618define double @uge_x(double %x)  {
619; STRICT-LABEL: uge_x:
620; STRICT:       # BB#0:
621; STRICT-NEXT:    xorpd %xmm1, %xmm1
622; STRICT-NEXT:    maxsd %xmm0, %xmm1
623; STRICT-NEXT:    movapd %xmm1, %xmm0
624; STRICT-NEXT:    retq
625;
626; RELAX-LABEL: uge_x:
627; RELAX:       # BB#0:
628; RELAX-NEXT:    xorpd %xmm1, %xmm1
629; RELAX-NEXT:    maxsd %xmm1, %xmm0
630; RELAX-NEXT:    retq
631;
632  %c = fcmp uge double %x, 0.000000e+00
633  %d = select i1 %c, double %x, double 0.000000e+00
634  ret double %d
635}
636
637define double @ule_x(double %x)  {
638; STRICT-LABEL: ule_x:
639; STRICT:       # BB#0:
640; STRICT-NEXT:    xorpd %xmm1, %xmm1
641; STRICT-NEXT:    minsd %xmm0, %xmm1
642; STRICT-NEXT:    movapd %xmm1, %xmm0
643; STRICT-NEXT:    retq
644;
645; RELAX-LABEL: ule_x:
646; RELAX:       # BB#0:
647; RELAX-NEXT:    xorpd %xmm1, %xmm1
648; RELAX-NEXT:    minsd %xmm1, %xmm0
649; RELAX-NEXT:    retq
650;
651  %c = fcmp ule double %x, 0.000000e+00
652  %d = select i1 %c, double %x, double 0.000000e+00
653  ret double %d
654}
655
656define double @uge_inverse_x(double %x)  {
657; STRICT-LABEL: uge_inverse_x:
658; STRICT:       # BB#0:
659; STRICT-NEXT:    xorpd %xmm1, %xmm1
660; STRICT-NEXT:    minsd %xmm1, %xmm0
661; STRICT-NEXT:    retq
662;
663; UNSAFE-LABEL: uge_inverse_x:
664; UNSAFE:       # BB#0:
665; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
666; UNSAFE-NEXT:    minsd %xmm1, %xmm0
667; UNSAFE-NEXT:    retq
668;
669; FINITE-LABEL: uge_inverse_x:
670; FINITE:       # BB#0:
671; FINITE-NEXT:    xorpd %xmm1, %xmm1
672; FINITE-NEXT:    minsd %xmm0, %xmm1
673; FINITE-NEXT:    movapd %xmm1, %xmm0
674; FINITE-NEXT:    retq
675;
676  %c = fcmp uge double %x, 0.000000e+00
677  %d = select i1 %c, double 0.000000e+00, double %x
678  ret double %d
679}
680
681define double @ule_inverse_x(double %x)  {
682; STRICT-LABEL: ule_inverse_x:
683; STRICT:       # BB#0:
684; STRICT-NEXT:    xorpd %xmm1, %xmm1
685; STRICT-NEXT:    maxsd %xmm1, %xmm0
686; STRICT-NEXT:    retq
687;
688; UNSAFE-LABEL: ule_inverse_x:
689; UNSAFE:       # BB#0:
690; UNSAFE-NEXT:    xorpd %xmm1, %xmm1
691; UNSAFE-NEXT:    maxsd %xmm1, %xmm0
692; UNSAFE-NEXT:    retq
693;
694; FINITE-LABEL: ule_inverse_x:
695; FINITE:       # BB#0:
696; FINITE-NEXT:    xorpd %xmm1, %xmm1
697; FINITE-NEXT:    maxsd %xmm0, %xmm1
698; FINITE-NEXT:    movapd %xmm1, %xmm0
699; FINITE-NEXT:    retq
700;
701  %c = fcmp ule double %x, 0.000000e+00
702  %d = select i1 %c, double 0.000000e+00, double %x
703  ret double %d
704}
705
706define double @ogt_y(double %x)  {
707; ALL-LABEL: ogt_y:
708; ALL:       # BB#0:
709; ALL-NEXT:    maxsd {{.*}}(%rip), %xmm0
710; ALL-NEXT:    retq
711;
712  %c = fcmp ogt double %x, -0.000000e+00
713  %d = select i1 %c, double %x, double -0.000000e+00
714  ret double %d
715}
716
717define double @olt_y(double %x)  {
718; ALL-LABEL: olt_y:
719; ALL:       # BB#0:
720; ALL-NEXT:    minsd {{.*}}(%rip), %xmm0
721; ALL-NEXT:    retq
722;
723  %c = fcmp olt double %x, -0.000000e+00
724  %d = select i1 %c, double %x, double -0.000000e+00
725  ret double %d
726}
727
728define double @ogt_inverse_y(double %x)  {
729; STRICT-LABEL: ogt_inverse_y:
730; STRICT:       # BB#0:
731; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
732; STRICT-NEXT:    minsd %xmm0, %xmm1
733; STRICT-NEXT:    movapd %xmm1, %xmm0
734; STRICT-NEXT:    retq
735;
736; UNSAFE-LABEL: ogt_inverse_y:
737; UNSAFE:       # BB#0:
738; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
739; UNSAFE-NEXT:    retq
740;
741; FINITE-LABEL: ogt_inverse_y:
742; FINITE:       # BB#0:
743; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
744; FINITE-NEXT:    minsd %xmm0, %xmm1
745; FINITE-NEXT:    movapd %xmm1, %xmm0
746; FINITE-NEXT:    retq
747;
748  %c = fcmp ogt double %x, -0.000000e+00
749  %d = select i1 %c, double -0.000000e+00, double %x
750  ret double %d
751}
752
753define double @olt_inverse_y(double %x)  {
754; STRICT-LABEL: olt_inverse_y:
755; STRICT:       # BB#0:
756; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
757; STRICT-NEXT:    maxsd %xmm0, %xmm1
758; STRICT-NEXT:    movapd %xmm1, %xmm0
759; STRICT-NEXT:    retq
760;
761; UNSAFE-LABEL: olt_inverse_y:
762; UNSAFE:       # BB#0:
763; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
764; UNSAFE-NEXT:    retq
765;
766; FINITE-LABEL: olt_inverse_y:
767; FINITE:       # BB#0:
768; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
769; FINITE-NEXT:    maxsd %xmm0, %xmm1
770; FINITE-NEXT:    movapd %xmm1, %xmm0
771; FINITE-NEXT:    retq
772;
773  %c = fcmp olt double %x, -0.000000e+00
774  %d = select i1 %c, double -0.000000e+00, double %x
775  ret double %d
776}
777
778define double @oge_y(double %x)  {
779; STRICT-LABEL: oge_y:
780; STRICT:       # BB#0:
781; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
782; STRICT-NEXT:    movapd %xmm1, %xmm2
783; STRICT-NEXT:    cmplesd %xmm0, %xmm2
784; STRICT-NEXT:    andpd %xmm2, %xmm0
785; STRICT-NEXT:    andnpd %xmm1, %xmm2
786; STRICT-NEXT:    orpd %xmm2, %xmm0
787; STRICT-NEXT:    retq
788;
789; RELAX-LABEL: oge_y:
790; RELAX:       # BB#0:
791; RELAX-NEXT:    maxsd {{.*}}(%rip), %xmm0
792; RELAX-NEXT:    retq
793;
794  %c = fcmp oge double %x, -0.000000e+00
795  %d = select i1 %c, double %x, double -0.000000e+00
796  ret double %d
797}
798
799define double @ole_y(double %x)  {
800; STRICT-LABEL: ole_y:
801; STRICT:       # BB#0:
802; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
803; STRICT-NEXT:    movapd %xmm0, %xmm1
804; STRICT-NEXT:    cmplesd %xmm2, %xmm1
805; STRICT-NEXT:    andpd %xmm1, %xmm0
806; STRICT-NEXT:    andnpd %xmm2, %xmm1
807; STRICT-NEXT:    orpd %xmm0, %xmm1
808; STRICT-NEXT:    movapd %xmm1, %xmm0
809; STRICT-NEXT:    retq
810;
811; RELAX-LABEL: ole_y:
812; RELAX:       # BB#0:
813; RELAX-NEXT:    minsd {{.*}}(%rip), %xmm0
814; RELAX-NEXT:    retq
815;
816  %c = fcmp ole double %x, -0.000000e+00
817  %d = select i1 %c, double %x, double -0.000000e+00
818  ret double %d
819}
820
821define double @oge_inverse_y(double %x)  {
822; STRICT-LABEL: oge_inverse_y:
823; STRICT:       # BB#0:
824; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
825; STRICT-NEXT:    movapd %xmm2, %xmm1
826; STRICT-NEXT:    cmplesd %xmm0, %xmm1
827; STRICT-NEXT:    andpd %xmm1, %xmm2
828; STRICT-NEXT:    andnpd %xmm0, %xmm1
829; STRICT-NEXT:    orpd %xmm2, %xmm1
830; STRICT-NEXT:    movapd %xmm1, %xmm0
831; STRICT-NEXT:    retq
832;
833; UNSAFE-LABEL: oge_inverse_y:
834; UNSAFE:       # BB#0:
835; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
836; UNSAFE-NEXT:    retq
837;
838; FINITE-LABEL: oge_inverse_y:
839; FINITE:       # BB#0:
840; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
841; FINITE-NEXT:    minsd %xmm0, %xmm1
842; FINITE-NEXT:    movapd %xmm1, %xmm0
843; FINITE-NEXT:    retq
844;
845  %c = fcmp oge double %x, -0.000000e+00
846  %d = select i1 %c, double -0.000000e+00, double %x
847  ret double %d
848}
849
850define double @ole_inverse_y(double %x)  {
851; STRICT-LABEL: ole_inverse_y:
852; STRICT:       # BB#0:
853; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
854; STRICT-NEXT:    movapd %xmm0, %xmm1
855; STRICT-NEXT:    cmplesd %xmm2, %xmm1
856; STRICT-NEXT:    andpd %xmm1, %xmm2
857; STRICT-NEXT:    andnpd %xmm0, %xmm1
858; STRICT-NEXT:    orpd %xmm2, %xmm1
859; STRICT-NEXT:    movapd %xmm1, %xmm0
860; STRICT-NEXT:    retq
861;
862; UNSAFE-LABEL: ole_inverse_y:
863; UNSAFE:       # BB#0:
864; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
865; UNSAFE-NEXT:    retq
866;
867; FINITE-LABEL: ole_inverse_y:
868; FINITE:       # BB#0:
869; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
870; FINITE-NEXT:    maxsd %xmm0, %xmm1
871; FINITE-NEXT:    movapd %xmm1, %xmm0
872; FINITE-NEXT:    retq
873;
874  %c = fcmp ole double %x, -0.000000e+00
875  %d = select i1 %c, double -0.000000e+00, double %x
876  ret double %d
877}
878
879define double @ugt_y(double %x)  {
880; STRICT-LABEL: ugt_y:
881; STRICT:       # BB#0:
882; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
883; STRICT-NEXT:    movapd %xmm0, %xmm1
884; STRICT-NEXT:    cmpnlesd %xmm2, %xmm1
885; STRICT-NEXT:    andpd %xmm1, %xmm0
886; STRICT-NEXT:    andnpd %xmm2, %xmm1
887; STRICT-NEXT:    orpd %xmm0, %xmm1
888; STRICT-NEXT:    movapd %xmm1, %xmm0
889; STRICT-NEXT:    retq
890;
891; RELAX-LABEL: ugt_y:
892; RELAX:       # BB#0:
893; RELAX-NEXT:    maxsd {{.*}}(%rip), %xmm0
894; RELAX-NEXT:    retq
895;
896  %c = fcmp ugt double %x, -0.000000e+00
897  %d = select i1 %c, double %x, double -0.000000e+00
898  ret double %d
899}
900
901define double @ult_y(double %x)  {
902; STRICT-LABEL: ult_y:
903; STRICT:       # BB#0:
904; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
905; STRICT-NEXT:    movapd %xmm1, %xmm2
906; STRICT-NEXT:    cmpnlesd %xmm0, %xmm2
907; STRICT-NEXT:    andpd %xmm2, %xmm0
908; STRICT-NEXT:    andnpd %xmm1, %xmm2
909; STRICT-NEXT:    orpd %xmm2, %xmm0
910; STRICT-NEXT:    retq
911;
912; RELAX-LABEL: ult_y:
913; RELAX:       # BB#0:
914; RELAX-NEXT:    minsd {{.*}}(%rip), %xmm0
915; RELAX-NEXT:    retq
916;
917  %c = fcmp ult double %x, -0.000000e+00
918  %d = select i1 %c, double %x, double -0.000000e+00
919  ret double %d
920}
921
922define double @ugt_inverse_y(double %x)  {
923; STRICT-LABEL: ugt_inverse_y:
924; STRICT:       # BB#0:
925; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
926; STRICT-NEXT:    movapd %xmm0, %xmm1
927; STRICT-NEXT:    cmpnlesd %xmm2, %xmm1
928; STRICT-NEXT:    andpd %xmm1, %xmm2
929; STRICT-NEXT:    andnpd %xmm0, %xmm1
930; STRICT-NEXT:    orpd %xmm2, %xmm1
931; STRICT-NEXT:    movapd %xmm1, %xmm0
932; STRICT-NEXT:    retq
933;
934; UNSAFE-LABEL: ugt_inverse_y:
935; UNSAFE:       # BB#0:
936; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
937; UNSAFE-NEXT:    retq
938;
939; FINITE-LABEL: ugt_inverse_y:
940; FINITE:       # BB#0:
941; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
942; FINITE-NEXT:    minsd %xmm0, %xmm1
943; FINITE-NEXT:    movapd %xmm1, %xmm0
944; FINITE-NEXT:    retq
945;
946  %c = fcmp ugt double %x, -0.000000e+00
947  %d = select i1 %c, double -0.000000e+00, double %x
948  ret double %d
949}
950
951define double @ult_inverse_y(double %x)  {
952; STRICT-LABEL: ult_inverse_y:
953; STRICT:       # BB#0:
954; STRICT-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
955; STRICT-NEXT:    movapd %xmm2, %xmm1
956; STRICT-NEXT:    cmpnlesd %xmm0, %xmm1
957; STRICT-NEXT:    andpd %xmm1, %xmm2
958; STRICT-NEXT:    andnpd %xmm0, %xmm1
959; STRICT-NEXT:    orpd %xmm2, %xmm1
960; STRICT-NEXT:    movapd %xmm1, %xmm0
961; STRICT-NEXT:    retq
962;
963; UNSAFE-LABEL: ult_inverse_y:
964; UNSAFE:       # BB#0:
965; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
966; UNSAFE-NEXT:    retq
967;
968; FINITE-LABEL: ult_inverse_y:
969; FINITE:       # BB#0:
970; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
971; FINITE-NEXT:    maxsd %xmm0, %xmm1
972; FINITE-NEXT:    movapd %xmm1, %xmm0
973; FINITE-NEXT:    retq
974;
975  %c = fcmp ult double %x, -0.000000e+00
976  %d = select i1 %c, double -0.000000e+00, double %x
977  ret double %d
978}
979
980define double @uge_y(double %x)  {
981; STRICT-LABEL: uge_y:
982; STRICT:       # BB#0:
983; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
984; STRICT-NEXT:    maxsd %xmm0, %xmm1
985; STRICT-NEXT:    movapd %xmm1, %xmm0
986; STRICT-NEXT:    retq
987;
988; RELAX-LABEL: uge_y:
989; RELAX:       # BB#0:
990; RELAX-NEXT:    maxsd {{.*}}(%rip), %xmm0
991; RELAX-NEXT:    retq
992;
993  %c = fcmp uge double %x, -0.000000e+00
994  %d = select i1 %c, double %x, double -0.000000e+00
995  ret double %d
996}
997
998define double @ule_y(double %x)  {
999; STRICT-LABEL: ule_y:
1000; STRICT:       # BB#0:
1001; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1002; STRICT-NEXT:    minsd %xmm0, %xmm1
1003; STRICT-NEXT:    movapd %xmm1, %xmm0
1004; STRICT-NEXT:    retq
1005;
1006; RELAX-LABEL: ule_y:
1007; RELAX:       # BB#0:
1008; RELAX-NEXT:    minsd {{.*}}(%rip), %xmm0
1009; RELAX-NEXT:    retq
1010;
1011  %c = fcmp ule double %x, -0.000000e+00
1012  %d = select i1 %c, double %x, double -0.000000e+00
1013  ret double %d
1014}
1015
1016define double @uge_inverse_y(double %x)  {
1017; STRICT-LABEL: uge_inverse_y:
1018; STRICT:       # BB#0:
1019; STRICT-NEXT:    minsd {{.*}}(%rip), %xmm0
1020; STRICT-NEXT:    retq
1021;
1022; UNSAFE-LABEL: uge_inverse_y:
1023; UNSAFE:       # BB#0:
1024; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
1025; UNSAFE-NEXT:    retq
1026;
1027; FINITE-LABEL: uge_inverse_y:
1028; FINITE:       # BB#0:
1029; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1030; FINITE-NEXT:    minsd %xmm0, %xmm1
1031; FINITE-NEXT:    movapd %xmm1, %xmm0
1032; FINITE-NEXT:    retq
1033;
1034  %c = fcmp uge double %x, -0.000000e+00
1035  %d = select i1 %c, double -0.000000e+00, double %x
1036  ret double %d
1037}
1038
1039define double @ule_inverse_y(double %x)  {
1040; STRICT-LABEL: ule_inverse_y:
1041; STRICT:       # BB#0:
1042; STRICT-NEXT:    maxsd {{.*}}(%rip), %xmm0
1043; STRICT-NEXT:    retq
1044;
1045; UNSAFE-LABEL: ule_inverse_y:
1046; UNSAFE:       # BB#0:
1047; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
1048; UNSAFE-NEXT:    retq
1049;
1050; FINITE-LABEL: ule_inverse_y:
1051; FINITE:       # BB#0:
1052; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1053; FINITE-NEXT:    maxsd %xmm0, %xmm1
1054; FINITE-NEXT:    movapd %xmm1, %xmm0
1055; FINITE-NEXT:    retq
1056;
1057  %c = fcmp ule double %x, -0.000000e+00
1058  %d = select i1 %c, double -0.000000e+00, double %x
1059  ret double %d
1060}
1061
1062; Test a few more misc. cases.
1063
1064define double @clampTo3k_a(double %x)  {
1065; STRICT-LABEL: clampTo3k_a:
1066; STRICT:       # BB#0:
1067; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1068; STRICT-NEXT:    minsd %xmm0, %xmm1
1069; STRICT-NEXT:    movapd %xmm1, %xmm0
1070; STRICT-NEXT:    retq
1071;
1072; UNSAFE-LABEL: clampTo3k_a:
1073; UNSAFE:       # BB#0:
1074; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
1075; UNSAFE-NEXT:    retq
1076;
1077; FINITE-LABEL: clampTo3k_a:
1078; FINITE:       # BB#0:
1079; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1080; FINITE-NEXT:    minsd %xmm0, %xmm1
1081; FINITE-NEXT:    movapd %xmm1, %xmm0
1082; FINITE-NEXT:    retq
1083;
1084  %t0 = fcmp ogt double %x, 3.000000e+03
1085  %y = select i1 %t0, double 3.000000e+03, double %x
1086  ret double %y
1087}
1088
1089define double @clampTo3k_b(double %x)  {
1090; STRICT-LABEL: clampTo3k_b:
1091; STRICT:       # BB#0:
1092; STRICT-NEXT:    minsd {{.*}}(%rip), %xmm0
1093; STRICT-NEXT:    retq
1094;
1095; UNSAFE-LABEL: clampTo3k_b:
1096; UNSAFE:       # BB#0:
1097; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
1098; UNSAFE-NEXT:    retq
1099;
1100; FINITE-LABEL: clampTo3k_b:
1101; FINITE:       # BB#0:
1102; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1103; FINITE-NEXT:    minsd %xmm0, %xmm1
1104; FINITE-NEXT:    movapd %xmm1, %xmm0
1105; FINITE-NEXT:    retq
1106;
1107  %t0 = fcmp uge double %x, 3.000000e+03
1108  %y = select i1 %t0, double 3.000000e+03, double %x
1109  ret double %y
1110}
1111
1112define double @clampTo3k_c(double %x)  {
1113; STRICT-LABEL: clampTo3k_c:
1114; STRICT:       # BB#0:
1115; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1116; STRICT-NEXT:    maxsd %xmm0, %xmm1
1117; STRICT-NEXT:    movapd %xmm1, %xmm0
1118; STRICT-NEXT:    retq
1119;
1120; UNSAFE-LABEL: clampTo3k_c:
1121; UNSAFE:       # BB#0:
1122; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
1123; UNSAFE-NEXT:    retq
1124;
1125; FINITE-LABEL: clampTo3k_c:
1126; FINITE:       # BB#0:
1127; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1128; FINITE-NEXT:    maxsd %xmm0, %xmm1
1129; FINITE-NEXT:    movapd %xmm1, %xmm0
1130; FINITE-NEXT:    retq
1131;
1132  %t0 = fcmp olt double %x, 3.000000e+03
1133  %y = select i1 %t0, double 3.000000e+03, double %x
1134  ret double %y
1135}
1136
1137define double @clampTo3k_d(double %x)  {
1138; STRICT-LABEL: clampTo3k_d:
1139; STRICT:       # BB#0:
1140; STRICT-NEXT:    maxsd {{.*}}(%rip), %xmm0
1141; STRICT-NEXT:    retq
1142;
1143; UNSAFE-LABEL: clampTo3k_d:
1144; UNSAFE:       # BB#0:
1145; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
1146; UNSAFE-NEXT:    retq
1147;
1148; FINITE-LABEL: clampTo3k_d:
1149; FINITE:       # BB#0:
1150; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1151; FINITE-NEXT:    maxsd %xmm0, %xmm1
1152; FINITE-NEXT:    movapd %xmm1, %xmm0
1153; FINITE-NEXT:    retq
1154;
1155  %t0 = fcmp ule double %x, 3.000000e+03
1156  %y = select i1 %t0, double 3.000000e+03, double %x
1157  ret double %y
1158}
1159
1160define double @clampTo3k_e(double %x)  {
1161; STRICT-LABEL: clampTo3k_e:
1162; STRICT:       # BB#0:
1163; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1164; STRICT-NEXT:    maxsd %xmm0, %xmm1
1165; STRICT-NEXT:    movapd %xmm1, %xmm0
1166; STRICT-NEXT:    retq
1167;
1168; UNSAFE-LABEL: clampTo3k_e:
1169; UNSAFE:       # BB#0:
1170; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
1171; UNSAFE-NEXT:    retq
1172;
1173; FINITE-LABEL: clampTo3k_e:
1174; FINITE:       # BB#0:
1175; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1176; FINITE-NEXT:    maxsd %xmm0, %xmm1
1177; FINITE-NEXT:    movapd %xmm1, %xmm0
1178; FINITE-NEXT:    retq
1179;
1180  %t0 = fcmp olt double %x, 3.000000e+03
1181  %y = select i1 %t0, double 3.000000e+03, double %x
1182  ret double %y
1183}
1184
1185define double @clampTo3k_f(double %x)  {
1186; STRICT-LABEL: clampTo3k_f:
1187; STRICT:       # BB#0:
1188; STRICT-NEXT:    maxsd {{.*}}(%rip), %xmm0
1189; STRICT-NEXT:    retq
1190;
1191; UNSAFE-LABEL: clampTo3k_f:
1192; UNSAFE:       # BB#0:
1193; UNSAFE-NEXT:    maxsd {{.*}}(%rip), %xmm0
1194; UNSAFE-NEXT:    retq
1195;
1196; FINITE-LABEL: clampTo3k_f:
1197; FINITE:       # BB#0:
1198; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1199; FINITE-NEXT:    maxsd %xmm0, %xmm1
1200; FINITE-NEXT:    movapd %xmm1, %xmm0
1201; FINITE-NEXT:    retq
1202;
1203  %t0 = fcmp ule double %x, 3.000000e+03
1204  %y = select i1 %t0, double 3.000000e+03, double %x
1205  ret double %y
1206}
1207
1208define double @clampTo3k_g(double %x)  {
1209; STRICT-LABEL: clampTo3k_g:
1210; STRICT:       # BB#0:
1211; STRICT-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1212; STRICT-NEXT:    minsd %xmm0, %xmm1
1213; STRICT-NEXT:    movapd %xmm1, %xmm0
1214; STRICT-NEXT:    retq
1215;
1216; UNSAFE-LABEL: clampTo3k_g:
1217; UNSAFE:       # BB#0:
1218; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
1219; UNSAFE-NEXT:    retq
1220;
1221; FINITE-LABEL: clampTo3k_g:
1222; FINITE:       # BB#0:
1223; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1224; FINITE-NEXT:    minsd %xmm0, %xmm1
1225; FINITE-NEXT:    movapd %xmm1, %xmm0
1226; FINITE-NEXT:    retq
1227;
1228  %t0 = fcmp ogt double %x, 3.000000e+03
1229  %y = select i1 %t0, double 3.000000e+03, double %x
1230  ret double %y
1231}
1232
1233define double @clampTo3k_h(double %x)  {
1234; STRICT-LABEL: clampTo3k_h:
1235; STRICT:       # BB#0:
1236; STRICT-NEXT:    minsd {{.*}}(%rip), %xmm0
1237; STRICT-NEXT:    retq
1238;
1239; UNSAFE-LABEL: clampTo3k_h:
1240; UNSAFE:       # BB#0:
1241; UNSAFE-NEXT:    minsd {{.*}}(%rip), %xmm0
1242; UNSAFE-NEXT:    retq
1243;
1244; FINITE-LABEL: clampTo3k_h:
1245; FINITE:       # BB#0:
1246; FINITE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
1247; FINITE-NEXT:    minsd %xmm0, %xmm1
1248; FINITE-NEXT:    movapd %xmm1, %xmm0
1249; FINITE-NEXT:    retq
1250;
1251  %t0 = fcmp uge double %x, 3.000000e+03
1252  %y = select i1 %t0, double 3.000000e+03, double %x
1253  ret double %y
1254}
1255
1256define <2 x double> @test_maxpd(<2 x double> %x, <2 x double> %y)  {
1257; STRICT-LABEL: test_maxpd:
1258; STRICT:       # BB#0:
1259; STRICT-NEXT:    movapd %xmm0, %xmm2
1260; STRICT-NEXT:    movapd %xmm1, %xmm0
1261; STRICT-NEXT:    cmplepd %xmm2, %xmm0
1262; STRICT-NEXT:    blendvpd %xmm2, %xmm1
1263; STRICT-NEXT:    movapd %xmm1, %xmm0
1264; STRICT-NEXT:    retq
1265;
1266; RELAX-LABEL: test_maxpd:
1267; RELAX:       # BB#0:
1268; RELAX-NEXT:    maxpd %xmm1, %xmm0
1269; RELAX-NEXT:    retq
1270;
1271  %max_is_x = fcmp oge <2 x double> %x, %y
1272  %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y
1273  ret <2 x double> %max
1274}
1275
1276define <2 x double> @test_minpd(<2 x double> %x, <2 x double> %y)  {
1277; STRICT-LABEL: test_minpd:
1278; STRICT:       # BB#0:
1279; STRICT-NEXT:    movapd %xmm0, %xmm2
1280; STRICT-NEXT:    cmplepd %xmm1, %xmm0
1281; STRICT-NEXT:    blendvpd %xmm2, %xmm1
1282; STRICT-NEXT:    movapd %xmm1, %xmm0
1283; STRICT-NEXT:    retq
1284;
1285; RELAX-LABEL: test_minpd:
1286; RELAX:       # BB#0:
1287; RELAX-NEXT:    minpd %xmm1, %xmm0
1288; RELAX-NEXT:    retq
1289;
1290  %min_is_x = fcmp ole <2 x double> %x, %y
1291  %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y
1292  ret <2 x double> %min
1293}
1294
1295define <4 x float> @test_maxps(<4 x float> %x, <4 x float> %y)  {
1296; STRICT-LABEL: test_maxps:
1297; STRICT:       # BB#0:
1298; STRICT-NEXT:    movaps %xmm0, %xmm2
1299; STRICT-NEXT:    movaps %xmm1, %xmm0
1300; STRICT-NEXT:    cmpleps %xmm2, %xmm0
1301; STRICT-NEXT:    blendvps %xmm2, %xmm1
1302; STRICT-NEXT:    movaps %xmm1, %xmm0
1303; STRICT-NEXT:    retq
1304;
1305; RELAX-LABEL: test_maxps:
1306; RELAX:       # BB#0:
1307; RELAX-NEXT:    maxps %xmm1, %xmm0
1308; RELAX-NEXT:    retq
1309;
1310  %max_is_x = fcmp oge <4 x float> %x, %y
1311  %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y
1312  ret <4 x float> %max
1313}
1314
1315define <4 x float> @test_minps(<4 x float> %x, <4 x float> %y)  {
1316; STRICT-LABEL: test_minps:
1317; STRICT:       # BB#0:
1318; STRICT-NEXT:    movaps %xmm0, %xmm2
1319; STRICT-NEXT:    cmpleps %xmm1, %xmm0
1320; STRICT-NEXT:    blendvps %xmm2, %xmm1
1321; STRICT-NEXT:    movaps %xmm1, %xmm0
1322; STRICT-NEXT:    retq
1323;
1324; RELAX-LABEL: test_minps:
1325; RELAX:       # BB#0:
1326; RELAX-NEXT:    minps %xmm1, %xmm0
1327; RELAX-NEXT:    retq
1328;
1329  %min_is_x = fcmp ole <4 x float> %x, %y
1330  %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y
1331  ret <4 x float> %min
1332}
1333
1334define <2 x float> @test_maxps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
1335; STRICT-LABEL: test_maxps_illegal_v2f32:
1336; STRICT:       # BB#0:
1337; STRICT-NEXT:    movaps %xmm0, %xmm2
1338; STRICT-NEXT:    movaps %xmm1, %xmm0
1339; STRICT-NEXT:    cmpleps %xmm2, %xmm0
1340; STRICT-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],zero,xmm0[1]
1341; STRICT-NEXT:    pslld $31, %xmm0
1342; STRICT-NEXT:    blendvps %xmm2, %xmm1
1343; STRICT-NEXT:    movaps %xmm1, %xmm0
1344; STRICT-NEXT:    retq
1345;
1346; RELAX-LABEL: test_maxps_illegal_v2f32:
1347; RELAX:       # BB#0:
1348; RELAX-NEXT:    maxps %xmm1, %xmm0
1349; RELAX-NEXT:    retq
1350;
1351  %max_is_x = fcmp oge <2 x float> %x, %y
1352  %max = select <2 x i1> %max_is_x, <2 x float> %x, <2 x float> %y
1353  ret <2 x float> %max
1354}
1355
1356define <2 x float> @test_minps_illegal_v2f32(<2 x float> %x, <2 x float> %y)  {
1357; STRICT-LABEL: test_minps_illegal_v2f32:
1358; STRICT:       # BB#0:
1359; STRICT-NEXT:    movaps %xmm0, %xmm2
1360; STRICT-NEXT:    cmpleps %xmm1, %xmm0
1361; STRICT-NEXT:    insertps {{.*#+}} xmm0 = xmm0[0,1],zero,xmm0[1]
1362; STRICT-NEXT:    pslld $31, %xmm0
1363; STRICT-NEXT:    blendvps %xmm2, %xmm1
1364; STRICT-NEXT:    movaps %xmm1, %xmm0
1365; STRICT-NEXT:    retq
1366;
1367; RELAX-LABEL: test_minps_illegal_v2f32:
1368; RELAX:       # BB#0:
1369; RELAX-NEXT:    minps %xmm1, %xmm0
1370; RELAX-NEXT:    retq
1371;
1372  %min_is_x = fcmp ole <2 x float> %x, %y
1373  %min = select <2 x i1> %min_is_x, <2 x float> %x, <2 x float> %y
1374  ret <2 x float> %min
1375}
1376
1377define <3 x float> @test_maxps_illegal_v3f32(<3 x float> %x, <3 x float> %y)  {
1378; STRICT-LABEL: test_maxps_illegal_v3f32:
1379; STRICT:       # BB#0:
1380; STRICT-NEXT:    movaps %xmm0, %xmm2
1381; STRICT-NEXT:    movaps %xmm1, %xmm0
1382; STRICT-NEXT:    cmpleps %xmm2, %xmm0
1383; STRICT-NEXT:    blendvps %xmm2, %xmm1
1384; STRICT-NEXT:    movaps %xmm1, %xmm0
1385; STRICT-NEXT:    retq
1386;
1387; RELAX-LABEL: test_maxps_illegal_v3f32:
1388; RELAX:       # BB#0:
1389; RELAX-NEXT:    maxps %xmm1, %xmm0
1390; RELAX-NEXT:    retq
1391;
1392  %max_is_x = fcmp oge <3 x float> %x, %y
1393  %max = select <3 x i1> %max_is_x, <3 x float> %x, <3 x float> %y
1394  ret <3 x float> %max
1395}
1396
1397define <3 x float> @test_minps_illegal_v3f32(<3 x float> %x, <3 x float> %y)  {
1398; STRICT-LABEL: test_minps_illegal_v3f32:
1399; STRICT:       # BB#0:
1400; STRICT-NEXT:    movaps %xmm0, %xmm2
1401; STRICT-NEXT:    cmpleps %xmm1, %xmm0
1402; STRICT-NEXT:    blendvps %xmm2, %xmm1
1403; STRICT-NEXT:    movaps %xmm1, %xmm0
1404; STRICT-NEXT:    retq
1405;
1406; RELAX-LABEL: test_minps_illegal_v3f32:
1407; RELAX:       # BB#0:
1408; RELAX-NEXT:    minps %xmm1, %xmm0
1409; RELAX-NEXT:    retq
1410;
1411  %min_is_x = fcmp ole <3 x float> %x, %y
1412  %min = select <3 x i1> %min_is_x, <3 x float> %x, <3 x float> %y
1413  ret <3 x float> %min
1414}
1415
1416