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