1; RUN: llc -march=amdgcn < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
2; RUN: llc -march=r600 -mcpu=cypress < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
3
4declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
5
6; FUNC-LABEL: {{^}}v_test_imin_sle_i32:
7; SI: v_min_i32_e32
8
9; EG: MIN_INT
10define void @v_test_imin_sle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
11  %a = load i32, i32 addrspace(1)* %aptr, align 4
12  %b = load i32, i32 addrspace(1)* %bptr, align 4
13  %cmp = icmp sle i32 %a, %b
14  %val = select i1 %cmp, i32 %a, i32 %b
15  store i32 %val, i32 addrspace(1)* %out, align 4
16  ret void
17}
18
19; FUNC-LABEL: {{^}}s_test_imin_sle_i32:
20; SI: s_min_i32
21
22; EG: MIN_INT
23define void @s_test_imin_sle_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
24  %cmp = icmp sle i32 %a, %b
25  %val = select i1 %cmp, i32 %a, i32 %b
26  store i32 %val, i32 addrspace(1)* %out, align 4
27  ret void
28}
29
30; FUNC-LABEL: {{^}}s_test_imin_sle_v1i32:
31; SI: s_min_i32
32
33; EG: MIN_INT
34define void @s_test_imin_sle_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
35  %cmp = icmp sle <1 x i32> %a, %b
36  %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
37  store <1 x i32> %val, <1 x i32> addrspace(1)* %out
38  ret void
39}
40
41; FUNC-LABEL: {{^}}s_test_imin_sle_v4i32:
42; SI: s_min_i32
43; SI: s_min_i32
44; SI: s_min_i32
45; SI: s_min_i32
46
47; EG: MIN_INT
48; EG: MIN_INT
49; EG: MIN_INT
50; EG: MIN_INT
51define void @s_test_imin_sle_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) nounwind {
52  %cmp = icmp sle <4 x i32> %a, %b
53  %val = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> %b
54  store <4 x i32> %val, <4 x i32> addrspace(1)* %out
55  ret void
56}
57
58; FUNC-LABEL: {{^}}s_test_imin_sle_i8:
59; SI: s_load_dword
60; SI: s_load_dword
61; SI: s_sext_i32_i8
62; SI: s_sext_i32_i8
63; SI: s_min_i32
64define void @s_test_imin_sle_i8(i8 addrspace(1)* %out, i8 %a, i8 %b) nounwind {
65  %cmp = icmp sle i8 %a, %b
66  %val = select i1 %cmp, i8 %a, i8 %b
67  store i8 %val, i8 addrspace(1)* %out
68  ret void
69}
70
71; XXX - should be able to use s_min if we stop unnecessarily doing
72; extloads with mubuf instructions.
73
74; FUNC-LABEL: {{^}}s_test_imin_sle_v4i8:
75; SI: buffer_load_sbyte
76; SI: buffer_load_sbyte
77; SI: buffer_load_sbyte
78; SI: buffer_load_sbyte
79; SI: buffer_load_sbyte
80; SI: buffer_load_sbyte
81; SI: buffer_load_sbyte
82; SI: buffer_load_sbyte
83
84; SI: v_min_i32
85; SI: v_min_i32
86; SI: v_min_i32
87; SI: v_min_i32
88
89; SI: s_endpgm
90
91; EG: MIN_INT
92; EG: MIN_INT
93; EG: MIN_INT
94; EG: MIN_INT
95define void @s_test_imin_sle_v4i8(<4 x i8> addrspace(1)* %out, <4 x i8> %a, <4 x i8> %b) nounwind {
96  %cmp = icmp sle <4 x i8> %a, %b
97  %val = select <4 x i1> %cmp, <4 x i8> %a, <4 x i8> %b
98  store <4 x i8> %val, <4 x i8> addrspace(1)* %out
99  ret void
100}
101
102; FUNC-LABEL: {{^}}s_test_imin_sle_v4i16:
103; SI: v_min_i32
104; SI: v_min_i32
105; SI: v_min_i32
106; SI: v_min_i32
107
108; EG: MIN_INT
109; EG: MIN_INT
110; EG: MIN_INT
111; EG: MIN_INT
112define void @s_test_imin_sle_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %a, <4 x i16> %b) nounwind {
113  %cmp = icmp sle <4 x i16> %a, %b
114  %val = select <4 x i1> %cmp, <4 x i16> %a, <4 x i16> %b
115  store <4 x i16> %val, <4 x i16> addrspace(1)* %out
116  ret void
117}
118
119; FUNC-LABEL: @v_test_imin_slt_i32
120; SI: v_min_i32_e32
121
122; EG: MIN_INT
123define void @v_test_imin_slt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
124  %a = load i32, i32 addrspace(1)* %aptr, align 4
125  %b = load i32, i32 addrspace(1)* %bptr, align 4
126  %cmp = icmp slt i32 %a, %b
127  %val = select i1 %cmp, i32 %a, i32 %b
128  store i32 %val, i32 addrspace(1)* %out, align 4
129  ret void
130}
131
132; FUNC-LABEL: @s_test_imin_slt_i32
133; SI: s_min_i32
134
135; EG: MIN_INT
136define void @s_test_imin_slt_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
137  %cmp = icmp slt i32 %a, %b
138  %val = select i1 %cmp, i32 %a, i32 %b
139  store i32 %val, i32 addrspace(1)* %out, align 4
140  ret void
141}
142
143; FUNC-LABEL: {{^}}s_test_imin_slt_v2i32:
144; SI: s_min_i32
145; SI: s_min_i32
146
147; EG: MIN_INT
148; EG: MIN_INT
149define void @s_test_imin_slt_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) nounwind {
150  %cmp = icmp slt <2 x i32> %a, %b
151  %val = select <2 x i1> %cmp, <2 x i32> %a, <2 x i32> %b
152  store <2 x i32> %val, <2 x i32> addrspace(1)* %out
153  ret void
154}
155
156; FUNC-LABEL: {{^}}s_test_imin_slt_imm_i32:
157; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
158
159; EG: MIN_INT {{.*}}literal.{{[xyzw]}}
160define void @s_test_imin_slt_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
161  %cmp = icmp slt i32 %a, 8
162  %val = select i1 %cmp, i32 %a, i32 8
163  store i32 %val, i32 addrspace(1)* %out, align 4
164  ret void
165}
166
167; FUNC-LABEL: {{^}}s_test_imin_sle_imm_i32:
168; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
169
170; EG: MIN_INT {{.*}}literal.{{[xyzw]}}
171define void @s_test_imin_sle_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
172  %cmp = icmp sle i32 %a, 8
173  %val = select i1 %cmp, i32 %a, i32 8
174  store i32 %val, i32 addrspace(1)* %out, align 4
175  ret void
176}
177
178; FUNC-LABEL: @v_test_umin_ule_i32
179; SI: v_min_u32_e32
180
181; EG: MIN_UINT
182define void @v_test_umin_ule_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
183  %a = load i32, i32 addrspace(1)* %aptr, align 4
184  %b = load i32, i32 addrspace(1)* %bptr, align 4
185  %cmp = icmp ule i32 %a, %b
186  %val = select i1 %cmp, i32 %a, i32 %b
187  store i32 %val, i32 addrspace(1)* %out, align 4
188  ret void
189}
190
191; FUNC-LABEL: @v_test_umin_ule_v3i32
192; SI: v_min_u32_e32
193; SI: v_min_u32_e32
194; SI: v_min_u32_e32
195; SI-NOT: v_min_u32_e32
196; SI: s_endpgm
197
198; EG: MIN_UINT
199; EG: MIN_UINT
200; EG: MIN_UINT
201define void @v_test_umin_ule_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %aptr, <3 x i32> addrspace(1)* %bptr) nounwind {
202  %a = load <3 x i32>, <3 x i32> addrspace(1)* %aptr
203  %b = load <3 x i32>, <3 x i32> addrspace(1)* %bptr
204  %cmp = icmp ule <3 x i32> %a, %b
205  %val = select <3 x i1> %cmp, <3 x i32> %a, <3 x i32> %b
206  store <3 x i32> %val, <3 x i32> addrspace(1)* %out
207  ret void
208}
209; FUNC-LABEL: @s_test_umin_ule_i32
210; SI: s_min_u32
211
212; EG: MIN_UINT
213define void @s_test_umin_ule_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
214  %cmp = icmp ule i32 %a, %b
215  %val = select i1 %cmp, i32 %a, i32 %b
216  store i32 %val, i32 addrspace(1)* %out, align 4
217  ret void
218}
219
220; FUNC-LABEL: @v_test_umin_ult_i32
221; SI: v_min_u32_e32
222
223; EG: MIN_UINT
224define void @v_test_umin_ult_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
225  %a = load i32, i32 addrspace(1)* %aptr, align 4
226  %b = load i32, i32 addrspace(1)* %bptr, align 4
227  %cmp = icmp ult i32 %a, %b
228  %val = select i1 %cmp, i32 %a, i32 %b
229  store i32 %val, i32 addrspace(1)* %out, align 4
230  ret void
231}
232
233; FUNC-LABEL: {{^}}v_test_umin_ult_i8:
234; SI: buffer_load_ubyte
235; SI: buffer_load_ubyte
236; SI: v_min_u32_e32
237
238; EG: MIN_UINT
239define void @v_test_umin_ult_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %aptr, i8 addrspace(1)* %bptr) nounwind {
240  %a = load i8, i8 addrspace(1)* %aptr, align 1
241  %b = load i8, i8 addrspace(1)* %bptr, align 1
242  %cmp = icmp ult i8 %a, %b
243  %val = select i1 %cmp, i8 %a, i8 %b
244  store i8 %val, i8 addrspace(1)* %out, align 1
245  ret void
246}
247
248; FUNC-LABEL: @s_test_umin_ult_i32
249; SI: s_min_u32
250
251; EG: MIN_UINT
252define void @s_test_umin_ult_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
253  %cmp = icmp ult i32 %a, %b
254  %val = select i1 %cmp, i32 %a, i32 %b
255  store i32 %val, i32 addrspace(1)* %out, align 4
256  ret void
257}
258
259; FUNC-LABEL: @v_test_umin_ult_i32_multi_use
260; SI-NOT: v_min
261; SI: v_cmp_lt_u32
262; SI-NEXT: v_cndmask_b32
263; SI-NOT: v_min
264; SI: s_endpgm
265
266; EG-NOT: MIN_UINT
267define void @v_test_umin_ult_i32_multi_use(i32 addrspace(1)* %out0, i1 addrspace(1)* %out1, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
268  %a = load i32, i32 addrspace(1)* %aptr, align 4
269  %b = load i32, i32 addrspace(1)* %bptr, align 4
270  %cmp = icmp ult i32 %a, %b
271  %val = select i1 %cmp, i32 %a, i32 %b
272  store i32 %val, i32 addrspace(1)* %out0, align 4
273  store i1 %cmp, i1 addrspace(1)* %out1
274  ret void
275}
276
277
278; FUNC-LABEL: @s_test_umin_ult_v1i32
279; SI: s_min_u32
280
281; EG: MIN_UINT
282define void @s_test_umin_ult_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
283  %cmp = icmp ult <1 x i32> %a, %b
284  %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
285  store <1 x i32> %val, <1 x i32> addrspace(1)* %out
286  ret void
287}
288
289; FUNC-LABEL: {{^}}s_test_umin_ult_v8i32:
290; SI: s_min_u32
291; SI: s_min_u32
292; SI: s_min_u32
293; SI: s_min_u32
294; SI: s_min_u32
295; SI: s_min_u32
296; SI: s_min_u32
297; SI: s_min_u32
298
299; EG: MIN_UINT
300; EG: MIN_UINT
301; EG: MIN_UINT
302; EG: MIN_UINT
303; EG: MIN_UINT
304; EG: MIN_UINT
305; EG: MIN_UINT
306; EG: MIN_UINT
307define void @s_test_umin_ult_v8i32(<8 x i32> addrspace(1)* %out, <8 x i32> %a, <8 x i32> %b) nounwind {
308  %cmp = icmp ult <8 x i32> %a, %b
309  %val = select <8 x i1> %cmp, <8 x i32> %a, <8 x i32> %b
310  store <8 x i32> %val, <8 x i32> addrspace(1)* %out
311  ret void
312}
313
314; FUNC-LABEL: {{^}}s_test_umin_ult_v8i16:
315; SI: v_min_u32
316; SI: v_min_u32
317; SI: v_min_u32
318; SI: v_min_u32
319; SI: v_min_u32
320; SI: v_min_u32
321; SI: v_min_u32
322; SI: v_min_u32
323
324; EG: MIN_UINT
325; EG: MIN_UINT
326; EG: MIN_UINT
327; EG: MIN_UINT
328; EG: MIN_UINT
329; EG: MIN_UINT
330; EG: MIN_UINT
331; EG: MIN_UINT
332define void @s_test_umin_ult_v8i16(<8 x i16> addrspace(1)* %out, <8 x i16> %a, <8 x i16> %b) nounwind {
333  %cmp = icmp ult <8 x i16> %a, %b
334  %val = select <8 x i1> %cmp, <8 x i16> %a, <8 x i16> %b
335  store <8 x i16> %val, <8 x i16> addrspace(1)* %out
336  ret void
337}
338
339; Make sure redundant and removed
340; FUNC-LABEL: {{^}}simplify_demanded_bits_test_umin_ult_i16:
341; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
342; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
343; SI: s_min_u32 [[MIN:s[0-9]+]], [[A]], [[B]]
344; SI: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
345; SI: buffer_store_dword [[VMIN]]
346
347; EG: MIN_UINT
348define void @simplify_demanded_bits_test_umin_ult_i16(i32 addrspace(1)* %out, i16 zeroext %a, i16 zeroext %b) nounwind {
349  %a.ext = zext i16 %a to i32
350  %b.ext = zext i16 %b to i32
351  %cmp = icmp ult i32 %a.ext, %b.ext
352  %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
353  %mask = and i32 %val, 65535
354  store i32 %mask, i32 addrspace(1)* %out
355  ret void
356}
357
358; Make sure redundant sign_extend_inreg removed.
359
360; FUNC-LABEL: {{^}}simplify_demanded_bits_test_min_slt_i16:
361; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
362; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
363; SI: s_min_i32 [[MIN:s[0-9]+]], [[A]], [[B]]
364; SI: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
365; SI: buffer_store_dword [[VMIN]]
366
367; EG: MIN_INT
368define void @simplify_demanded_bits_test_min_slt_i16(i32 addrspace(1)* %out, i16 signext %a, i16 signext %b) nounwind {
369  %a.ext = sext i16 %a to i32
370  %b.ext = sext i16 %b to i32
371  %cmp = icmp slt i32 %a.ext, %b.ext
372  %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
373  %shl = shl i32 %val, 16
374  %sextinreg = ashr i32 %shl, 16
375  store i32 %sextinreg, i32 addrspace(1)* %out
376  ret void
377}
378
379; FUNC-LABEL: {{^}}s_test_imin_sle_i16:
380; SI: s_min_i32
381
382; EG: MIN_INT
383define void @s_test_imin_sle_i16(i16 addrspace(1)* %out, i16 %a, i16 %b) nounwind {
384  %cmp = icmp sle i16 %a, %b
385  %val = select i1 %cmp, i16 %a, i16 %b
386  store i16 %val, i16 addrspace(1)* %out
387  ret void
388}
389
390; 64 bit
391; FUNC-LABEL: {{^}}test_umin_ult_i64
392; SI: s_endpgm
393
394; EG: MIN_UINT
395; EG: MIN_UINT
396define void @test_umin_ult_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
397  %tmp = icmp ult i64 %a, %b
398  %val = select i1 %tmp, i64 %a, i64 %b
399  store i64 %val, i64 addrspace(1)* %out, align 8
400  ret void
401}
402
403; FUNC-LABEL: {{^}}test_umin_ule_i64
404; SI: s_endpgm
405
406; EG: MIN_UINT
407; EG: MIN_UINT
408define void @test_umin_ule_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
409  %tmp = icmp ule i64 %a, %b
410  %val = select i1 %tmp, i64 %a, i64 %b
411  store i64 %val, i64 addrspace(1)* %out, align 8
412  ret void
413}
414
415; FUNC-LABEL: {{^}}test_imin_slt_i64
416; SI: s_endpgm
417
418; EG-DAG: MIN_UINT
419; EG-DAG: MIN_INT
420define void @test_imin_slt_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
421  %tmp = icmp slt i64 %a, %b
422  %val = select i1 %tmp, i64 %a, i64 %b
423  store i64 %val, i64 addrspace(1)* %out, align 8
424  ret void
425}
426
427; FUNC-LABEL: {{^}}test_imin_sle_i64
428; SI: s_endpgm
429
430; EG-DAG: MIN_UINT
431; EG-DAG: MIN_INT
432define void @test_imin_sle_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
433  %tmp = icmp sle i64 %a, %b
434  %val = select i1 %tmp, i64 %a, i64 %b
435  store i64 %val, i64 addrspace(1)* %out, align 8
436  ret void
437}
438