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
25 ; GCN-LABEL: {{^}}v_test_umed3_multi_use_r_i_i_i32:
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
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
64 ; GCN-LABEL: {{^}}v_test_umed3_r_i_i_i64:
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
555 ; GCN-LABEL: {{^}}s_test_umed3_i16_pat_0:
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
570 ; GCN-LABEL: {{^}}s_test_umed3_i8_pat_0:
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
585 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_0:
587 ; GCN-NOT: {{s_min_u32|s_max_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
600 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_1:
602 ; GCN-NOT: {{s_min_u32|s_max_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
615 ; GCN-LABEL: {{^}}s_test_umed3_i32_pat_0_multi_use_2:
618 ; GCN-NOT: {{s_min_u32|s_max_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
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
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
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
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
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
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
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
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
751 attributes #0 = { nounwind readnone }
752 attributes #1 = { nounwind }
753 attributes #2 = { nounwind readnone alwaysinline }