xref: /llvm-project/llvm/test/CodeGen/AMDGPU/umed3.ll (revision 49357b22dbb26d4aa6816dee279df70f1a2cd695)
1; RUN: llc -mtriple=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN  -check-prefix=SI %s
2; RUN: llc -mtriple=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
3; RUN: llc -mtriple=amdgcn -mcpu=gfx900 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GFX9 %s
4; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-flat-for-global,-real-true16 -verify-machineinstrs < %s | FileCheck -check-prefix=GFX11-FAKE16 %s
5; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-flat-for-global,+real-true16 -verify-machineinstrs < %s | FileCheck -check-prefix=GFX11-TRUE16 %s
6
7declare i32 @llvm.amdgcn.workitem.id.x() #0
8
9; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i32:
10; GCN: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
11define amdgpu_kernel void @v_test_umed3_r_i_i_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
12  %tid = call i32 @llvm.amdgcn.workitem.id.x()
13  %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
14  %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
15  %a = load i32, ptr addrspace(1) %gep0
16
17  %icmp0 = icmp ugt i32 %a, 12
18  %i0 = select i1 %icmp0, i32 %a, i32 12
19
20  %icmp1 = icmp ult i32 %i0, 17
21  %i1 = select i1 %icmp1, i32 %i0, i32 17
22
23  store i32 %i1, ptr addrspace(1) %outgep
24  ret void
25}
26
27; GCN-LABEL: {{^}}v_test_umed3_multi_use_r_i_i_i32:
28; GCN: v_max_u32
29; GCN: v_min_u32
30define amdgpu_kernel void @v_test_umed3_multi_use_r_i_i_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
31  %tid = call i32 @llvm.amdgcn.workitem.id.x()
32  %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
33  %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
34  %a = load i32, ptr addrspace(1) %gep0
35
36  %icmp0 = icmp ugt i32 %a, 12
37  %i0 = select i1 %icmp0, i32 %a, i32 12
38
39  %icmp1 = icmp ult i32 %i0, 17
40  %i1 = select i1 %icmp1, i32 %i0, i32 17
41
42  store volatile i32 %i0, ptr addrspace(1) %outgep
43  store volatile i32 %i1, ptr addrspace(1) %outgep
44  ret void
45}
46
47; GCN-LABEL: {{^}}v_test_umed3_r_i_i_sign_mismatch_i32:
48; GCN: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
49define amdgpu_kernel void @v_test_umed3_r_i_i_sign_mismatch_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
50  %tid = call i32 @llvm.amdgcn.workitem.id.x()
51  %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
52  %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
53  %a = load i32, ptr addrspace(1) %gep0
54
55  %icmp0 = icmp sgt i32 %a, 12
56  %i0 = select i1 %icmp0, i32 %a, i32 12
57
58  %icmp1 = icmp ult i32 %i0, 17
59  %i1 = select i1 %icmp1, i32 %i0, i32 17
60
61  store i32 %i1, ptr addrspace(1) %outgep
62  ret void
63}
64
65; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i64:
66; GCN: v_cmp_lt_u64
67; GCN: v_cmp_gt_u64
68define amdgpu_kernel void @v_test_umed3_r_i_i_i64(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
69  %tid = call i32 @llvm.amdgcn.workitem.id.x()
70  %gep0 = getelementptr i64, ptr addrspace(1) %aptr, i32 %tid
71  %outgep = getelementptr i64, ptr addrspace(1) %out, i32 %tid
72  %a = load i64, ptr addrspace(1) %gep0
73
74  %icmp0 = icmp ugt i64 %a, 12
75  %i0 = select i1 %icmp0, i64 %a, i64 12
76
77  %icmp1 = icmp ult i64 %i0, 17
78  %i1 = select i1 %icmp1, i64 %i0, i64 17
79
80  store i64 %i1, ptr addrspace(1) %outgep
81  ret void
82}
83
84; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i16:
85; SI: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
86; VI: v_max_u16_e32 [[MAX:v[0-9]]], 12, {{v[0-9]}}
87; VI: v_min_u16_e32 {{v[0-9]}}, 17, [[MAX]]
88; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
89; GFX11-TRUE16: v_med3_u16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, 12, 17
90; GFX11-FAKE16: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
91define amdgpu_kernel void @v_test_umed3_r_i_i_i16(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
92  %tid = call i32 @llvm.amdgcn.workitem.id.x()
93  %gep0 = getelementptr i16, ptr addrspace(1) %aptr, i32 %tid
94  %outgep = getelementptr i16, ptr addrspace(1) %out, i32 %tid
95  %a = load i16, ptr addrspace(1) %gep0
96
97  %icmp0 = icmp ugt i16 %a, 12
98  %i0 = select i1 %icmp0, i16 %a, i16 12
99
100  %icmp1 = icmp ult i16 %i0, 17
101  %i1 = select i1 %icmp1, i16 %i0, i16 17
102
103  store i16 %i1, ptr addrspace(1) %outgep
104  ret void
105}
106
107define internal i32 @umin(i32 %x, i32 %y) #2 {
108  %cmp = icmp ult i32 %x, %y
109  %sel = select i1 %cmp, i32 %x, i32 %y
110  ret i32 %sel
111}
112
113define internal i32 @umax(i32 %x, i32 %y) #2 {
114  %cmp = icmp ugt i32 %x, %y
115  %sel = select i1 %cmp, i32 %x, i32 %y
116  ret i32 %sel
117}
118
119define internal i16 @umin16(i16 %x, i16 %y) #2 {
120  %cmp = icmp ult i16 %x, %y
121  %sel = select i1 %cmp, i16 %x, i16 %y
122  ret i16 %sel
123}
124
125define internal i16 @umax16(i16 %x, i16 %y) #2 {
126  %cmp = icmp ugt i16 %x, %y
127  %sel = select i1 %cmp, i16 %x, i16 %y
128  ret i16 %sel
129}
130
131define internal i8 @umin8(i8 %x, i8 %y) #2 {
132  %cmp = icmp ult i8 %x, %y
133  %sel = select i1 %cmp, i8 %x, i8 %y
134  ret i8 %sel
135}
136
137define internal i8 @umax8(i8 %x, i8 %y) #2 {
138  %cmp = icmp ugt i8 %x, %y
139  %sel = select i1 %cmp, i8 %x, i8 %y
140  ret i8 %sel
141}
142
143; 16 combinations
144
145; 0: max(min(x, y), min(max(x, y), z))
146; 1: max(min(x, y), min(max(y, x), z))
147; 2: max(min(x, y), min(z, max(x, y)))
148; 3: max(min(x, y), min(z, max(y, x)))
149; 4: max(min(y, x), min(max(x, y), z))
150; 5: max(min(y, x), min(max(y, x), z))
151; 6: max(min(y, x), min(z, max(x, y)))
152; 7: max(min(y, x), min(z, max(y, x)))
153;
154; + commute outermost max
155
156
157; FIXME: In these cases we probably should have used scalar operations
158; instead.
159
160; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0:
161; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
162define amdgpu_kernel void @s_test_umed3_i32_pat_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
163bb:
164  %tmp0 = call i32 @umin(i32 %x, i32 %y)
165  %tmp1 = call i32 @umax(i32 %x, i32 %y)
166  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
167  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
168  store i32 %tmp3, ptr addrspace(1) %arg
169  ret void
170}
171
172; GCN-LABEL: {{^}}s_test_umed3_i32_pat_1:
173; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
174define amdgpu_kernel void @s_test_umed3_i32_pat_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
175bb:
176  %tmp0 = call i32 @umin(i32 %x, i32 %y)
177  %tmp1 = call i32 @umax(i32 %y, i32 %x)
178  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
179  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
180  store i32 %tmp3, ptr addrspace(1) %arg
181  ret void
182}
183
184; GCN-LABEL: {{^}}s_test_umed3_i32_pat_2:
185; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
186define amdgpu_kernel void @s_test_umed3_i32_pat_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
187bb:
188  %tmp0 = call i32 @umin(i32 %x, i32 %y)
189  %tmp1 = call i32 @umax(i32 %x, i32 %y)
190  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
191  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
192  store i32 %tmp3, ptr addrspace(1) %arg
193  ret void
194}
195
196; GCN-LABEL: {{^}}s_test_umed3_i32_pat_3:
197; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
198define amdgpu_kernel void @s_test_umed3_i32_pat_3(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
199bb:
200  %tmp0 = call i32 @umin(i32 %x, i32 %y)
201  %tmp1 = call i32 @umax(i32 %y, i32 %x)
202  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
203  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
204  store i32 %tmp3, ptr addrspace(1) %arg
205  ret void
206}
207
208; GCN-LABEL: {{^}}s_test_umed3_i32_pat_4:
209; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
210define amdgpu_kernel void @s_test_umed3_i32_pat_4(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
211bb:
212  %tmp0 = call i32 @umin(i32 %y, i32 %x)
213  %tmp1 = call i32 @umax(i32 %x, i32 %y)
214  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
215  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
216  store i32 %tmp3, ptr addrspace(1) %arg
217  ret void
218}
219
220; GCN-LABEL: {{^}}s_test_umed3_i32_pat_5:
221; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
222define amdgpu_kernel void @s_test_umed3_i32_pat_5(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
223bb:
224  %tmp0 = call i32 @umin(i32 %y, i32 %x)
225  %tmp1 = call i32 @umax(i32 %y, i32 %x)
226  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
227  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
228  store i32 %tmp3, ptr addrspace(1) %arg
229  ret void
230}
231
232; GCN-LABEL: {{^}}s_test_umed3_i32_pat_6:
233; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
234define amdgpu_kernel void @s_test_umed3_i32_pat_6(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
235bb:
236  %tmp0 = call i32 @umin(i32 %y, i32 %x)
237  %tmp1 = call i32 @umax(i32 %x, i32 %y)
238  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
239  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
240  store i32 %tmp3, ptr addrspace(1) %arg
241  ret void
242}
243
244; GCN-LABEL: {{^}}s_test_umed3_i32_pat_7:
245; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
246define amdgpu_kernel void @s_test_umed3_i32_pat_7(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
247bb:
248  %tmp0 = call i32 @umin(i32 %y, i32 %x)
249  %tmp1 = call i32 @umax(i32 %y, i32 %x)
250  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
251  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
252  store i32 %tmp3, ptr addrspace(1) %arg
253  ret void
254}
255
256; GCN-LABEL: {{^}}s_test_umed3_i32_pat_8:
257; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
258define amdgpu_kernel void @s_test_umed3_i32_pat_8(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
259bb:
260  %tmp0 = call i32 @umin(i32 %x, i32 %y)
261  %tmp1 = call i32 @umax(i32 %x, i32 %y)
262  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
263  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
264  store i32 %tmp3, ptr addrspace(1) %arg
265  ret void
266}
267
268; GCN-LABEL: {{^}}s_test_umed3_i32_pat_9:
269; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
270define amdgpu_kernel void @s_test_umed3_i32_pat_9(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
271bb:
272  %tmp0 = call i32 @umin(i32 %x, i32 %y)
273  %tmp1 = call i32 @umax(i32 %y, i32 %x)
274  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
275  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
276  store i32 %tmp3, ptr addrspace(1) %arg
277  ret void
278}
279
280; GCN-LABEL: {{^}}s_test_umed3_i32_pat_10:
281; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
282define amdgpu_kernel void @s_test_umed3_i32_pat_10(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
283bb:
284  %tmp0 = call i32 @umin(i32 %x, i32 %y)
285  %tmp1 = call i32 @umax(i32 %x, i32 %y)
286  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
287  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
288  store i32 %tmp3, ptr addrspace(1) %arg
289  ret void
290}
291
292; GCN-LABEL: {{^}}s_test_umed3_i32_pat_11:
293; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
294define amdgpu_kernel void @s_test_umed3_i32_pat_11(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
295bb:
296  %tmp0 = call i32 @umin(i32 %x, i32 %y)
297  %tmp1 = call i32 @umax(i32 %y, i32 %x)
298  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
299  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
300  store i32 %tmp3, ptr addrspace(1) %arg
301  ret void
302}
303
304; GCN-LABEL: {{^}}s_test_umed3_i32_pat_12:
305; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
306define amdgpu_kernel void @s_test_umed3_i32_pat_12(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
307bb:
308  %tmp0 = call i32 @umin(i32 %y, i32 %x)
309  %tmp1 = call i32 @umax(i32 %x, i32 %y)
310  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
311  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
312  store i32 %tmp3, ptr addrspace(1) %arg
313  ret void
314}
315
316; GCN-LABEL: {{^}}s_test_umed3_i32_pat_13:
317; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
318define amdgpu_kernel void @s_test_umed3_i32_pat_13(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
319bb:
320  %tmp0 = call i32 @umin(i32 %y, i32 %x)
321  %tmp1 = call i32 @umax(i32 %y, i32 %x)
322  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
323  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
324  store i32 %tmp3, ptr addrspace(1) %arg
325  ret void
326}
327
328; GCN-LABEL: {{^}}s_test_umed3_i32_pat_14:
329; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
330define amdgpu_kernel void @s_test_umed3_i32_pat_14(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
331bb:
332  %tmp0 = call i32 @umin(i32 %y, i32 %x)
333  %tmp1 = call i32 @umax(i32 %x, i32 %y)
334  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
335  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
336  store i32 %tmp3, ptr addrspace(1) %arg
337  ret void
338}
339
340; GCN-LABEL: {{^}}s_test_umed3_i32_pat_15:
341; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
342define amdgpu_kernel void @s_test_umed3_i32_pat_15(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
343bb:
344  %tmp0 = call i32 @umin(i32 %y, i32 %x)
345  %tmp1 = call i32 @umax(i32 %y, i32 %x)
346  %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
347  %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
348  store i32 %tmp3, ptr addrspace(1) %arg
349  ret void
350}
351
352; 16 combinations
353
354; 16: min(max(x, y), max(min(x, y), z))
355; 17: min(max(x, y), max(min(y, x), z))
356; 18: min(max(x, y), max(z, min(x, y)))
357; 19: min(max(x, y), max(z, min(y, x)))
358; 20: min(max(y, x), max(min(x, y), z))
359; 21: min(max(y, x), max(min(y, x), z))
360; 22: min(max(y, x), max(z, min(x, y)))
361; 23: min(max(y, x), max(z, min(y, x)))
362;
363; + commute outermost min
364
365
366; GCN-LABEL: {{^}}s_test_umed3_i32_pat_16:
367; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
368define amdgpu_kernel void @s_test_umed3_i32_pat_16(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
369bb:
370  %tmp0 = call i32 @umin(i32 %x, i32 %y)
371  %tmp1 = call i32 @umax(i32 %x, i32 %y)
372  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
373  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
374  store i32 %tmp3, ptr addrspace(1) %arg
375  ret void
376}
377
378; GCN-LABEL: {{^}}s_test_umed3_i32_pat_17:
379; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
380define amdgpu_kernel void @s_test_umed3_i32_pat_17(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
381bb:
382  %tmp0 = call i32 @umin(i32 %y, i32 %x)
383  %tmp1 = call i32 @umax(i32 %x, i32 %y)
384  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
385  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
386  store i32 %tmp3, ptr addrspace(1) %arg
387  ret void
388}
389
390; GCN-LABEL: {{^}}s_test_umed3_i32_pat_18:
391; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
392define amdgpu_kernel void @s_test_umed3_i32_pat_18(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
393bb:
394  %tmp0 = call i32 @umin(i32 %x, i32 %y)
395  %tmp1 = call i32 @umax(i32 %x, i32 %y)
396  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
397  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
398  store i32 %tmp3, ptr addrspace(1) %arg
399  ret void
400}
401
402; GCN-LABEL: {{^}}s_test_umed3_i32_pat_19:
403; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
404define amdgpu_kernel void @s_test_umed3_i32_pat_19(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
405bb:
406  %tmp0 = call i32 @umin(i32 %y, i32 %x)
407  %tmp1 = call i32 @umax(i32 %x, i32 %y)
408  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
409  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
410  store i32 %tmp3, ptr addrspace(1) %arg
411  ret void
412}
413
414; GCN-LABEL: {{^}}s_test_umed3_i32_pat_20:
415; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
416define amdgpu_kernel void @s_test_umed3_i32_pat_20(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
417bb:
418  %tmp0 = call i32 @umin(i32 %x, i32 %y)
419  %tmp1 = call i32 @umax(i32 %y, i32 %x)
420  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
421  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
422  store i32 %tmp3, ptr addrspace(1) %arg
423  ret void
424}
425
426; GCN-LABEL: {{^}}s_test_umed3_i32_pat_21:
427; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
428define amdgpu_kernel void @s_test_umed3_i32_pat_21(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
429bb:
430  %tmp0 = call i32 @umin(i32 %y, i32 %x)
431  %tmp1 = call i32 @umax(i32 %y, i32 %x)
432  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
433  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
434  store i32 %tmp3, ptr addrspace(1) %arg
435  ret void
436}
437
438; GCN-LABEL: {{^}}s_test_umed3_i32_pat_22:
439; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
440define amdgpu_kernel void @s_test_umed3_i32_pat_22(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
441bb:
442  %tmp0 = call i32 @umin(i32 %x, i32 %y)
443  %tmp1 = call i32 @umax(i32 %y, i32 %x)
444  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
445  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
446  store i32 %tmp3, ptr addrspace(1) %arg
447  ret void
448}
449
450; GCN-LABEL: {{^}}s_test_umed3_i32_pat_23:
451; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
452define amdgpu_kernel void @s_test_umed3_i32_pat_23(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
453bb:
454  %tmp0 = call i32 @umin(i32 %y, i32 %x)
455  %tmp1 = call i32 @umax(i32 %y, i32 %x)
456  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
457  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
458  store i32 %tmp3, ptr addrspace(1) %arg
459  ret void
460}
461
462; GCN-LABEL: {{^}}s_test_umed3_i32_pat_24:
463; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
464define amdgpu_kernel void @s_test_umed3_i32_pat_24(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
465bb:
466  %tmp0 = call i32 @umin(i32 %x, i32 %y)
467  %tmp1 = call i32 @umax(i32 %x, i32 %y)
468  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
469  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
470  store i32 %tmp3, ptr addrspace(1) %arg
471  ret void
472}
473
474; GCN-LABEL: {{^}}s_test_umed3_i32_pat_25:
475; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
476define amdgpu_kernel void @s_test_umed3_i32_pat_25(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
477bb:
478  %tmp0 = call i32 @umin(i32 %y, i32 %x)
479  %tmp1 = call i32 @umax(i32 %x, i32 %y)
480  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
481  %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
482  store i32 %tmp3, ptr addrspace(1) %arg
483  ret void
484}
485
486; GCN-LABEL: {{^}}s_test_umed3_i32_pat_26:
487; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
488define amdgpu_kernel void @s_test_umed3_i32_pat_26(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
489bb:
490  %tmp0 = call i32 @umin(i32 %x, i32 %y)
491  %tmp1 = call i32 @umax(i32 %x, i32 %y)
492  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
493  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
494  store i32 %tmp3, ptr addrspace(1) %arg
495  ret void
496}
497
498; GCN-LABEL: {{^}}s_test_umed3_i32_pat_27:
499; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
500define amdgpu_kernel void @s_test_umed3_i32_pat_27(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
501bb:
502  %tmp0 = call i32 @umin(i32 %y, i32 %x)
503  %tmp1 = call i32 @umax(i32 %x, i32 %y)
504  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
505  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
506  store i32 %tmp3, ptr addrspace(1) %arg
507  ret void
508}
509
510; GCN-LABEL: {{^}}s_test_umed3_i32_pat_28:
511; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
512define amdgpu_kernel void @s_test_umed3_i32_pat_28(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
513bb:
514  %tmp0 = call i32 @umin(i32 %x, i32 %y)
515  %tmp1 = call i32 @umax(i32 %y, i32 %x)
516  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
517  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
518  store i32 %tmp3, ptr addrspace(1) %arg
519  ret void
520}
521
522; GCN-LABEL: {{^}}s_test_umed3_i32_pat_29:
523; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
524define amdgpu_kernel void @s_test_umed3_i32_pat_29(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
525bb:
526  %tmp0 = call i32 @umin(i32 %y, i32 %x)
527  %tmp1 = call i32 @umax(i32 %y, i32 %x)
528  %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
529  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
530  store i32 %tmp3, ptr addrspace(1) %arg
531  ret void
532}
533
534; GCN-LABEL: {{^}}s_test_umed3_i32_pat_30:
535; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
536define amdgpu_kernel void @s_test_umed3_i32_pat_30(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
537bb:
538  %tmp0 = call i32 @umin(i32 %x, i32 %y)
539  %tmp1 = call i32 @umax(i32 %y, i32 %x)
540  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
541  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
542  store i32 %tmp3, ptr addrspace(1) %arg
543  ret void
544}
545
546; GCN-LABEL: {{^}}s_test_umed3_i32_pat_31:
547; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
548define amdgpu_kernel void @s_test_umed3_i32_pat_31(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
549bb:
550  %tmp0 = call i32 @umin(i32 %y, i32 %x)
551  %tmp1 = call i32 @umax(i32 %y, i32 %x)
552  %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
553  %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
554  store i32 %tmp3, ptr addrspace(1) %arg
555  ret void
556}
557
558; GCN-LABEL: {{^}}s_test_umed3_i16_pat_0:
559; GCN: s_and_b32
560; GCN: s_and_b32
561; GCN: s_and_b32
562; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
563define amdgpu_kernel void @s_test_umed3_i16_pat_0(ptr addrspace(1) %arg, [8 x i32], i16 %x, [8 x i32], i16 %y, [8 x i32], i16 %z) #1 {
564bb:
565  %tmp0 = call i16 @umin16(i16 %x, i16 %y)
566  %tmp1 = call i16 @umax16(i16 %x, i16 %y)
567  %tmp2 = call i16 @umin16(i16 %tmp1, i16 %z)
568  %tmp3 = call i16 @umax16(i16 %tmp0, i16 %tmp2)
569  store i16 %tmp3, ptr addrspace(1) %arg
570  ret void
571}
572
573; GCN-LABEL: {{^}}s_test_umed3_i8_pat_0:
574; GCN: s_and_b32
575; GCN: s_and_b32
576; GCN: s_and_b32
577; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
578define amdgpu_kernel void @s_test_umed3_i8_pat_0(ptr addrspace(1) %arg, [8 x i32], i8 %x, [8 x i32], i8 %y, [8 x i32], i8 %z) #1 {
579bb:
580  %tmp0 = call i8 @umin8(i8 %x, i8 %y)
581  %tmp1 = call i8 @umax8(i8 %x, i8 %y)
582  %tmp2 = call i8 @umin8(i8 %tmp1, i8 %z)
583  %tmp3 = call i8 @umax8(i8 %tmp0, i8 %tmp2)
584  store i8 %tmp3, ptr addrspace(1) %arg
585  ret void
586}
587
588; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_0:
589; GCN: s_min_u32
590; GCN-NOT: {{s_min_u32|s_max_u32}}
591; GCN: v_med3_u32
592define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
593bb:
594  %tmp0 = call i32 @umin(i32 %x, i32 %y)
595  %tmp1 = call i32 @umax(i32 %x, i32 %y)
596  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
597  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
598  store volatile i32 %tmp0, ptr addrspace(1) %arg
599  store volatile i32 %tmp3, ptr addrspace(1) %arg
600  ret void
601}
602
603; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_1:
604; GCN: s_max_u32
605; GCN-NOT: {{s_min_u32|s_max_u32}}
606; GCN: v_med3_u32
607define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
608bb:
609  %tmp0 = call i32 @umin(i32 %x, i32 %y)
610  %tmp1 = call i32 @umax(i32 %x, i32 %y)
611  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
612  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
613  store volatile i32 %tmp1, ptr addrspace(1) %arg
614  store volatile i32 %tmp3, ptr addrspace(1) %arg
615  ret void
616}
617
618; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_2:
619; GCN: s_max_u32
620; GCN: s_min_u32
621; GCN-NOT: {{s_min_u32|s_max_u32}}
622; GCN: v_med3_u32
623define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
624bb:
625  %tmp0 = call i32 @umin(i32 %x, i32 %y)
626  %tmp1 = call i32 @umax(i32 %x, i32 %y)
627  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
628  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
629  store volatile i32 %tmp2, ptr addrspace(1) %arg
630  store volatile i32 %tmp3, ptr addrspace(1) %arg
631  ret void
632}
633
634; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_result:
635; GCN-NOT: {{s_min_u32|s_max_u32}}
636; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
637define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_result(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
638bb:
639  %tmp0 = call i32 @umin(i32 %x, i32 %y)
640  %tmp1 = call i32 @umax(i32 %x, i32 %y)
641  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
642  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
643  store volatile i32 %tmp3, ptr addrspace(1) %arg
644  store volatile i32 %tmp3, ptr addrspace(1) %arg
645  ret void
646}
647
648; GCN-LABEL: {{^}}s_test_smed3_reuse_bounds
649; GCN-NOT: {{s_min_u32|s_max_u32}}
650; GCN: v_med3_u32 v{{[0-9]+}}, [[B0:s[0-9]+]], [[B1:v[0-9]+]], v{{[0-9]+}}
651; GCN: v_med3_u32 v{{[0-9]+}}, [[B0]], [[B1]], v{{[0-9]+}}
652define amdgpu_kernel void @s_test_smed3_reuse_bounds(ptr addrspace(1) %arg, i32 %b0, i32 %b1, i32 %x, i32 %y) #1 {
653bb:
654  %lo = call i32 @umin(i32 %b0, i32 %b1)
655  %hi = call i32 @umax(i32 %b0, i32 %b1)
656
657  %tmp0 = call i32 @umin(i32 %x, i32 %hi)
658  %z0 = call i32 @umax(i32 %tmp0, i32 %lo)
659
660  %tmp1 = call i32 @umin(i32 %y, i32 %hi)
661  %z1 = call i32 @umax(i32 %tmp1, i32 %lo)
662
663  store volatile i32 %z0, ptr addrspace(1) %arg
664  store volatile i32 %z1, ptr addrspace(1) %arg
665  ret void
666}
667
668; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src0:
669; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, 1, v{{[0-9]+}}
670define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
671bb:
672  %tmp0 = call i32 @umin(i32 1, i32 %y)
673  %tmp1 = call i32 @umax(i32 1, i32 %y)
674  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
675  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
676  store i32 %tmp3, ptr addrspace(1) %arg
677  ret void
678}
679
680; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src1:
681; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, 2, v{{[0-9]+}}
682define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
683bb:
684  %tmp0 = call i32 @umin(i32 %x, i32 2)
685  %tmp1 = call i32 @umax(i32 %x, i32 2)
686  %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
687  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
688  store i32 %tmp3, ptr addrspace(1) %arg
689  ret void
690}
691
692; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src2:
693; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, 9
694define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
695bb:
696  %tmp0 = call i32 @umin(i32 %x, i32 %y)
697  %tmp1 = call i32 @umax(i32 %x, i32 %y)
698  %tmp2 = call i32 @umin(i32 %tmp1, i32 9)
699  %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
700  store i32 %tmp3, ptr addrspace(1) %arg
701  ret void
702}
703
704; GCN-LABEL: {{^}}v_test_umed3_i16_pat_0:
705; SI: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
706
707; FIXME: VI not matching med3
708; VI: v_min_u16
709; VI: v_max_u16
710; VI: v_min_u16
711; VI: v_max_u16
712
713; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
714; GFX11-TRUE16: v_med3_u16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, v{{[0-9]+}}.h, v{{[0-9]+}}.l
715; GFX11-FAKE16: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
716define amdgpu_kernel void @v_test_umed3_i16_pat_0(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
717bb:
718  %tid = call i32 @llvm.amdgcn.workitem.id.x()
719  %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
720  %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
721  %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
722  %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
723  %x = load i16, ptr addrspace(1) %gep0
724  %y = load i16, ptr addrspace(1) %gep1
725  %z = load i16, ptr addrspace(1) %gep2
726
727  %tmp0 = call i16 @umin16(i16 %x, i16 %y)
728  %tmp1 = call i16 @umax16(i16 %x, i16 %y)
729  %tmp2 = call i16 @umin16(i16 %tmp1, i16 %z)
730  %tmp3 = call i16 @umax16(i16 %tmp0, i16 %tmp2)
731  store i16 %tmp3, ptr addrspace(1) %out.gep
732  ret void
733}
734
735; GCN-LABEL: {{^}}v_test_umed3_i16_pat_1:
736; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
737; GFX11-TRUE16: v_med3_u16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, v{{[0-9]+}}.h, v{{[0-9]+}}.l
738; GFX11-FAKE16: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
739define amdgpu_kernel void @v_test_umed3_i16_pat_1(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
740bb:
741  %tid = call i32 @llvm.amdgcn.workitem.id.x()
742  %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
743  %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
744  %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
745  %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
746  %x = load i16, ptr addrspace(1) %gep0
747  %y = load i16, ptr addrspace(1) %gep1
748  %z = load i16, ptr addrspace(1) %gep2
749
750  %tmp0 = call i16 @umin16(i16 %x, i16 %y)
751  %tmp1 = call i16 @umax16(i16 %x, i16 %y)
752  %tmp2 = call i16 @umax16(i16 %tmp0, i16 %z)
753  %tmp3 = call i16 @umin16(i16 %tmp1, i16 %tmp2)
754  store i16 %tmp3, ptr addrspace(1) %out.gep
755  ret void
756}
757
758attributes #0 = { nounwind readnone }
759attributes #1 = { nounwind }
760attributes #2 = { nounwind readnone alwaysinline }
761