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