Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / umed3.ll
blobced86b98d779eec5e3d8ea6faec51b00c5eec128
1 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN  -check-prefix=SI %s
2 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
3 ; RUN: llc -march=amdgcn -mcpu=gfx900 -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=GFX9 %s
5 declare i32 @llvm.amdgcn.workitem.id.x() #0
7 ; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i32:
8 ; GCN: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
9 define amdgpu_kernel void @v_test_umed3_r_i_i_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
10   %tid = call i32 @llvm.amdgcn.workitem.id.x()
11   %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
12   %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
13   %a = load i32, ptr addrspace(1) %gep0
15   %icmp0 = icmp ugt i32 %a, 12
16   %i0 = select i1 %icmp0, i32 %a, i32 12
18   %icmp1 = icmp ult i32 %i0, 17
19   %i1 = select i1 %icmp1, i32 %i0, i32 17
21   store i32 %i1, ptr addrspace(1) %outgep
22   ret void
25 ; GCN-LABEL: {{^}}v_test_umed3_multi_use_r_i_i_i32:
26 ; GCN: v_max_u32
27 ; GCN: v_min_u32
28 define amdgpu_kernel void @v_test_umed3_multi_use_r_i_i_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
29   %tid = call i32 @llvm.amdgcn.workitem.id.x()
30   %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
31   %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
32   %a = load i32, ptr addrspace(1) %gep0
34   %icmp0 = icmp ugt i32 %a, 12
35   %i0 = select i1 %icmp0, i32 %a, i32 12
37   %icmp1 = icmp ult i32 %i0, 17
38   %i1 = select i1 %icmp1, i32 %i0, i32 17
40   store volatile i32 %i0, ptr addrspace(1) %outgep
41   store volatile i32 %i1, ptr addrspace(1) %outgep
42   ret void
45 ; GCN-LABEL: {{^}}v_test_umed3_r_i_i_sign_mismatch_i32:
46 ; GCN: v_max_i32_e32 v{{[0-9]+}}, 12, v{{[0-9]+}}
47 ; GCN: v_min_u32_e32 v{{[0-9]+}}, 17, v{{[0-9]+}}
48 define amdgpu_kernel void @v_test_umed3_r_i_i_sign_mismatch_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
49   %tid = call i32 @llvm.amdgcn.workitem.id.x()
50   %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
51   %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
52   %a = load i32, ptr addrspace(1) %gep0
54   %icmp0 = icmp sgt i32 %a, 12
55   %i0 = select i1 %icmp0, i32 %a, i32 12
57   %icmp1 = icmp ult i32 %i0, 17
58   %i1 = select i1 %icmp1, i32 %i0, i32 17
60   store i32 %i1, ptr addrspace(1) %outgep
61   ret void
64 ; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i64:
65 ; GCN: v_cmp_lt_u64
66 ; GCN: v_cmp_gt_u64
67 define amdgpu_kernel void @v_test_umed3_r_i_i_i64(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
68   %tid = call i32 @llvm.amdgcn.workitem.id.x()
69   %gep0 = getelementptr i64, ptr addrspace(1) %aptr, i32 %tid
70   %outgep = getelementptr i64, ptr addrspace(1) %out, i32 %tid
71   %a = load i64, ptr addrspace(1) %gep0
73   %icmp0 = icmp ugt i64 %a, 12
74   %i0 = select i1 %icmp0, i64 %a, i64 12
76   %icmp1 = icmp ult i64 %i0, 17
77   %i1 = select i1 %icmp1, i64 %i0, i64 17
79   store i64 %i1, ptr addrspace(1) %outgep
80   ret void
83 ; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i16:
84 ; SI: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
85 ; VI: v_max_u16_e32 [[MAX:v[0-9]]], 12, {{v[0-9]}}
86 ; VI: v_min_u16_e32 {{v[0-9]}}, 17, [[MAX]]
87 ; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
88 define amdgpu_kernel void @v_test_umed3_r_i_i_i16(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
89   %tid = call i32 @llvm.amdgcn.workitem.id.x()
90   %gep0 = getelementptr i16, ptr addrspace(1) %aptr, i32 %tid
91   %outgep = getelementptr i16, ptr addrspace(1) %out, i32 %tid
92   %a = load i16, ptr addrspace(1) %gep0
94   %icmp0 = icmp ugt i16 %a, 12
95   %i0 = select i1 %icmp0, i16 %a, i16 12
97   %icmp1 = icmp ult i16 %i0, 17
98   %i1 = select i1 %icmp1, i16 %i0, i16 17
100   store i16 %i1, ptr addrspace(1) %outgep
101   ret void
104 define internal i32 @umin(i32 %x, i32 %y) #2 {
105   %cmp = icmp ult i32 %x, %y
106   %sel = select i1 %cmp, i32 %x, i32 %y
107   ret i32 %sel
110 define internal i32 @umax(i32 %x, i32 %y) #2 {
111   %cmp = icmp ugt i32 %x, %y
112   %sel = select i1 %cmp, i32 %x, i32 %y
113   ret i32 %sel
116 define internal i16 @umin16(i16 %x, i16 %y) #2 {
117   %cmp = icmp ult i16 %x, %y
118   %sel = select i1 %cmp, i16 %x, i16 %y
119   ret i16 %sel
122 define internal i16 @umax16(i16 %x, i16 %y) #2 {
123   %cmp = icmp ugt i16 %x, %y
124   %sel = select i1 %cmp, i16 %x, i16 %y
125   ret i16 %sel
128 define internal i8 @umin8(i8 %x, i8 %y) #2 {
129   %cmp = icmp ult i8 %x, %y
130   %sel = select i1 %cmp, i8 %x, i8 %y
131   ret i8 %sel
134 define internal i8 @umax8(i8 %x, i8 %y) #2 {
135   %cmp = icmp ugt i8 %x, %y
136   %sel = select i1 %cmp, i8 %x, i8 %y
137   ret i8 %sel
140 ; 16 combinations
142 ; 0: max(min(x, y), min(max(x, y), z))
143 ; 1: max(min(x, y), min(max(y, x), z))
144 ; 2: max(min(x, y), min(z, max(x, y)))
145 ; 3: max(min(x, y), min(z, max(y, x)))
146 ; 4: max(min(y, x), min(max(x, y), z))
147 ; 5: max(min(y, x), min(max(y, x), z))
148 ; 6: max(min(y, x), min(z, max(x, y)))
149 ; 7: max(min(y, x), min(z, max(y, x)))
151 ; + commute outermost max
154 ; FIXME: In these cases we probably should have used scalar operations
155 ; instead.
157 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0:
158 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
159 define amdgpu_kernel void @s_test_umed3_i32_pat_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
161   %tmp0 = call i32 @umin(i32 %x, i32 %y)
162   %tmp1 = call i32 @umax(i32 %x, i32 %y)
163   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
164   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
165   store i32 %tmp3, ptr addrspace(1) %arg
166   ret void
169 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_1:
170 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
171 define amdgpu_kernel void @s_test_umed3_i32_pat_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
173   %tmp0 = call i32 @umin(i32 %x, i32 %y)
174   %tmp1 = call i32 @umax(i32 %y, i32 %x)
175   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
176   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
177   store i32 %tmp3, ptr addrspace(1) %arg
178   ret void
181 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_2:
182 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
183 define amdgpu_kernel void @s_test_umed3_i32_pat_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
185   %tmp0 = call i32 @umin(i32 %x, i32 %y)
186   %tmp1 = call i32 @umax(i32 %x, i32 %y)
187   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
188   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
189   store i32 %tmp3, ptr addrspace(1) %arg
190   ret void
193 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_3:
194 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
195 define amdgpu_kernel void @s_test_umed3_i32_pat_3(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
197   %tmp0 = call i32 @umin(i32 %x, i32 %y)
198   %tmp1 = call i32 @umax(i32 %y, i32 %x)
199   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
200   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
201   store i32 %tmp3, ptr addrspace(1) %arg
202   ret void
205 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_4:
206 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
207 define amdgpu_kernel void @s_test_umed3_i32_pat_4(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
209   %tmp0 = call i32 @umin(i32 %y, i32 %x)
210   %tmp1 = call i32 @umax(i32 %x, i32 %y)
211   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
212   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
213   store i32 %tmp3, ptr addrspace(1) %arg
214   ret void
217 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_5:
218 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
219 define amdgpu_kernel void @s_test_umed3_i32_pat_5(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
221   %tmp0 = call i32 @umin(i32 %y, i32 %x)
222   %tmp1 = call i32 @umax(i32 %y, i32 %x)
223   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
224   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
225   store i32 %tmp3, ptr addrspace(1) %arg
226   ret void
229 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_6:
230 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
231 define amdgpu_kernel void @s_test_umed3_i32_pat_6(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
233   %tmp0 = call i32 @umin(i32 %y, i32 %x)
234   %tmp1 = call i32 @umax(i32 %x, i32 %y)
235   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
236   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
237   store i32 %tmp3, ptr addrspace(1) %arg
238   ret void
241 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_7:
242 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
243 define amdgpu_kernel void @s_test_umed3_i32_pat_7(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
245   %tmp0 = call i32 @umin(i32 %y, i32 %x)
246   %tmp1 = call i32 @umax(i32 %y, i32 %x)
247   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
248   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
249   store i32 %tmp3, ptr addrspace(1) %arg
250   ret void
253 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_8:
254 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
255 define amdgpu_kernel void @s_test_umed3_i32_pat_8(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
257   %tmp0 = call i32 @umin(i32 %x, i32 %y)
258   %tmp1 = call i32 @umax(i32 %x, i32 %y)
259   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
260   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
261   store i32 %tmp3, ptr addrspace(1) %arg
262   ret void
265 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_9:
266 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
267 define amdgpu_kernel void @s_test_umed3_i32_pat_9(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
269   %tmp0 = call i32 @umin(i32 %x, i32 %y)
270   %tmp1 = call i32 @umax(i32 %y, i32 %x)
271   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
272   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
273   store i32 %tmp3, ptr addrspace(1) %arg
274   ret void
277 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_10:
278 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
279 define amdgpu_kernel void @s_test_umed3_i32_pat_10(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
281   %tmp0 = call i32 @umin(i32 %x, i32 %y)
282   %tmp1 = call i32 @umax(i32 %x, i32 %y)
283   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
284   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
285   store i32 %tmp3, ptr addrspace(1) %arg
286   ret void
289 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_11:
290 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
291 define amdgpu_kernel void @s_test_umed3_i32_pat_11(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
293   %tmp0 = call i32 @umin(i32 %x, i32 %y)
294   %tmp1 = call i32 @umax(i32 %y, i32 %x)
295   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
296   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
297   store i32 %tmp3, ptr addrspace(1) %arg
298   ret void
301 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_12:
302 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
303 define amdgpu_kernel void @s_test_umed3_i32_pat_12(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
305   %tmp0 = call i32 @umin(i32 %y, i32 %x)
306   %tmp1 = call i32 @umax(i32 %x, i32 %y)
307   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
308   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
309   store i32 %tmp3, ptr addrspace(1) %arg
310   ret void
313 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_13:
314 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
315 define amdgpu_kernel void @s_test_umed3_i32_pat_13(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
317   %tmp0 = call i32 @umin(i32 %y, i32 %x)
318   %tmp1 = call i32 @umax(i32 %y, i32 %x)
319   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
320   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
321   store i32 %tmp3, ptr addrspace(1) %arg
322   ret void
325 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_14:
326 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
327 define amdgpu_kernel void @s_test_umed3_i32_pat_14(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
329   %tmp0 = call i32 @umin(i32 %y, i32 %x)
330   %tmp1 = call i32 @umax(i32 %x, i32 %y)
331   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
332   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
333   store i32 %tmp3, ptr addrspace(1) %arg
334   ret void
337 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_15:
338 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
339 define amdgpu_kernel void @s_test_umed3_i32_pat_15(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
341   %tmp0 = call i32 @umin(i32 %y, i32 %x)
342   %tmp1 = call i32 @umax(i32 %y, i32 %x)
343   %tmp2 = call i32 @umin(i32 %z, i32 %tmp1)
344   %tmp3 = call i32 @umax(i32 %tmp2, i32 %tmp0)
345   store i32 %tmp3, ptr addrspace(1) %arg
346   ret void
349 ; 16 combinations
351 ; 16: min(max(x, y), max(min(x, y), z))
352 ; 17: min(max(x, y), max(min(y, x), z))
353 ; 18: min(max(x, y), max(z, min(x, y)))
354 ; 19: min(max(x, y), max(z, min(y, x)))
355 ; 20: min(max(y, x), max(min(x, y), z))
356 ; 21: min(max(y, x), max(min(y, x), z))
357 ; 22: min(max(y, x), max(z, min(x, y)))
358 ; 23: min(max(y, x), max(z, min(y, x)))
360 ; + commute outermost min
363 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_16:
364 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
365 define amdgpu_kernel void @s_test_umed3_i32_pat_16(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
367   %tmp0 = call i32 @umin(i32 %x, i32 %y)
368   %tmp1 = call i32 @umax(i32 %x, i32 %y)
369   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
370   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
371   store i32 %tmp3, ptr addrspace(1) %arg
372   ret void
375 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_17:
376 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
377 define amdgpu_kernel void @s_test_umed3_i32_pat_17(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
379   %tmp0 = call i32 @umin(i32 %y, i32 %x)
380   %tmp1 = call i32 @umax(i32 %x, i32 %y)
381   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
382   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
383   store i32 %tmp3, ptr addrspace(1) %arg
384   ret void
387 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_18:
388 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
389 define amdgpu_kernel void @s_test_umed3_i32_pat_18(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
391   %tmp0 = call i32 @umin(i32 %x, i32 %y)
392   %tmp1 = call i32 @umax(i32 %x, i32 %y)
393   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
394   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
395   store i32 %tmp3, ptr addrspace(1) %arg
396   ret void
399 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_19:
400 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
401 define amdgpu_kernel void @s_test_umed3_i32_pat_19(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
403   %tmp0 = call i32 @umin(i32 %y, i32 %x)
404   %tmp1 = call i32 @umax(i32 %x, i32 %y)
405   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
406   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
407   store i32 %tmp3, ptr addrspace(1) %arg
408   ret void
411 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_20:
412 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
413 define amdgpu_kernel void @s_test_umed3_i32_pat_20(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
415   %tmp0 = call i32 @umin(i32 %x, i32 %y)
416   %tmp1 = call i32 @umax(i32 %y, i32 %x)
417   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
418   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
419   store i32 %tmp3, ptr addrspace(1) %arg
420   ret void
423 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_21:
424 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
425 define amdgpu_kernel void @s_test_umed3_i32_pat_21(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
427   %tmp0 = call i32 @umin(i32 %y, i32 %x)
428   %tmp1 = call i32 @umax(i32 %y, i32 %x)
429   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
430   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
431   store i32 %tmp3, ptr addrspace(1) %arg
432   ret void
435 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_22:
436 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
437 define amdgpu_kernel void @s_test_umed3_i32_pat_22(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
439   %tmp0 = call i32 @umin(i32 %x, i32 %y)
440   %tmp1 = call i32 @umax(i32 %y, i32 %x)
441   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
442   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
443   store i32 %tmp3, ptr addrspace(1) %arg
444   ret void
447 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_23:
448 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
449 define amdgpu_kernel void @s_test_umed3_i32_pat_23(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
451   %tmp0 = call i32 @umin(i32 %y, i32 %x)
452   %tmp1 = call i32 @umax(i32 %y, i32 %x)
453   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
454   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
455   store i32 %tmp3, ptr addrspace(1) %arg
456   ret void
459 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_24:
460 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
461 define amdgpu_kernel void @s_test_umed3_i32_pat_24(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
463   %tmp0 = call i32 @umin(i32 %x, i32 %y)
464   %tmp1 = call i32 @umax(i32 %x, i32 %y)
465   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
466   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
467   store i32 %tmp3, ptr addrspace(1) %arg
468   ret void
471 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_25:
472 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
473 define amdgpu_kernel void @s_test_umed3_i32_pat_25(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
475   %tmp0 = call i32 @umin(i32 %y, i32 %x)
476   %tmp1 = call i32 @umax(i32 %x, i32 %y)
477   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
478   %tmp3 = call i32 @umin(i32 %tmp1, i32 %tmp2)
479   store i32 %tmp3, ptr addrspace(1) %arg
480   ret void
483 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_26:
484 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
485 define amdgpu_kernel void @s_test_umed3_i32_pat_26(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
487   %tmp0 = call i32 @umin(i32 %x, i32 %y)
488   %tmp1 = call i32 @umax(i32 %x, i32 %y)
489   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
490   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
491   store i32 %tmp3, ptr addrspace(1) %arg
492   ret void
495 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_27:
496 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
497 define amdgpu_kernel void @s_test_umed3_i32_pat_27(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
499   %tmp0 = call i32 @umin(i32 %y, i32 %x)
500   %tmp1 = call i32 @umax(i32 %x, i32 %y)
501   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
502   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
503   store i32 %tmp3, ptr addrspace(1) %arg
504   ret void
507 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_28:
508 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
509 define amdgpu_kernel void @s_test_umed3_i32_pat_28(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
511   %tmp0 = call i32 @umin(i32 %x, i32 %y)
512   %tmp1 = call i32 @umax(i32 %y, i32 %x)
513   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
514   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
515   store i32 %tmp3, ptr addrspace(1) %arg
516   ret void
519 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_29:
520 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
521 define amdgpu_kernel void @s_test_umed3_i32_pat_29(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
523   %tmp0 = call i32 @umin(i32 %y, i32 %x)
524   %tmp1 = call i32 @umax(i32 %y, i32 %x)
525   %tmp2 = call i32 @umax(i32 %tmp0, i32 %z)
526   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
527   store i32 %tmp3, ptr addrspace(1) %arg
528   ret void
531 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_30:
532 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
533 define amdgpu_kernel void @s_test_umed3_i32_pat_30(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
535   %tmp0 = call i32 @umin(i32 %x, i32 %y)
536   %tmp1 = call i32 @umax(i32 %y, i32 %x)
537   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
538   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
539   store i32 %tmp3, ptr addrspace(1) %arg
540   ret void
543 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_31:
544 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
545 define amdgpu_kernel void @s_test_umed3_i32_pat_31(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
547   %tmp0 = call i32 @umin(i32 %y, i32 %x)
548   %tmp1 = call i32 @umax(i32 %y, i32 %x)
549   %tmp2 = call i32 @umax(i32 %z, i32 %tmp0)
550   %tmp3 = call i32 @umin(i32 %tmp2, i32 %tmp1)
551   store i32 %tmp3, ptr addrspace(1) %arg
552   ret void
555 ; GCN-LABEL: {{^}}s_test_umed3_i16_pat_0:
556 ; GCN: s_and_b32
557 ; GCN: s_and_b32
558 ; GCN: s_and_b32
559 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
560 define 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 {
562   %tmp0 = call i16 @umin16(i16 %x, i16 %y)
563   %tmp1 = call i16 @umax16(i16 %x, i16 %y)
564   %tmp2 = call i16 @umin16(i16 %tmp1, i16 %z)
565   %tmp3 = call i16 @umax16(i16 %tmp0, i16 %tmp2)
566   store i16 %tmp3, ptr addrspace(1) %arg
567   ret void
570 ; GCN-LABEL: {{^}}s_test_umed3_i8_pat_0:
571 ; GCN: s_and_b32
572 ; GCN: s_and_b32
573 ; GCN: s_and_b32
574 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
575 define 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 {
577   %tmp0 = call i8 @umin8(i8 %x, i8 %y)
578   %tmp1 = call i8 @umax8(i8 %x, i8 %y)
579   %tmp2 = call i8 @umin8(i8 %tmp1, i8 %z)
580   %tmp3 = call i8 @umax8(i8 %tmp0, i8 %tmp2)
581   store i8 %tmp3, ptr addrspace(1) %arg
582   ret void
585 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_0:
586 ; GCN: s_min_u32
587 ; GCN-NOT: {{s_min_u32|s_max_u32}}
588 ; GCN: v_med3_u32
589 define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
591   %tmp0 = call i32 @umin(i32 %x, i32 %y)
592   %tmp1 = call i32 @umax(i32 %x, i32 %y)
593   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
594   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
595   store volatile i32 %tmp0, ptr addrspace(1) %arg
596   store volatile i32 %tmp3, ptr addrspace(1) %arg
597   ret void
600 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_1:
601 ; GCN: s_max_u32
602 ; GCN-NOT: {{s_min_u32|s_max_u32}}
603 ; GCN: v_med3_u32
604 define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
606   %tmp0 = call i32 @umin(i32 %x, i32 %y)
607   %tmp1 = call i32 @umax(i32 %x, i32 %y)
608   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
609   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
610   store volatile i32 %tmp1, ptr addrspace(1) %arg
611   store volatile i32 %tmp3, ptr addrspace(1) %arg
612   ret void
615 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_2:
616 ; GCN: s_max_u32
617 ; GCN: s_min_u32
618 ; GCN-NOT: {{s_min_u32|s_max_u32}}
619 ; GCN: v_med3_u32
620 define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
622   %tmp0 = call i32 @umin(i32 %x, i32 %y)
623   %tmp1 = call i32 @umax(i32 %x, i32 %y)
624   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
625   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
626   store volatile i32 %tmp2, ptr addrspace(1) %arg
627   store volatile i32 %tmp3, ptr addrspace(1) %arg
628   ret void
631 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_result:
632 ; GCN-NOT: {{s_min_u32|s_max_u32}}
633 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
634 define amdgpu_kernel void @s_test_umed3_i32_pat_0_multi_use_result(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
636   %tmp0 = call i32 @umin(i32 %x, i32 %y)
637   %tmp1 = call i32 @umax(i32 %x, i32 %y)
638   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
639   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
640   store volatile i32 %tmp3, ptr addrspace(1) %arg
641   store volatile i32 %tmp3, ptr addrspace(1) %arg
642   ret void
645 ; GCN-LABEL: {{^}}s_test_smed3_reuse_bounds
646 ; GCN-NOT: {{s_min_u32|s_max_u32}}
647 ; GCN: v_med3_u32 v{{[0-9]+}}, [[B0:s[0-9]+]], [[B1:v[0-9]+]], v{{[0-9]+}}
648 ; GCN: v_med3_u32 v{{[0-9]+}}, [[B0]], [[B1]], v{{[0-9]+}}
649 define amdgpu_kernel void @s_test_smed3_reuse_bounds(ptr addrspace(1) %arg, i32 %b0, i32 %b1, i32 %x, i32 %y) #1 {
651   %lo = call i32 @umin(i32 %b0, i32 %b1)
652   %hi = call i32 @umax(i32 %b0, i32 %b1)
654   %tmp0 = call i32 @umin(i32 %x, i32 %hi)
655   %z0 = call i32 @umax(i32 %tmp0, i32 %lo)
657   %tmp1 = call i32 @umin(i32 %y, i32 %hi)
658   %z1 = call i32 @umax(i32 %tmp1, i32 %lo)
660   store volatile i32 %z0, ptr addrspace(1) %arg
661   store volatile i32 %z1, ptr addrspace(1) %arg
662   ret void
665 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src0:
666 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, 1, v{{[0-9]+}}
667 define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
669   %tmp0 = call i32 @umin(i32 1, i32 %y)
670   %tmp1 = call i32 @umax(i32 1, i32 %y)
671   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
672   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
673   store i32 %tmp3, ptr addrspace(1) %arg
674   ret void
677 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src1:
678 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, 2, v{{[0-9]+}}
679 define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
681   %tmp0 = call i32 @umin(i32 %x, i32 2)
682   %tmp1 = call i32 @umax(i32 %x, i32 2)
683   %tmp2 = call i32 @umin(i32 %tmp1, i32 %z)
684   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
685   store i32 %tmp3, ptr addrspace(1) %arg
686   ret void
689 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_imm_src2:
690 ; GCN: v_med3_u32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, 9
691 define amdgpu_kernel void @s_test_umed3_i32_pat_0_imm_src2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
693   %tmp0 = call i32 @umin(i32 %x, i32 %y)
694   %tmp1 = call i32 @umax(i32 %x, i32 %y)
695   %tmp2 = call i32 @umin(i32 %tmp1, i32 9)
696   %tmp3 = call i32 @umax(i32 %tmp0, i32 %tmp2)
697   store i32 %tmp3, ptr addrspace(1) %arg
698   ret void
701 ; GCN-LABEL: {{^}}v_test_umed3_i16_pat_0:
702 ; SI: v_med3_u32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
704 ; FIXME: VI not matching med3
705 ; VI: v_min_u16
706 ; VI: v_max_u16
707 ; VI: v_min_u16
708 ; VI: v_max_u16
710 ; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
711 define amdgpu_kernel void @v_test_umed3_i16_pat_0(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
713   %tid = call i32 @llvm.amdgcn.workitem.id.x()
714   %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
715   %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
716   %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
717   %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
718   %x = load i16, ptr addrspace(1) %gep0
719   %y = load i16, ptr addrspace(1) %gep1
720   %z = load i16, ptr addrspace(1) %gep2
722   %tmp0 = call i16 @umin16(i16 %x, i16 %y)
723   %tmp1 = call i16 @umax16(i16 %x, i16 %y)
724   %tmp2 = call i16 @umin16(i16 %tmp1, i16 %z)
725   %tmp3 = call i16 @umax16(i16 %tmp0, i16 %tmp2)
726   store i16 %tmp3, ptr addrspace(1) %out.gep
727   ret void
730 ; GCN-LABEL: {{^}}v_test_umed3_i16_pat_1:
731 ; GFX9: v_med3_u16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
732 define amdgpu_kernel void @v_test_umed3_i16_pat_1(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
734   %tid = call i32 @llvm.amdgcn.workitem.id.x()
735   %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
736   %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
737   %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
738   %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
739   %x = load i16, ptr addrspace(1) %gep0
740   %y = load i16, ptr addrspace(1) %gep1
741   %z = load i16, ptr addrspace(1) %gep2
743   %tmp0 = call i16 @umin16(i16 %x, i16 %y)
744   %tmp1 = call i16 @umax16(i16 %x, i16 %y)
745   %tmp2 = call i16 @umax16(i16 %tmp0, i16 %z)
746   %tmp3 = call i16 @umin16(i16 %tmp1, i16 %tmp2)
747   store i16 %tmp3, ptr addrspace(1) %out.gep
748   ret void
751 attributes #0 = { nounwind readnone }
752 attributes #1 = { nounwind }
753 attributes #2 = { nounwind readnone alwaysinline }