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