[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AMDGPU / smed3.ll
blob16aff2edba956469e6e564fa4e12be08d5b5d328
1 ; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SICIVI -check-prefix=SI %s
2 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=SICIVI -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_smed3_r_i_i_i32:
8 ; GCN: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
9 define amdgpu_kernel void @v_test_smed3_r_i_i_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr) #1 {
10   %tid = call i32 @llvm.amdgcn.workitem.id.x()
11   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
12   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
13   %a = load i32, i32 addrspace(1)* %gep0
15   %icmp0 = icmp sgt i32 %a, 12
16   %i0 = select i1 %icmp0, i32 %a, i32 12
18   %icmp1 = icmp slt i32 %i0, 17
19   %i1 = select i1 %icmp1, i32 %i0, i32 17
21   store i32 %i1, i32 addrspace(1)* %outgep
22   ret void
25 ; GCN-LABEL: {{^}}v_test_smed3_multi_use_r_i_i_i32:
26 ; GCN: v_max_i32
27 ; GCN: v_min_i32
28 define amdgpu_kernel void @v_test_smed3_multi_use_r_i_i_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr) #1 {
29   %tid = call i32 @llvm.amdgcn.workitem.id.x()
30   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
31   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
32   %a = load i32, i32 addrspace(1)* %gep0
34   %icmp0 = icmp sgt i32 %a, 12
35   %i0 = select i1 %icmp0, i32 %a, i32 12
37   %icmp1 = icmp slt i32 %i0, 17
38   %i1 = select i1 %icmp1, i32 %i0, i32 17
40   store volatile i32 %i0, i32 addrspace(1)* %outgep
41   store volatile i32 %i1, i32 addrspace(1)* %outgep
42   ret void
45 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_sign_mismatch_i32:
46 ; GCN: v_max_u32_e32 v{{[0-9]+}}, 12, v{{[0-9]+}}
47 ; GCN: v_min_i32_e32 v{{[0-9]+}}, 17, v{{[0-9]+}}
48 define amdgpu_kernel void @v_test_smed3_r_i_i_sign_mismatch_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr) #1 {
49   %tid = call i32 @llvm.amdgcn.workitem.id.x()
50   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
51   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
52   %a = load i32, i32 addrspace(1)* %gep0
54   %icmp0 = icmp ugt i32 %a, 12
55   %i0 = select i1 %icmp0, i32 %a, i32 12
57   %icmp1 = icmp slt i32 %i0, 17
58   %i1 = select i1 %icmp1, i32 %i0, i32 17
60   store i32 %i1, i32 addrspace(1)* %outgep
61   ret void
64 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i64:
65 ; GCN: v_cmp_lt_i64
66 ; GCN: v_cmp_gt_i64
67 define amdgpu_kernel void @v_test_smed3_r_i_i_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr) #1 {
68   %tid = call i32 @llvm.amdgcn.workitem.id.x()
69   %gep0 = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid
70   %outgep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid
71   %a = load i64, i64 addrspace(1)* %gep0
73   %icmp0 = icmp sgt i64 %a, 12
74   %i0 = select i1 %icmp0, i64 %a, i64 12
76   %icmp1 = icmp slt i64 %i0, 17
77   %i1 = select i1 %icmp1, i64 %i0, i64 17
79   store i64 %i1, i64 addrspace(1)* %outgep
80   ret void
83 ; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i16:
84 ; SICIVI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
85 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
86 define amdgpu_kernel void @v_test_smed3_r_i_i_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %aptr) #1 {
87   %tid = call i32 @llvm.amdgcn.workitem.id.x()
88   %gep0 = getelementptr i16, i16 addrspace(1)* %aptr, i32 %tid
89   %outgep = getelementptr i16, i16 addrspace(1)* %out, i32 %tid
90   %a = load i16, i16 addrspace(1)* %gep0
92   %icmp0 = icmp sgt i16 %a, 12
93   %i0 = select i1 %icmp0, i16 %a, i16 12
95   %icmp1 = icmp slt i16 %i0, 17
96   %i1 = select i1 %icmp1, i16 %i0, i16 17
98   store i16 %i1, i16 addrspace(1)* %outgep
99   ret void
103 define internal i32 @smin(i32 %x, i32 %y) #2 {
104   %cmp = icmp slt i32 %x, %y
105   %sel = select i1 %cmp, i32 %x, i32 %y
106   ret i32 %sel
109 define internal i32 @smax(i32 %x, i32 %y) #2 {
110   %cmp = icmp sgt i32 %x, %y
111   %sel = select i1 %cmp, i32 %x, i32 %y
112   ret i32 %sel
115 define internal i16 @smin16(i16 %x, i16 %y) #2 {
116   %cmp = icmp slt i16 %x, %y
117   %sel = select i1 %cmp, i16 %x, i16 %y
118   ret i16 %sel
121 define internal i16 @smax16(i16 %x, i16 %y) #2 {
122   %cmp = icmp sgt i16 %x, %y
123   %sel = select i1 %cmp, i16 %x, i16 %y
124   ret i16 %sel
127 define internal i8 @smin8(i8 %x, i8 %y) #2 {
128   %cmp = icmp slt i8 %x, %y
129   %sel = select i1 %cmp, i8 %x, i8 %y
130   ret i8 %sel
133 define internal i8 @smax8(i8 %x, i8 %y) #2 {
134   %cmp = icmp sgt i8 %x, %y
135   %sel = select i1 %cmp, i8 %x, i8 %y
136   ret i8 %sel
139 ; 16 combinations
141 ; 0: max(min(x, y), min(max(x, y), z))
142 ; 1: max(min(x, y), min(max(y, x), z))
143 ; 2: max(min(x, y), min(z, max(x, y)))
144 ; 3: max(min(x, y), min(z, max(y, x)))
145 ; 4: max(min(y, x), min(max(x, y), z))
146 ; 5: max(min(y, x), min(max(y, x), z))
147 ; 6: max(min(y, x), min(z, max(x, y)))
148 ; 7: max(min(y, x), min(z, max(y, x)))
150 ; + commute outermost max
153 ; FIXME: In these cases we probably should have used scalar operations
154 ; instead.
156 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0:
157 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
158 define amdgpu_kernel void @s_test_smed3_i32_pat_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
160   %tmp0 = call i32 @smin(i32 %x, i32 %y)
161   %tmp1 = call i32 @smax(i32 %x, i32 %y)
162   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
163   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
164   store i32 %tmp3, i32 addrspace(1)* %arg
165   ret void
168 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_1:
169 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
170 define amdgpu_kernel void @s_test_smed3_i32_pat_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
172   %tmp0 = call i32 @smin(i32 %x, i32 %y)
173   %tmp1 = call i32 @smax(i32 %y, i32 %x)
174   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
175   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
176   store i32 %tmp3, i32 addrspace(1)* %arg
177   ret void
180 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_2:
181 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
182 define amdgpu_kernel void @s_test_smed3_i32_pat_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
184   %tmp0 = call i32 @smin(i32 %x, i32 %y)
185   %tmp1 = call i32 @smax(i32 %x, i32 %y)
186   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
187   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
188   store i32 %tmp3, i32 addrspace(1)* %arg
189   ret void
192 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_3:
193 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
194 define amdgpu_kernel void @s_test_smed3_i32_pat_3(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
196   %tmp0 = call i32 @smin(i32 %x, i32 %y)
197   %tmp1 = call i32 @smax(i32 %y, i32 %x)
198   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
199   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
200   store i32 %tmp3, i32 addrspace(1)* %arg
201   ret void
204 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_4:
205 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
206 define amdgpu_kernel void @s_test_smed3_i32_pat_4(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
208   %tmp0 = call i32 @smin(i32 %y, i32 %x)
209   %tmp1 = call i32 @smax(i32 %x, i32 %y)
210   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
211   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
212   store i32 %tmp3, i32 addrspace(1)* %arg
213   ret void
216 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_5:
217 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
218 define amdgpu_kernel void @s_test_smed3_i32_pat_5(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
220   %tmp0 = call i32 @smin(i32 %y, i32 %x)
221   %tmp1 = call i32 @smax(i32 %y, i32 %x)
222   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
223   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
224   store i32 %tmp3, i32 addrspace(1)* %arg
225   ret void
228 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_6:
229 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
230 define amdgpu_kernel void @s_test_smed3_i32_pat_6(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
232   %tmp0 = call i32 @smin(i32 %y, i32 %x)
233   %tmp1 = call i32 @smax(i32 %x, i32 %y)
234   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
235   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
236   store i32 %tmp3, i32 addrspace(1)* %arg
237   ret void
240 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_7:
241 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
242 define amdgpu_kernel void @s_test_smed3_i32_pat_7(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
244   %tmp0 = call i32 @smin(i32 %y, i32 %x)
245   %tmp1 = call i32 @smax(i32 %y, i32 %x)
246   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
247   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
248   store i32 %tmp3, i32 addrspace(1)* %arg
249   ret void
252 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_8:
253 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
254 define amdgpu_kernel void @s_test_smed3_i32_pat_8(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
256   %tmp0 = call i32 @smin(i32 %x, i32 %y)
257   %tmp1 = call i32 @smax(i32 %x, i32 %y)
258   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
259   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
260   store i32 %tmp3, i32 addrspace(1)* %arg
261   ret void
264 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_9:
265 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
266 define amdgpu_kernel void @s_test_smed3_i32_pat_9(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
268   %tmp0 = call i32 @smin(i32 %x, i32 %y)
269   %tmp1 = call i32 @smax(i32 %y, i32 %x)
270   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
271   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
272   store i32 %tmp3, i32 addrspace(1)* %arg
273   ret void
276 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_10:
277 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
278 define amdgpu_kernel void @s_test_smed3_i32_pat_10(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
280   %tmp0 = call i32 @smin(i32 %x, i32 %y)
281   %tmp1 = call i32 @smax(i32 %x, i32 %y)
282   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
283   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
284   store i32 %tmp3, i32 addrspace(1)* %arg
285   ret void
288 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_11:
289 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
290 define amdgpu_kernel void @s_test_smed3_i32_pat_11(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
292   %tmp0 = call i32 @smin(i32 %x, i32 %y)
293   %tmp1 = call i32 @smax(i32 %y, i32 %x)
294   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
295   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
296   store i32 %tmp3, i32 addrspace(1)* %arg
297   ret void
300 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_12:
301 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
302 define amdgpu_kernel void @s_test_smed3_i32_pat_12(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
304   %tmp0 = call i32 @smin(i32 %y, i32 %x)
305   %tmp1 = call i32 @smax(i32 %x, i32 %y)
306   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
307   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
308   store i32 %tmp3, i32 addrspace(1)* %arg
309   ret void
312 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_13:
313 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
314 define amdgpu_kernel void @s_test_smed3_i32_pat_13(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
316   %tmp0 = call i32 @smin(i32 %y, i32 %x)
317   %tmp1 = call i32 @smax(i32 %y, i32 %x)
318   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
319   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
320   store i32 %tmp3, i32 addrspace(1)* %arg
321   ret void
324 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_14:
325 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
326 define amdgpu_kernel void @s_test_smed3_i32_pat_14(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
328   %tmp0 = call i32 @smin(i32 %y, i32 %x)
329   %tmp1 = call i32 @smax(i32 %x, i32 %y)
330   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
331   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
332   store i32 %tmp3, i32 addrspace(1)* %arg
333   ret void
336 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_15:
337 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
338 define amdgpu_kernel void @s_test_smed3_i32_pat_15(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
340   %tmp0 = call i32 @smin(i32 %y, i32 %x)
341   %tmp1 = call i32 @smax(i32 %y, i32 %x)
342   %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
343   %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
344   store i32 %tmp3, i32 addrspace(1)* %arg
345   ret void
348 ; 16 combinations
350 ; 16: min(max(x, y), max(min(x, y), z))
351 ; 17: min(max(x, y), max(min(y, x), z))
352 ; 18: min(max(x, y), max(z, min(x, y)))
353 ; 19: min(max(x, y), max(z, min(y, x)))
354 ; 20: min(max(y, x), max(min(x, y), z))
355 ; 21: min(max(y, x), max(min(y, x), z))
356 ; 22: min(max(y, x), max(z, min(x, y)))
357 ; 23: min(max(y, x), max(z, min(y, x)))
359 ; + commute outermost min
361 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_16:
362 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
363 define amdgpu_kernel void @s_test_smed3_i32_pat_16(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
365   %tmp0 = call i32 @smin(i32 %x, i32 %y)
366   %tmp1 = call i32 @smax(i32 %x, i32 %y)
367   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
368   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
369   store i32 %tmp3, i32 addrspace(1)* %arg
370   ret void
373 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_17:
374 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
375 define amdgpu_kernel void @s_test_smed3_i32_pat_17(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
377   %tmp0 = call i32 @smin(i32 %y, i32 %x)
378   %tmp1 = call i32 @smax(i32 %x, i32 %y)
379   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
380   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
381   store i32 %tmp3, i32 addrspace(1)* %arg
382   ret void
385 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_18:
386 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
387 define amdgpu_kernel void @s_test_smed3_i32_pat_18(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
389   %tmp0 = call i32 @smin(i32 %x, i32 %y)
390   %tmp1 = call i32 @smax(i32 %x, i32 %y)
391   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
392   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
393   store i32 %tmp3, i32 addrspace(1)* %arg
394   ret void
397 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_19:
398 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
399 define amdgpu_kernel void @s_test_smed3_i32_pat_19(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
401   %tmp0 = call i32 @smin(i32 %y, i32 %x)
402   %tmp1 = call i32 @smax(i32 %x, i32 %y)
403   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
404   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
405   store i32 %tmp3, i32 addrspace(1)* %arg
406   ret void
409 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_20:
410 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
411 define amdgpu_kernel void @s_test_smed3_i32_pat_20(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
413   %tmp0 = call i32 @smin(i32 %x, i32 %y)
414   %tmp1 = call i32 @smax(i32 %y, i32 %x)
415   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
416   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
417   store i32 %tmp3, i32 addrspace(1)* %arg
418   ret void
421 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_21:
422 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
423 define amdgpu_kernel void @s_test_smed3_i32_pat_21(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
425   %tmp0 = call i32 @smin(i32 %y, i32 %x)
426   %tmp1 = call i32 @smax(i32 %y, i32 %x)
427   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
428   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
429   store i32 %tmp3, i32 addrspace(1)* %arg
430   ret void
433 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_22:
434 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
435 define amdgpu_kernel void @s_test_smed3_i32_pat_22(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
437   %tmp0 = call i32 @smin(i32 %x, i32 %y)
438   %tmp1 = call i32 @smax(i32 %y, i32 %x)
439   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
440   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
441   store i32 %tmp3, i32 addrspace(1)* %arg
442   ret void
445 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_23:
446 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
447 define amdgpu_kernel void @s_test_smed3_i32_pat_23(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
449   %tmp0 = call i32 @smin(i32 %y, i32 %x)
450   %tmp1 = call i32 @smax(i32 %y, i32 %x)
451   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
452   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
453   store i32 %tmp3, i32 addrspace(1)* %arg
454   ret void
457 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_24:
458 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
459 define amdgpu_kernel void @s_test_smed3_i32_pat_24(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
461   %tmp0 = call i32 @smin(i32 %x, i32 %y)
462   %tmp1 = call i32 @smax(i32 %x, i32 %y)
463   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
464   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
465   store i32 %tmp3, i32 addrspace(1)* %arg
466   ret void
469 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_25:
470 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
471 define amdgpu_kernel void @s_test_smed3_i32_pat_25(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
473   %tmp0 = call i32 @smin(i32 %y, i32 %x)
474   %tmp1 = call i32 @smax(i32 %x, i32 %y)
475   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
476   %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
477   store i32 %tmp3, i32 addrspace(1)* %arg
478   ret void
481 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_26:
482 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
483 define amdgpu_kernel void @s_test_smed3_i32_pat_26(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
485   %tmp0 = call i32 @smin(i32 %x, i32 %y)
486   %tmp1 = call i32 @smax(i32 %x, i32 %y)
487   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
488   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
489   store i32 %tmp3, i32 addrspace(1)* %arg
490   ret void
493 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_27:
494 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
495 define amdgpu_kernel void @s_test_smed3_i32_pat_27(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
497   %tmp0 = call i32 @smin(i32 %y, i32 %x)
498   %tmp1 = call i32 @smax(i32 %x, i32 %y)
499   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
500   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
501   store i32 %tmp3, i32 addrspace(1)* %arg
502   ret void
505 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_28:
506 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
507 define amdgpu_kernel void @s_test_smed3_i32_pat_28(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
509   %tmp0 = call i32 @smin(i32 %x, i32 %y)
510   %tmp1 = call i32 @smax(i32 %y, i32 %x)
511   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
512   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
513   store i32 %tmp3, i32 addrspace(1)* %arg
514   ret void
517 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_29:
518 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
519 define amdgpu_kernel void @s_test_smed3_i32_pat_29(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
521   %tmp0 = call i32 @smin(i32 %y, i32 %x)
522   %tmp1 = call i32 @smax(i32 %y, i32 %x)
523   %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
524   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
525   store i32 %tmp3, i32 addrspace(1)* %arg
526   ret void
529 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_30:
530 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
531 define amdgpu_kernel void @s_test_smed3_i32_pat_30(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
533   %tmp0 = call i32 @smin(i32 %x, i32 %y)
534   %tmp1 = call i32 @smax(i32 %y, i32 %x)
535   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
536   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
537   store i32 %tmp3, i32 addrspace(1)* %arg
538   ret void
541 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_31:
542 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
543 define amdgpu_kernel void @s_test_smed3_i32_pat_31(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
545   %tmp0 = call i32 @smin(i32 %y, i32 %x)
546   %tmp1 = call i32 @smax(i32 %y, i32 %x)
547   %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
548   %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
549   store i32 %tmp3, i32 addrspace(1)* %arg
550   ret void
553 ; FIXME: Should keep scalar or not promote
554 ; GCN-LABEL: {{^}}s_test_smed3_i16_pat_0:
555 ; GCN: s_sext_i32_i16
556 ; GCN: s_sext_i32_i16
557 ; GCN: s_sext_i32_i16
558 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
559 define amdgpu_kernel void @s_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, [8 x i32], i16 %x, [8 x i32], i16 %y, [8 x i32], i16 %z) #1 {
561   %tmp0 = call i16 @smin16(i16 %x, i16 %y)
562   %tmp1 = call i16 @smax16(i16 %x, i16 %y)
563   %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
564   %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
565   store i16 %tmp3, i16 addrspace(1)* %arg
566   ret void
569 ; GCN-LABEL: {{^}}s_test_smed3_i8_pat_0:
570 ; GCN: s_sext_i32_i8
571 ; GCN: s_sext_i32_i8
572 ; GCN: s_sext_i32_i8
573 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
574 define amdgpu_kernel void @s_test_smed3_i8_pat_0(i8 addrspace(1)* %arg, [8 x i32], i8 %x, [8 x i32], i8 %y, [8 x i32], i8 %z) #1 {
576   %tmp0 = call i8 @smin8(i8 %x, i8 %y)
577   %tmp1 = call i8 @smax8(i8 %x, i8 %y)
578   %tmp2 = call i8 @smin8(i8 %tmp1, i8 %z)
579   %tmp3 = call i8 @smax8(i8 %tmp0, i8 %tmp2)
580   store i8 %tmp3, i8 addrspace(1)* %arg
581   ret void
584 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
585 ; GCN-NOT: v_med3_i32
586 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
588   %tmp0 = call i32 @smin(i32 %x, i32 %y)
589   %tmp1 = call i32 @smax(i32 %x, i32 %y)
590   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
591   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
592   store volatile i32 %tmp0, i32 addrspace(1)* %arg
593   store volatile i32 %tmp3, i32 addrspace(1)* %arg
594   ret void
597 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_1:
598 ; GCN-NOT: v_med3_i32
599 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
601   %tmp0 = call i32 @smin(i32 %x, i32 %y)
602   %tmp1 = call i32 @smax(i32 %x, i32 %y)
603   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
604   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
605   store volatile i32 %tmp1, i32 addrspace(1)* %arg
606   store volatile i32 %tmp3, i32 addrspace(1)* %arg
607   ret void
610 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_2:
611 ; GCN-NOT: v_med3_i32
612 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
614   %tmp0 = call i32 @smin(i32 %x, i32 %y)
615   %tmp1 = call i32 @smax(i32 %x, i32 %y)
616   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
617   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
618   store volatile i32 %tmp2, i32 addrspace(1)* %arg
619   store volatile i32 %tmp3, i32 addrspace(1)* %arg
620   ret void
623 ; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_result:
624 ; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
625 define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_result(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
627   %tmp0 = call i32 @smin(i32 %x, i32 %y)
628   %tmp1 = call i32 @smax(i32 %x, i32 %y)
629   %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
630   %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
631   store volatile i32 %tmp3, i32 addrspace(1)* %arg
632   store volatile i32 %tmp3, i32 addrspace(1)* %arg
633   ret void
636 ; GCN-LABEL: {{^}}v_test_smed3_i16_pat_0:
637 ; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
639 ; FIXME: VI not matching med3
640 ; VI: v_min_i16
641 ; VI: v_max_i16
642 ; VI: v_min_i16
643 ; VI: v_max_i16
645 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
646 define amdgpu_kernel void @v_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
648   %tid = call i32 @llvm.amdgcn.workitem.id.x()
649   %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
650   %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
651   %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
652   %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
653   %x = load i16, i16 addrspace(1)* %gep0
654   %y = load i16, i16 addrspace(1)* %gep1
655   %z = load i16, i16 addrspace(1)* %gep2
657   %tmp0 = call i16 @smin16(i16 %x, i16 %y)
658   %tmp1 = call i16 @smax16(i16 %x, i16 %y)
659   %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
660   %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
661   store i16 %tmp3, i16 addrspace(1)* %out.gep
662   ret void
665 ; GCN-LABEL: {{^}}v_test_smed3_i16_pat_1:
666 ; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
668 define amdgpu_kernel void @v_test_smed3_i16_pat_1(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
670   %tid = call i32 @llvm.amdgcn.workitem.id.x()
671   %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
672   %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
673   %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
674   %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
675   %x = load i16, i16 addrspace(1)* %gep0
676   %y = load i16, i16 addrspace(1)* %gep1
677   %z = load i16, i16 addrspace(1)* %gep2
679   %tmp0 = call i16 @smin16(i16 %x, i16 %y)
680   %tmp1 = call i16 @smax16(i16 %x, i16 %y)
681   %tmp2 = call i16 @smax16(i16 %tmp0, i16 %z)
682   %tmp3 = call i16 @smin16(i16 %tmp1, i16 %tmp2)
683   store i16 %tmp3, i16 addrspace(1)* %out.gep
684   ret void
687 attributes #0 = { nounwind readnone }
688 attributes #1 = { nounwind }
689 attributes #2 = { nounwind readnone alwaysinline }