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-prefixes=GFX11-FAKE16 %s
5 ; RUN: llc -mtriple=amdgcn -mcpu=gfx1100 -mattr=-flat-for-global,+real-true16 -verify-machineinstrs < %s | FileCheck -check-prefixes=GFX11-TRUE16 %s
7 declare i32 @llvm.amdgcn.workitem.id.x() #0
9 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i32:
10 ; GCN: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
11 define amdgpu_kernel void @v_test_smed3_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
17 %icmp0 = icmp sgt i32 %a, 12
18 %i0 = select i1 %icmp0, i32 %a, i32 12
20 %icmp1 = icmp slt i32 %i0, 17
21 %i1 = select i1 %icmp1, i32 %i0, i32 17
23 store i32 %i1, ptr addrspace(1) %outgep
27 ; GCN-LABEL: {{^}}v_test_smed3_multi_use_r_i_i_i32:
30 define amdgpu_kernel void @v_test_smed3_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
36 %icmp0 = icmp sgt i32 %a, 12
37 %i0 = select i1 %icmp0, i32 %a, i32 12
39 %icmp1 = icmp slt i32 %i0, 17
40 %i1 = select i1 %icmp1, i32 %i0, i32 17
42 store volatile i32 %i0, ptr addrspace(1) %outgep
43 store volatile i32 %i1, ptr addrspace(1) %outgep
47 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_sign_mismatch_i32:
48 ; GCN: v_max_u32_e32 v{{[0-9]+}}, 12, v{{[0-9]+}}
49 ; GCN: v_min_i32_e32 v{{[0-9]+}}, 17, v{{[0-9]+}}
50 define amdgpu_kernel void @v_test_smed3_r_i_i_sign_mismatch_i32(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
51 %tid = call i32 @llvm.amdgcn.workitem.id.x()
52 %gep0 = getelementptr i32, ptr addrspace(1) %aptr, i32 %tid
53 %outgep = getelementptr i32, ptr addrspace(1) %out, i32 %tid
54 %a = load i32, ptr addrspace(1) %gep0
56 %icmp0 = icmp ugt i32 %a, 12
57 %i0 = select i1 %icmp0, i32 %a, i32 12
59 %icmp1 = icmp slt i32 %i0, 17
60 %i1 = select i1 %icmp1, i32 %i0, i32 17
62 store i32 %i1, ptr addrspace(1) %outgep
66 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i64:
69 define amdgpu_kernel void @v_test_smed3_r_i_i_i64(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
70 %tid = call i32 @llvm.amdgcn.workitem.id.x()
71 %gep0 = getelementptr i64, ptr addrspace(1) %aptr, i32 %tid
72 %outgep = getelementptr i64, ptr addrspace(1) %out, i32 %tid
73 %a = load i64, ptr addrspace(1) %gep0
75 %icmp0 = icmp sgt i64 %a, 12
76 %i0 = select i1 %icmp0, i64 %a, i64 12
78 %icmp1 = icmp slt i64 %i0, 17
79 %i1 = select i1 %icmp1, i64 %i0, i64 17
81 store i64 %i1, ptr addrspace(1) %outgep
85 ; Regression test for performIntMed3ImmCombine extending arguments to 32 bit
86 ; which failed for 64 bit arguments. Previously asserted / crashed.
87 ; GCN-LABEL: {{^}}test_intMed3ImmCombine_no_32bit_extend:
90 define i64 @test_intMed3ImmCombine_no_32bit_extend(i64 %x) {
91 %smax = call i64 @llvm.smax.i64(i64 %x, i64 -2)
92 %smin = call i64 @llvm.smin.i64(i64 %smax, i64 2)
95 declare i64 @llvm.smax.i64(i64, i64)
96 declare i64 @llvm.smin.i64(i64, i64)
98 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i16:
99 ; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
100 ; VI: v_max_i16_e32 [[MAX:v[0-9]]], 12, {{v[0-9]}}
101 ; VI: v_min_i16_e32 {{v[0-9]}}, 17, [[MAX]]
102 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
103 ; GFX11-TRUE16: v_med3_i16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, 12, 17
104 ; GFX11-FAKE16: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
105 define amdgpu_kernel void @v_test_smed3_r_i_i_i16(ptr addrspace(1) %out, ptr addrspace(1) %aptr) #1 {
106 %tid = call i32 @llvm.amdgcn.workitem.id.x()
107 %gep0 = getelementptr i16, ptr addrspace(1) %aptr, i32 %tid
108 %outgep = getelementptr i16, ptr addrspace(1) %out, i32 %tid
109 %a = load i16, ptr addrspace(1) %gep0
111 %icmp0 = icmp sgt i16 %a, 12
112 %i0 = select i1 %icmp0, i16 %a, i16 12
114 %icmp1 = icmp slt i16 %i0, 17
115 %i1 = select i1 %icmp1, i16 %i0, i16 17
117 store i16 %i1, ptr addrspace(1) %outgep
122 define internal i32 @smin(i32 %x, i32 %y) #2 {
123 %cmp = icmp slt i32 %x, %y
124 %sel = select i1 %cmp, i32 %x, i32 %y
128 define internal i32 @smax(i32 %x, i32 %y) #2 {
129 %cmp = icmp sgt i32 %x, %y
130 %sel = select i1 %cmp, i32 %x, i32 %y
134 define internal i16 @smin16(i16 %x, i16 %y) #2 {
135 %cmp = icmp slt i16 %x, %y
136 %sel = select i1 %cmp, i16 %x, i16 %y
140 define internal i16 @smax16(i16 %x, i16 %y) #2 {
141 %cmp = icmp sgt i16 %x, %y
142 %sel = select i1 %cmp, i16 %x, i16 %y
146 define internal i8 @smin8(i8 %x, i8 %y) #2 {
147 %cmp = icmp slt i8 %x, %y
148 %sel = select i1 %cmp, i8 %x, i8 %y
152 define internal i8 @smax8(i8 %x, i8 %y) #2 {
153 %cmp = icmp sgt i8 %x, %y
154 %sel = select i1 %cmp, i8 %x, i8 %y
160 ; 0: max(min(x, y), min(max(x, y), z))
161 ; 1: max(min(x, y), min(max(y, x), z))
162 ; 2: max(min(x, y), min(z, max(x, y)))
163 ; 3: max(min(x, y), min(z, max(y, x)))
164 ; 4: max(min(y, x), min(max(x, y), z))
165 ; 5: max(min(y, x), min(max(y, x), z))
166 ; 6: max(min(y, x), min(z, max(x, y)))
167 ; 7: max(min(y, x), min(z, max(y, x)))
169 ; + commute outermost max
172 ; FIXME: In these cases we probably should have used scalar operations
175 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0:
176 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
177 define amdgpu_kernel void @s_test_smed3_i32_pat_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
179 %tmp0 = call i32 @smin(i32 %x, i32 %y)
180 %tmp1 = call i32 @smax(i32 %x, i32 %y)
181 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
182 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
183 store i32 %tmp3, ptr addrspace(1) %arg
187 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_1:
188 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
189 define amdgpu_kernel void @s_test_smed3_i32_pat_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
191 %tmp0 = call i32 @smin(i32 %x, i32 %y)
192 %tmp1 = call i32 @smax(i32 %y, i32 %x)
193 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
194 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
195 store i32 %tmp3, ptr addrspace(1) %arg
199 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_2:
200 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
201 define amdgpu_kernel void @s_test_smed3_i32_pat_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
203 %tmp0 = call i32 @smin(i32 %x, i32 %y)
204 %tmp1 = call i32 @smax(i32 %x, i32 %y)
205 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
206 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
207 store i32 %tmp3, ptr addrspace(1) %arg
211 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_3:
212 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
213 define amdgpu_kernel void @s_test_smed3_i32_pat_3(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
215 %tmp0 = call i32 @smin(i32 %x, i32 %y)
216 %tmp1 = call i32 @smax(i32 %y, i32 %x)
217 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
218 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
219 store i32 %tmp3, ptr addrspace(1) %arg
223 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_4:
224 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
225 define amdgpu_kernel void @s_test_smed3_i32_pat_4(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
227 %tmp0 = call i32 @smin(i32 %y, i32 %x)
228 %tmp1 = call i32 @smax(i32 %x, i32 %y)
229 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
230 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
231 store i32 %tmp3, ptr addrspace(1) %arg
235 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_5:
236 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
237 define amdgpu_kernel void @s_test_smed3_i32_pat_5(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
239 %tmp0 = call i32 @smin(i32 %y, i32 %x)
240 %tmp1 = call i32 @smax(i32 %y, i32 %x)
241 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
242 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
243 store i32 %tmp3, ptr addrspace(1) %arg
247 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_6:
248 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
249 define amdgpu_kernel void @s_test_smed3_i32_pat_6(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
251 %tmp0 = call i32 @smin(i32 %y, i32 %x)
252 %tmp1 = call i32 @smax(i32 %x, i32 %y)
253 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
254 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
255 store i32 %tmp3, ptr addrspace(1) %arg
259 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_7:
260 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
261 define amdgpu_kernel void @s_test_smed3_i32_pat_7(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
263 %tmp0 = call i32 @smin(i32 %y, i32 %x)
264 %tmp1 = call i32 @smax(i32 %y, i32 %x)
265 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
266 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
267 store i32 %tmp3, ptr addrspace(1) %arg
271 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_8:
272 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
273 define amdgpu_kernel void @s_test_smed3_i32_pat_8(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
275 %tmp0 = call i32 @smin(i32 %x, i32 %y)
276 %tmp1 = call i32 @smax(i32 %x, i32 %y)
277 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
278 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
279 store i32 %tmp3, ptr addrspace(1) %arg
283 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_9:
284 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
285 define amdgpu_kernel void @s_test_smed3_i32_pat_9(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
287 %tmp0 = call i32 @smin(i32 %x, i32 %y)
288 %tmp1 = call i32 @smax(i32 %y, i32 %x)
289 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
290 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
291 store i32 %tmp3, ptr addrspace(1) %arg
295 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_10:
296 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
297 define amdgpu_kernel void @s_test_smed3_i32_pat_10(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
299 %tmp0 = call i32 @smin(i32 %x, i32 %y)
300 %tmp1 = call i32 @smax(i32 %x, i32 %y)
301 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
302 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
303 store i32 %tmp3, ptr addrspace(1) %arg
307 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_11:
308 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
309 define amdgpu_kernel void @s_test_smed3_i32_pat_11(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
311 %tmp0 = call i32 @smin(i32 %x, i32 %y)
312 %tmp1 = call i32 @smax(i32 %y, i32 %x)
313 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
314 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
315 store i32 %tmp3, ptr addrspace(1) %arg
319 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_12:
320 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
321 define amdgpu_kernel void @s_test_smed3_i32_pat_12(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
323 %tmp0 = call i32 @smin(i32 %y, i32 %x)
324 %tmp1 = call i32 @smax(i32 %x, i32 %y)
325 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
326 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
327 store i32 %tmp3, ptr addrspace(1) %arg
331 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_13:
332 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
333 define amdgpu_kernel void @s_test_smed3_i32_pat_13(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
335 %tmp0 = call i32 @smin(i32 %y, i32 %x)
336 %tmp1 = call i32 @smax(i32 %y, i32 %x)
337 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
338 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
339 store i32 %tmp3, ptr addrspace(1) %arg
343 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_14:
344 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
345 define amdgpu_kernel void @s_test_smed3_i32_pat_14(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
347 %tmp0 = call i32 @smin(i32 %y, i32 %x)
348 %tmp1 = call i32 @smax(i32 %x, i32 %y)
349 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
350 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
351 store i32 %tmp3, ptr addrspace(1) %arg
355 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_15:
356 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
357 define amdgpu_kernel void @s_test_smed3_i32_pat_15(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
359 %tmp0 = call i32 @smin(i32 %y, i32 %x)
360 %tmp1 = call i32 @smax(i32 %y, i32 %x)
361 %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
362 %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
363 store i32 %tmp3, ptr addrspace(1) %arg
369 ; 16: min(max(x, y), max(min(x, y), z))
370 ; 17: min(max(x, y), max(min(y, x), z))
371 ; 18: min(max(x, y), max(z, min(x, y)))
372 ; 19: min(max(x, y), max(z, min(y, x)))
373 ; 20: min(max(y, x), max(min(x, y), z))
374 ; 21: min(max(y, x), max(min(y, x), z))
375 ; 22: min(max(y, x), max(z, min(x, y)))
376 ; 23: min(max(y, x), max(z, min(y, x)))
378 ; + commute outermost min
380 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_16:
381 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
382 define amdgpu_kernel void @s_test_smed3_i32_pat_16(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
384 %tmp0 = call i32 @smin(i32 %x, i32 %y)
385 %tmp1 = call i32 @smax(i32 %x, i32 %y)
386 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
387 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
388 store i32 %tmp3, ptr addrspace(1) %arg
392 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_17:
393 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
394 define amdgpu_kernel void @s_test_smed3_i32_pat_17(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
396 %tmp0 = call i32 @smin(i32 %y, i32 %x)
397 %tmp1 = call i32 @smax(i32 %x, i32 %y)
398 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
399 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
400 store i32 %tmp3, ptr addrspace(1) %arg
404 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_18:
405 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
406 define amdgpu_kernel void @s_test_smed3_i32_pat_18(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
408 %tmp0 = call i32 @smin(i32 %x, i32 %y)
409 %tmp1 = call i32 @smax(i32 %x, i32 %y)
410 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
411 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
412 store i32 %tmp3, ptr addrspace(1) %arg
416 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_19:
417 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
418 define amdgpu_kernel void @s_test_smed3_i32_pat_19(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
420 %tmp0 = call i32 @smin(i32 %y, i32 %x)
421 %tmp1 = call i32 @smax(i32 %x, i32 %y)
422 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
423 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
424 store i32 %tmp3, ptr addrspace(1) %arg
428 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_20:
429 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
430 define amdgpu_kernel void @s_test_smed3_i32_pat_20(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
432 %tmp0 = call i32 @smin(i32 %x, i32 %y)
433 %tmp1 = call i32 @smax(i32 %y, i32 %x)
434 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
435 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
436 store i32 %tmp3, ptr addrspace(1) %arg
440 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_21:
441 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
442 define amdgpu_kernel void @s_test_smed3_i32_pat_21(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
444 %tmp0 = call i32 @smin(i32 %y, i32 %x)
445 %tmp1 = call i32 @smax(i32 %y, i32 %x)
446 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
447 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
448 store i32 %tmp3, ptr addrspace(1) %arg
452 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_22:
453 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
454 define amdgpu_kernel void @s_test_smed3_i32_pat_22(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
456 %tmp0 = call i32 @smin(i32 %x, i32 %y)
457 %tmp1 = call i32 @smax(i32 %y, i32 %x)
458 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
459 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
460 store i32 %tmp3, ptr addrspace(1) %arg
464 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_23:
465 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
466 define amdgpu_kernel void @s_test_smed3_i32_pat_23(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
468 %tmp0 = call i32 @smin(i32 %y, i32 %x)
469 %tmp1 = call i32 @smax(i32 %y, i32 %x)
470 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
471 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
472 store i32 %tmp3, ptr addrspace(1) %arg
476 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_24:
477 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
478 define amdgpu_kernel void @s_test_smed3_i32_pat_24(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
480 %tmp0 = call i32 @smin(i32 %x, i32 %y)
481 %tmp1 = call i32 @smax(i32 %x, i32 %y)
482 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
483 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
484 store i32 %tmp3, ptr addrspace(1) %arg
488 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_25:
489 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
490 define amdgpu_kernel void @s_test_smed3_i32_pat_25(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
492 %tmp0 = call i32 @smin(i32 %y, i32 %x)
493 %tmp1 = call i32 @smax(i32 %x, i32 %y)
494 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
495 %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
496 store i32 %tmp3, ptr addrspace(1) %arg
500 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_26:
501 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
502 define amdgpu_kernel void @s_test_smed3_i32_pat_26(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
504 %tmp0 = call i32 @smin(i32 %x, i32 %y)
505 %tmp1 = call i32 @smax(i32 %x, i32 %y)
506 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
507 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
508 store i32 %tmp3, ptr addrspace(1) %arg
512 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_27:
513 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
514 define amdgpu_kernel void @s_test_smed3_i32_pat_27(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
516 %tmp0 = call i32 @smin(i32 %y, i32 %x)
517 %tmp1 = call i32 @smax(i32 %x, i32 %y)
518 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
519 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
520 store i32 %tmp3, ptr addrspace(1) %arg
524 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_28:
525 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
526 define amdgpu_kernel void @s_test_smed3_i32_pat_28(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
528 %tmp0 = call i32 @smin(i32 %x, i32 %y)
529 %tmp1 = call i32 @smax(i32 %y, i32 %x)
530 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
531 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
532 store i32 %tmp3, ptr addrspace(1) %arg
536 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_29:
537 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
538 define amdgpu_kernel void @s_test_smed3_i32_pat_29(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
540 %tmp0 = call i32 @smin(i32 %y, i32 %x)
541 %tmp1 = call i32 @smax(i32 %y, i32 %x)
542 %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
543 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
544 store i32 %tmp3, ptr addrspace(1) %arg
548 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_30:
549 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
550 define amdgpu_kernel void @s_test_smed3_i32_pat_30(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
552 %tmp0 = call i32 @smin(i32 %x, i32 %y)
553 %tmp1 = call i32 @smax(i32 %y, i32 %x)
554 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
555 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
556 store i32 %tmp3, ptr addrspace(1) %arg
560 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_31:
561 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
562 define amdgpu_kernel void @s_test_smed3_i32_pat_31(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
564 %tmp0 = call i32 @smin(i32 %y, i32 %x)
565 %tmp1 = call i32 @smax(i32 %y, i32 %x)
566 %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
567 %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
568 store i32 %tmp3, ptr addrspace(1) %arg
572 ; FIXME: Should keep scalar or not promote
573 ; GCN-LABEL: {{^}}s_test_smed3_i16_pat_0:
574 ; GCN: s_sext_i32_i16
575 ; GCN: s_sext_i32_i16
576 ; GCN: s_sext_i32_i16
577 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
578 define amdgpu_kernel void @s_test_smed3_i16_pat_0(ptr addrspace(1) %arg, [8 x i32], i16 %x, [8 x i32], i16 %y, [8 x i32], i16 %z) #1 {
580 %tmp0 = call i16 @smin16(i16 %x, i16 %y)
581 %tmp1 = call i16 @smax16(i16 %x, i16 %y)
582 %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
583 %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
584 store i16 %tmp3, ptr addrspace(1) %arg
588 ; GCN-LABEL: {{^}}s_test_smed3_i8_pat_0:
592 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
593 define amdgpu_kernel void @s_test_smed3_i8_pat_0(ptr addrspace(1) %arg, [8 x i32], i8 %x, [8 x i32], i8 %y, [8 x i32], i8 %z) #1 {
595 %tmp0 = call i8 @smin8(i8 %x, i8 %y)
596 %tmp1 = call i8 @smax8(i8 %x, i8 %y)
597 %tmp2 = call i8 @smin8(i8 %tmp1, i8 %z)
598 %tmp3 = call i8 @smax8(i8 %tmp0, i8 %tmp2)
599 store i8 %tmp3, ptr addrspace(1) %arg
603 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
605 ; GCN-NOT: {{s_min_i32|s_max_i32}}
607 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_0(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
609 %tmp0 = call i32 @smin(i32 %x, i32 %y)
610 %tmp1 = call i32 @smax(i32 %x, i32 %y)
611 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
612 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
613 store volatile i32 %tmp0, ptr addrspace(1) %arg
614 store volatile i32 %tmp3, ptr addrspace(1) %arg
618 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_1:
620 ; GCN-NOT: {{s_min_i32|s_max_i32}}
622 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_1(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
624 %tmp0 = call i32 @smin(i32 %x, i32 %y)
625 %tmp1 = call i32 @smax(i32 %x, i32 %y)
626 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
627 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
628 store volatile i32 %tmp1, ptr addrspace(1) %arg
629 store volatile i32 %tmp3, ptr addrspace(1) %arg
633 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_2:
636 ; GCN-NOT: {{s_min_i32|s_max_i32}}
638 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_2(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
640 %tmp0 = call i32 @smin(i32 %x, i32 %y)
641 %tmp1 = call i32 @smax(i32 %x, i32 %y)
642 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
643 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
644 store volatile i32 %tmp2, ptr addrspace(1) %arg
645 store volatile i32 %tmp3, ptr addrspace(1) %arg
649 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_result:
650 ; GCN-NOT: {{s_min_i32|s_max_i32}}
651 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
652 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_result(ptr addrspace(1) %arg, i32 %x, i32 %y, i32 %z) #1 {
654 %tmp0 = call i32 @smin(i32 %x, i32 %y)
655 %tmp1 = call i32 @smax(i32 %x, i32 %y)
656 %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
657 %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
658 store volatile i32 %tmp3, ptr addrspace(1) %arg
659 store volatile i32 %tmp3, ptr addrspace(1) %arg
663 ; GCN-LABEL: {{^}}s_test_smed3_reuse_bounds
664 ; GCN-NOT: {{s_min_i32|s_max_i32}}
665 ; GCN: v_med3_i32 v{{[0-9]+}}, [[B0:s[0-9]+]], [[B1:v[0-9]+]], v{{[0-9]+}}
666 ; GCN: v_med3_i32 v{{[0-9]+}}, [[B0]], [[B1]], v{{[0-9]+}}
667 define amdgpu_kernel void @s_test_smed3_reuse_bounds(ptr addrspace(1) %arg, i32 %b0, i32 %b1, i32 %x, i32 %y) #1 {
669 %lo = call i32 @smin(i32 %b0, i32 %b1)
670 %hi = call i32 @smax(i32 %b0, i32 %b1)
672 %tmp0 = call i32 @smin(i32 %x, i32 %hi)
673 %z0 = call i32 @smax(i32 %tmp0, i32 %lo)
675 %tmp1 = call i32 @smin(i32 %y, i32 %hi)
676 %z1 = call i32 @smax(i32 %tmp1, i32 %lo)
678 store volatile i32 %z0, ptr addrspace(1) %arg
679 store volatile i32 %z1, ptr addrspace(1) %arg
683 ; GCN-LABEL: {{^}}v_test_smed3_i16_pat_0:
684 ; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
686 ; FIXME: VI not matching med3
692 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
693 ; GFX11-TRUE16: v_med3_i16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, v{{[0-9]+}}.h, v{{[0-9]+}}.l
694 ; GFX11-FAKE16: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
695 define amdgpu_kernel void @v_test_smed3_i16_pat_0(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
697 %tid = call i32 @llvm.amdgcn.workitem.id.x()
698 %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
699 %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
700 %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
701 %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
702 %x = load i16, ptr addrspace(1) %gep0
703 %y = load i16, ptr addrspace(1) %gep1
704 %z = load i16, ptr addrspace(1) %gep2
706 %tmp0 = call i16 @smin16(i16 %x, i16 %y)
707 %tmp1 = call i16 @smax16(i16 %x, i16 %y)
708 %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
709 %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
710 store i16 %tmp3, ptr addrspace(1) %out.gep
714 ; GCN-LABEL: {{^}}v_test_smed3_i16_pat_1:
715 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
716 ; GFX11-TRUE16: v_med3_i16 v{{[0-9]+}}.l, v{{[0-9]+}}.l, v{{[0-9]+}}.h, v{{[0-9]+}}.l
717 ; GFX11-FAKE16: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
719 define amdgpu_kernel void @v_test_smed3_i16_pat_1(ptr addrspace(1) %arg, ptr addrspace(1) %out, ptr addrspace(1) %a.ptr) #1 {
721 %tid = call i32 @llvm.amdgcn.workitem.id.x()
722 %gep0 = getelementptr inbounds i16, ptr addrspace(1) %a.ptr, i32 %tid
723 %gep1 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 3
724 %gep2 = getelementptr inbounds i16, ptr addrspace(1) %gep0, i32 8
725 %out.gep = getelementptr inbounds i16, ptr addrspace(1) %out, i32 %tid
726 %x = load i16, ptr addrspace(1) %gep0
727 %y = load i16, ptr addrspace(1) %gep1
728 %z = load i16, ptr addrspace(1) %gep2
730 %tmp0 = call i16 @smin16(i16 %x, i16 %y)
731 %tmp1 = call i16 @smax16(i16 %x, i16 %y)
732 %tmp2 = call i16 @smax16(i16 %tmp0, i16 %z)
733 %tmp3 = call i16 @smin16(i16 %tmp1, i16 %tmp2)
734 store i16 %tmp3, ptr addrspace(1) %out.gep
738 attributes #0 = { nounwind readnone }
739 attributes #1 = { nounwind }
740 attributes #2 = { nounwind readnone alwaysinline }