blob: 17ffb5e464aa0715a4997b5e874ab4e007fa4ecd [file] [log] [blame]
Dan Gohman19488552009-09-21 18:03:22 +00001; RUN: llc < %s -march=x86-64 -asm-verbose=false | FileCheck %s
2
3; Some of these patterns can be matched as SSE min or max. Some of
4; then can be matched provided that the operands are swapped.
5; Some of them can't be matched at all and require a comparison
6; and a conditional branch.
7
8; The naming convention is {,x_}{o,u}{gt,lt,ge,le}{,_inverse}
9; x_ : use 0.0 instead of %y
10; _inverse : swap the arms of the select.
11
12; CHECK: ogt:
13; CHECK-NEXT: maxsd %xmm1, %xmm0
14; CHECK-NEXT: ret
15define double @ogt(double %x, double %y) nounwind {
16 %c = fcmp ogt double %x, %y
17 %d = select i1 %c, double %x, double %y
18 ret double %d
19}
20
21; CHECK: olt:
22; CHECK-NEXT: minsd %xmm1, %xmm0
23; CHECK-NEXT: ret
24define double @olt(double %x, double %y) nounwind {
25 %c = fcmp olt double %x, %y
26 %d = select i1 %c, double %x, double %y
27 ret double %d
28}
29
30; CHECK: ogt_inverse:
31; CHECK-NEXT: minsd %xmm0, %xmm1
32; CHECK-NEXT: movapd %xmm1, %xmm0
33; CHECK-NEXT: ret
34define double @ogt_inverse(double %x, double %y) nounwind {
35 %c = fcmp ogt double %x, %y
36 %d = select i1 %c, double %y, double %x
37 ret double %d
38}
39
40; CHECK: olt_inverse:
41; CHECK-NEXT: maxsd %xmm0, %xmm1
42; CHECK-NEXT: movapd %xmm1, %xmm0
43; CHECK-NEXT: ret
44define double @olt_inverse(double %x, double %y) nounwind {
45 %c = fcmp olt double %x, %y
46 %d = select i1 %c, double %y, double %x
47 ret double %d
48}
49
50; CHECK: oge:
51; CHECK-NEXT: ucomisd %xmm1, %xmm0
52define double @oge(double %x, double %y) nounwind {
53 %c = fcmp oge double %x, %y
54 %d = select i1 %c, double %x, double %y
55 ret double %d
56}
57
58; CHECK: ole:
59; CHECK-NEXT: ucomisd %xmm0, %xmm1
60define double @ole(double %x, double %y) nounwind {
61 %c = fcmp ole double %x, %y
62 %d = select i1 %c, double %x, double %y
63 ret double %d
64}
65
66; CHECK: oge_inverse:
67; CHECK-NEXT: ucomisd %xmm1, %xmm0
68define double @oge_inverse(double %x, double %y) nounwind {
69 %c = fcmp oge double %x, %y
70 %d = select i1 %c, double %y, double %x
71 ret double %d
72}
73
74; CHECK: ole_inverse:
75; CHECK-NEXT: ucomisd %xmm0, %xmm1
76define double @ole_inverse(double %x, double %y) nounwind {
77 %c = fcmp ole double %x, %y
78 %d = select i1 %c, double %y, double %x
79 ret double %d
80}
81
82; CHECK: x_ogt:
83; CHECK-NEXT: pxor %xmm1, %xmm1
84; CHECK-NEXT: maxsd %xmm1, %xmm0
85; CHECK-NEXT: ret
86define double @x_ogt(double %x) nounwind {
87 %c = fcmp ogt double %x, 0.000000e+00
88 %d = select i1 %c, double %x, double 0.000000e+00
89 ret double %d
90}
91
92; CHECK: x_olt:
93; CHECK-NEXT: pxor %xmm1, %xmm1
94; CHECK-NEXT: minsd %xmm1, %xmm0
95; CHECK-NEXT: ret
96define double @x_olt(double %x) nounwind {
97 %c = fcmp olt double %x, 0.000000e+00
98 %d = select i1 %c, double %x, double 0.000000e+00
99 ret double %d
100}
101
102; CHECK: x_ogt_inverse:
103; CHECK-NEXT: pxor %xmm1, %xmm1
104; CHECK-NEXT: minsd %xmm0, %xmm1
105; CHECK-NEXT: movapd %xmm1, %xmm0
106; CHECK-NEXT: ret
107define double @x_ogt_inverse(double %x) nounwind {
108 %c = fcmp ogt double %x, 0.000000e+00
109 %d = select i1 %c, double 0.000000e+00, double %x
110 ret double %d
111}
112
113; CHECK: x_olt_inverse:
114; CHECK-NEXT: pxor %xmm1, %xmm1
115; CHECK-NEXT: maxsd %xmm0, %xmm1
116; CHECK-NEXT: movapd %xmm1, %xmm0
117; CHECK-NEXT: ret
118define double @x_olt_inverse(double %x) nounwind {
119 %c = fcmp olt double %x, 0.000000e+00
120 %d = select i1 %c, double 0.000000e+00, double %x
121 ret double %d
122}
123
124; CHECK: x_oge:
125; CHECK-NEXT: pxor %xmm1, %xmm1
126; CHECK-NEXT: maxsd %xmm1, %xmm0
127; CHECK-NEXT: ret
128define double @x_oge(double %x) nounwind {
129 %c = fcmp oge double %x, 0.000000e+00
130 %d = select i1 %c, double %x, double 0.000000e+00
131 ret double %d
132}
133
134; CHECK: x_ole:
135; CHECK-NEXT: pxor %xmm1, %xmm1
136; CHECK-NEXT: minsd %xmm1, %xmm0
137; CHECK-NEXT: ret
138define double @x_ole(double %x) nounwind {
139 %c = fcmp ole double %x, 0.000000e+00
140 %d = select i1 %c, double %x, double 0.000000e+00
141 ret double %d
142}
143
144; CHECK: x_oge_inverse:
145; CHECK-NEXT: pxor %xmm1, %xmm1
146; CHECK-NEXT: minsd %xmm0, %xmm1
147; CHECK-NEXT: movapd %xmm1, %xmm0
148; CHECK-NEXT: ret
149define double @x_oge_inverse(double %x) nounwind {
150 %c = fcmp oge double %x, 0.000000e+00
151 %d = select i1 %c, double 0.000000e+00, double %x
152 ret double %d
153}
154
155; CHECK: x_ole_inverse:
156; CHECK-NEXT: pxor %xmm1, %xmm1
157; CHECK-NEXT: maxsd %xmm0, %xmm1
158; CHECK-NEXT: movapd %xmm1, %xmm0
159; CHECK-NEXT: ret
160define double @x_ole_inverse(double %x) nounwind {
161 %c = fcmp ole double %x, 0.000000e+00
162 %d = select i1 %c, double 0.000000e+00, double %x
163 ret double %d
164}
165
166; CHECK: ugt:
167; CHECK-NEXT: ucomisd %xmm0, %xmm1
168define double @ugt(double %x, double %y) nounwind {
169 %c = fcmp ugt double %x, %y
170 %d = select i1 %c, double %x, double %y
171 ret double %d
172}
173
174; CHECK: ult:
175; CHECK-NEXT: ucomisd %xmm1, %xmm0
176define double @ult(double %x, double %y) nounwind {
177 %c = fcmp ult double %x, %y
178 %d = select i1 %c, double %x, double %y
179 ret double %d
180}
181
182; CHECK: ugt_inverse:
183; CHECK-NEXT: ucomisd %xmm0, %xmm1
184define double @ugt_inverse(double %x, double %y) nounwind {
185 %c = fcmp ugt double %x, %y
186 %d = select i1 %c, double %y, double %x
187 ret double %d
188}
189
190; CHECK: ult_inverse:
191; CHECK-NEXT: ucomisd %xmm1, %xmm0
192define double @ult_inverse(double %x, double %y) nounwind {
193 %c = fcmp ult double %x, %y
194 %d = select i1 %c, double %y, double %x
195 ret double %d
196}
197
198; CHECK: uge:
199; CHECK-NEXT: maxsd %xmm0, %xmm1
200; CHECK-NEXT: movapd %xmm1, %xmm0
201; CHECK-NEXT: ret
202define double @uge(double %x, double %y) nounwind {
203 %c = fcmp uge double %x, %y
204 %d = select i1 %c, double %x, double %y
205 ret double %d
206}
207
208; CHECK: ule:
209; CHECK-NEXT: minsd %xmm0, %xmm1
210; CHECK-NEXT: movapd %xmm1, %xmm0
211; CHECK-NEXT: ret
212define double @ule(double %x, double %y) nounwind {
213 %c = fcmp ule double %x, %y
214 %d = select i1 %c, double %x, double %y
215 ret double %d
216}
217
218; CHECK: uge_inverse:
219; CHECK-NEXT: minsd %xmm1, %xmm0
220; CHECK-NEXT: ret
221define double @uge_inverse(double %x, double %y) nounwind {
222 %c = fcmp uge double %x, %y
223 %d = select i1 %c, double %y, double %x
224 ret double %d
225}
226
227; CHECK: ule_inverse:
228; CHECK-NEXT: maxsd %xmm1, %xmm0
229; CHECK-NEXT: ret
230define double @ule_inverse(double %x, double %y) nounwind {
231 %c = fcmp ule double %x, %y
232 %d = select i1 %c, double %y, double %x
233 ret double %d
234}
235
236; CHECK: x_ugt:
237; CHECK-NEXT: pxor %xmm1, %xmm1
238; CHECK-NEXT: maxsd %xmm0, %xmm1
239; CHECK-NEXT: movapd %xmm1, %xmm0
240; CHECK-NEXT: ret
241define double @x_ugt(double %x) nounwind {
242 %c = fcmp ugt double %x, 0.000000e+00
243 %d = select i1 %c, double %x, double 0.000000e+00
244 ret double %d
245}
246
247; CHECK: x_ult:
248; CHECK-NEXT: pxor %xmm1, %xmm1
249; CHECK-NEXT: minsd %xmm0, %xmm1
250; CHECK-NEXT: movapd %xmm1, %xmm0
251; CHECK-NEXT: ret
252define double @x_ult(double %x) nounwind {
253 %c = fcmp ult double %x, 0.000000e+00
254 %d = select i1 %c, double %x, double 0.000000e+00
255 ret double %d
256}
257
258; CHECK: x_ugt_inverse:
259; CHECK-NEXT: pxor %xmm1, %xmm1
260; CHECK-NEXT: minsd %xmm1, %xmm0
261; CHECK-NEXT: ret
262define double @x_ugt_inverse(double %x) nounwind {
263 %c = fcmp ugt double %x, 0.000000e+00
264 %d = select i1 %c, double 0.000000e+00, double %x
265 ret double %d
266}
267
268; CHECK: x_ult_inverse:
269; CHECK-NEXT: pxor %xmm1, %xmm1
270; CHECK-NEXT: maxsd %xmm1, %xmm0
271; CHECK-NEXT: ret
272define double @x_ult_inverse(double %x) nounwind {
273 %c = fcmp ult double %x, 0.000000e+00
274 %d = select i1 %c, double 0.000000e+00, double %x
275 ret double %d
276}
277
278; CHECK: x_uge:
279; CHECK-NEXT: pxor %xmm1, %xmm1
280; CHECK-NEXT: maxsd %xmm0, %xmm1
281; CHECK-NEXT: movapd %xmm1, %xmm0
282; CHECK-NEXT: ret
283define double @x_uge(double %x) nounwind {
284 %c = fcmp uge double %x, 0.000000e+00
285 %d = select i1 %c, double %x, double 0.000000e+00
286 ret double %d
287}
288
289; CHECK: x_ule:
290; CHECK-NEXT: pxor %xmm1, %xmm1
291; CHECK-NEXT: minsd %xmm0, %xmm1
292; CHECK-NEXT: movapd %xmm1, %xmm0
293; CHECK-NEXT: ret
294define double @x_ule(double %x) nounwind {
295 %c = fcmp ule double %x, 0.000000e+00
296 %d = select i1 %c, double %x, double 0.000000e+00
297 ret double %d
298}
299
300; CHECK: x_uge_inverse:
301; CHECK-NEXT: pxor %xmm1, %xmm1
302; CHECK-NEXT: minsd %xmm1, %xmm0
303; CHECK-NEXT: ret
304define double @x_uge_inverse(double %x) nounwind {
305 %c = fcmp uge double %x, 0.000000e+00
306 %d = select i1 %c, double 0.000000e+00, double %x
307 ret double %d
308}
309
310; CHECK: x_ule_inverse:
311; CHECK-NEXT: pxor %xmm1, %xmm1
312; CHECK-NEXT: maxsd %xmm1, %xmm0
313; CHECK-NEXT: ret
314define double @x_ule_inverse(double %x) nounwind {
315 %c = fcmp ule double %x, 0.000000e+00
316 %d = select i1 %c, double 0.000000e+00, double %x
317 ret double %d
318}
319
320; Test a few more misc. cases.
Dan Gohman41b3f4a2009-09-03 20:34:31 +0000321
322; CHECK: clampTo3k_a:
323; CHECK: minsd
324define double @clampTo3k_a(double %x) nounwind readnone {
325entry:
326 %0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1]
327 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
328 ret double %x_addr.0
329}
330
331; CHECK: clampTo3k_b:
332; CHECK: minsd
333define double @clampTo3k_b(double %x) nounwind readnone {
334entry:
335 %0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1]
336 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
337 ret double %x_addr.0
338}
339
340; CHECK: clampTo3k_c:
341; CHECK: maxsd
342define double @clampTo3k_c(double %x) nounwind readnone {
343entry:
344 %0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1]
345 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
346 ret double %x_addr.0
347}
348
349; CHECK: clampTo3k_d:
350; CHECK: maxsd
351define double @clampTo3k_d(double %x) nounwind readnone {
352entry:
353 %0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1]
354 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
355 ret double %x_addr.0
356}
357
358; CHECK: clampTo3k_e:
359; CHECK: maxsd
360define double @clampTo3k_e(double %x) nounwind readnone {
361entry:
362 %0 = fcmp olt double %x, 3.000000e+03 ; <i1> [#uses=1]
363 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
364 ret double %x_addr.0
365}
366
367; CHECK: clampTo3k_f:
368; CHECK: maxsd
369define double @clampTo3k_f(double %x) nounwind readnone {
370entry:
371 %0 = fcmp ule double %x, 3.000000e+03 ; <i1> [#uses=1]
372 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
373 ret double %x_addr.0
374}
375
376; CHECK: clampTo3k_g:
377; CHECK: minsd
378define double @clampTo3k_g(double %x) nounwind readnone {
379entry:
380 %0 = fcmp ogt double %x, 3.000000e+03 ; <i1> [#uses=1]
381 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
382 ret double %x_addr.0
383}
384
385; CHECK: clampTo3k_h:
386; CHECK: minsd
387define double @clampTo3k_h(double %x) nounwind readnone {
388entry:
389 %0 = fcmp uge double %x, 3.000000e+03 ; <i1> [#uses=1]
390 %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1]
391 ret double %x_addr.0
392}