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
4
5declare i32 @llvm.amdgcn.workitem.id.x() #0
6
7; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i32:
8; GCN: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
9define 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
14
15  %icmp0 = icmp sgt i32 %a, 12
16  %i0 = select i1 %icmp0, i32 %a, i32 12
17
18  %icmp1 = icmp slt i32 %i0, 17
19  %i1 = select i1 %icmp1, i32 %i0, i32 17
20
21  store i32 %i1, i32 addrspace(1)* %outgep
22  ret void
23}
24
25; GCN-LABEL: {{^}}v_test_smed3_multi_use_r_i_i_i32:
26; GCN: v_max_i32
27; GCN: v_min_i32
28define 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
33
34  %icmp0 = icmp sgt i32 %a, 12
35  %i0 = select i1 %icmp0, i32 %a, i32 12
36
37  %icmp1 = icmp slt i32 %i0, 17
38  %i1 = select i1 %icmp1, i32 %i0, i32 17
39
40  store volatile i32 %i0, i32 addrspace(1)* %outgep
41  store volatile i32 %i1, i32 addrspace(1)* %outgep
42  ret void
43}
44
45; GCN-LABEL: {{^}}v_test_smed3_r_i_i_constant_order_i32:
46; GCN: v_max_i32_e32 v{{[0-9]+}}, 17, v{{[0-9]+}}
47; GCN: v_min_i32_e32 v{{[0-9]+}}, 12, v{{[0-9]+}}
48define amdgpu_kernel void @v_test_smed3_r_i_i_constant_order_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
53
54  %icmp0 = icmp sgt i32 %a, 17
55  %i0 = select i1 %icmp0, i32 %a, i32 17
56
57  %icmp1 = icmp slt i32 %i0, 12
58  %i1 = select i1 %icmp1, i32 %i0, i32 12
59
60  store i32 %i1, i32 addrspace(1)* %outgep
61  ret void
62}
63
64; GCN-LABEL: {{^}}v_test_smed3_r_i_i_sign_mismatch_i32:
65; GCN: v_max_u32_e32 v{{[0-9]+}}, 12, v{{[0-9]+}}
66; GCN: v_min_i32_e32 v{{[0-9]+}}, 17, v{{[0-9]+}}
67define amdgpu_kernel void @v_test_smed3_r_i_i_sign_mismatch_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr) #1 {
68  %tid = call i32 @llvm.amdgcn.workitem.id.x()
69  %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
70  %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
71  %a = load i32, i32 addrspace(1)* %gep0
72
73  %icmp0 = icmp ugt i32 %a, 12
74  %i0 = select i1 %icmp0, i32 %a, i32 12
75
76  %icmp1 = icmp slt i32 %i0, 17
77  %i1 = select i1 %icmp1, i32 %i0, i32 17
78
79  store i32 %i1, i32 addrspace(1)* %outgep
80  ret void
81}
82
83; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i64:
84; GCN: v_cmp_lt_i64
85; GCN: v_cmp_gt_i64
86define amdgpu_kernel void @v_test_smed3_r_i_i_i64(i64 addrspace(1)* %out, i64 addrspace(1)* %aptr) #1 {
87  %tid = call i32 @llvm.amdgcn.workitem.id.x()
88  %gep0 = getelementptr i64, i64 addrspace(1)* %aptr, i32 %tid
89  %outgep = getelementptr i64, i64 addrspace(1)* %out, i32 %tid
90  %a = load i64, i64 addrspace(1)* %gep0
91
92  %icmp0 = icmp sgt i64 %a, 12
93  %i0 = select i1 %icmp0, i64 %a, i64 12
94
95  %icmp1 = icmp slt i64 %i0, 17
96  %i1 = select i1 %icmp1, i64 %i0, i64 17
97
98  store i64 %i1, i64 addrspace(1)* %outgep
99  ret void
100}
101
102; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i16:
103; SICIVI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
104; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
105define amdgpu_kernel void @v_test_smed3_r_i_i_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %aptr) #1 {
106  %tid = call i32 @llvm.amdgcn.workitem.id.x()
107  %gep0 = getelementptr i16, i16 addrspace(1)* %aptr, i32 %tid
108  %outgep = getelementptr i16, i16 addrspace(1)* %out, i32 %tid
109  %a = load i16, i16 addrspace(1)* %gep0
110
111  %icmp0 = icmp sgt i16 %a, 12
112  %i0 = select i1 %icmp0, i16 %a, i16 12
113
114  %icmp1 = icmp slt i16 %i0, 17
115  %i1 = select i1 %icmp1, i16 %i0, i16 17
116
117  store i16 %i1, i16 addrspace(1)* %outgep
118  ret void
119}
120
121
122define internal i32 @smin(i32 %x, i32 %y) #2 {
123  %cmp = icmp slt i32 %x, %y
124  %sel = select i1 %cmp, i32 %x, i32 %y
125  ret i32 %sel
126}
127
128define internal i32 @smax(i32 %x, i32 %y) #2 {
129  %cmp = icmp sgt i32 %x, %y
130  %sel = select i1 %cmp, i32 %x, i32 %y
131  ret i32 %sel
132}
133
134define internal i16 @smin16(i16 %x, i16 %y) #2 {
135  %cmp = icmp slt i16 %x, %y
136  %sel = select i1 %cmp, i16 %x, i16 %y
137  ret i16 %sel
138}
139
140define internal i16 @smax16(i16 %x, i16 %y) #2 {
141  %cmp = icmp sgt i16 %x, %y
142  %sel = select i1 %cmp, i16 %x, i16 %y
143  ret i16 %sel
144}
145
146define internal i8 @smin8(i8 %x, i8 %y) #2 {
147  %cmp = icmp slt i8 %x, %y
148  %sel = select i1 %cmp, i8 %x, i8 %y
149  ret i8 %sel
150}
151
152define internal i8 @smax8(i8 %x, i8 %y) #2 {
153  %cmp = icmp sgt i8 %x, %y
154  %sel = select i1 %cmp, i8 %x, i8 %y
155  ret i8 %sel
156}
157
158; 16 combinations
159
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)))
168;
169; + commute outermost max
170
171
172; FIXME: In these cases we probably should have used scalar operations
173; instead.
174
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]+}}
177define amdgpu_kernel void @s_test_smed3_i32_pat_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
178bb:
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, i32 addrspace(1)* %arg
184  ret void
185}
186
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]+}}
189define amdgpu_kernel void @s_test_smed3_i32_pat_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
190bb:
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, i32 addrspace(1)* %arg
196  ret void
197}
198
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]+}}
201define amdgpu_kernel void @s_test_smed3_i32_pat_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
202bb:
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, i32 addrspace(1)* %arg
208  ret void
209}
210
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]+}}
213define amdgpu_kernel void @s_test_smed3_i32_pat_3(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
214bb:
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, i32 addrspace(1)* %arg
220  ret void
221}
222
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]+}}
225define amdgpu_kernel void @s_test_smed3_i32_pat_4(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
226bb:
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, i32 addrspace(1)* %arg
232  ret void
233}
234
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]+}}
237define amdgpu_kernel void @s_test_smed3_i32_pat_5(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
238bb:
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, i32 addrspace(1)* %arg
244  ret void
245}
246
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]+}}
249define amdgpu_kernel void @s_test_smed3_i32_pat_6(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
250bb:
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, i32 addrspace(1)* %arg
256  ret void
257}
258
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]+}}
261define amdgpu_kernel void @s_test_smed3_i32_pat_7(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
262bb:
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, i32 addrspace(1)* %arg
268  ret void
269}
270
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]+}}
273define amdgpu_kernel void @s_test_smed3_i32_pat_8(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
274bb:
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, i32 addrspace(1)* %arg
280  ret void
281}
282
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]+}}
285define amdgpu_kernel void @s_test_smed3_i32_pat_9(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
286bb:
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, i32 addrspace(1)* %arg
292  ret void
293}
294
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]+}}
297define amdgpu_kernel void @s_test_smed3_i32_pat_10(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
298bb:
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, i32 addrspace(1)* %arg
304  ret void
305}
306
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]+}}
309define amdgpu_kernel void @s_test_smed3_i32_pat_11(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
310bb:
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, i32 addrspace(1)* %arg
316  ret void
317}
318
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]+}}
321define amdgpu_kernel void @s_test_smed3_i32_pat_12(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
322bb:
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, i32 addrspace(1)* %arg
328  ret void
329}
330
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]+}}
333define amdgpu_kernel void @s_test_smed3_i32_pat_13(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
334bb:
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, i32 addrspace(1)* %arg
340  ret void
341}
342
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]+}}
345define amdgpu_kernel void @s_test_smed3_i32_pat_14(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
346bb:
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, i32 addrspace(1)* %arg
352  ret void
353}
354
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]+}}
357define amdgpu_kernel void @s_test_smed3_i32_pat_15(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
358bb:
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, i32 addrspace(1)* %arg
364  ret void
365}
366
367; 16 combinations
368
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)))
377;
378; + commute outermost min
379
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]+}}
382define amdgpu_kernel void @s_test_smed3_i32_pat_16(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
383bb:
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, i32 addrspace(1)* %arg
389  ret void
390}
391
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]+}}
394define amdgpu_kernel void @s_test_smed3_i32_pat_17(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
395bb:
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, i32 addrspace(1)* %arg
401  ret void
402}
403
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]+}}
406define amdgpu_kernel void @s_test_smed3_i32_pat_18(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
407bb:
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, i32 addrspace(1)* %arg
413  ret void
414}
415
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]+}}
418define amdgpu_kernel void @s_test_smed3_i32_pat_19(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
419bb:
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, i32 addrspace(1)* %arg
425  ret void
426}
427
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]+}}
430define amdgpu_kernel void @s_test_smed3_i32_pat_20(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
431bb:
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, i32 addrspace(1)* %arg
437  ret void
438}
439
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]+}}
442define amdgpu_kernel void @s_test_smed3_i32_pat_21(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
443bb:
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, i32 addrspace(1)* %arg
449  ret void
450}
451
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]+}}
454define amdgpu_kernel void @s_test_smed3_i32_pat_22(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
455bb:
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, i32 addrspace(1)* %arg
461  ret void
462}
463
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]+}}
466define amdgpu_kernel void @s_test_smed3_i32_pat_23(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
467bb:
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, i32 addrspace(1)* %arg
473  ret void
474}
475
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]+}}
478define amdgpu_kernel void @s_test_smed3_i32_pat_24(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
479bb:
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, i32 addrspace(1)* %arg
485  ret void
486}
487
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]+}}
490define amdgpu_kernel void @s_test_smed3_i32_pat_25(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
491bb:
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, i32 addrspace(1)* %arg
497  ret void
498}
499
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]+}}
502define amdgpu_kernel void @s_test_smed3_i32_pat_26(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
503bb:
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, i32 addrspace(1)* %arg
509  ret void
510}
511
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]+}}
514define amdgpu_kernel void @s_test_smed3_i32_pat_27(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
515bb:
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, i32 addrspace(1)* %arg
521  ret void
522}
523
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]+}}
526define amdgpu_kernel void @s_test_smed3_i32_pat_28(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
527bb:
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, i32 addrspace(1)* %arg
533  ret void
534}
535
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]+}}
538define amdgpu_kernel void @s_test_smed3_i32_pat_29(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
539bb:
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, i32 addrspace(1)* %arg
545  ret void
546}
547
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]+}}
550define amdgpu_kernel void @s_test_smed3_i32_pat_30(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
551bb:
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, i32 addrspace(1)* %arg
557  ret void
558}
559
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]+}}
562define amdgpu_kernel void @s_test_smed3_i32_pat_31(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
563bb:
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, i32 addrspace(1)* %arg
569  ret void
570}
571
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]+}}
578define 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 {
579bb:
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, i16 addrspace(1)* %arg
585  ret void
586}
587
588; GCN-LABEL: {{^}}s_test_smed3_i8_pat_0:
589; GCN: s_sext_i32_i8
590; GCN: s_sext_i32_i8
591; GCN: s_sext_i32_i8
592; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
593define 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 {
594bb:
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, i8 addrspace(1)* %arg
600  ret void
601}
602
603; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
604; GCN-NOT: v_med3_i32
605define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
606bb:
607  %tmp0 = call i32 @smin(i32 %x, i32 %y)
608  %tmp1 = call i32 @smax(i32 %x, i32 %y)
609  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
610  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
611  store volatile i32 %tmp0, i32 addrspace(1)* %arg
612  store volatile i32 %tmp3, i32 addrspace(1)* %arg
613  ret void
614}
615
616; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_1:
617; GCN-NOT: v_med3_i32
618define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
619bb:
620  %tmp0 = call i32 @smin(i32 %x, i32 %y)
621  %tmp1 = call i32 @smax(i32 %x, i32 %y)
622  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
623  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
624  store volatile i32 %tmp1, i32 addrspace(1)* %arg
625  store volatile i32 %tmp3, i32 addrspace(1)* %arg
626  ret void
627}
628
629; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_2:
630; GCN-NOT: v_med3_i32
631define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
632bb:
633  %tmp0 = call i32 @smin(i32 %x, i32 %y)
634  %tmp1 = call i32 @smax(i32 %x, i32 %y)
635  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
636  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
637  store volatile i32 %tmp2, i32 addrspace(1)* %arg
638  store volatile i32 %tmp3, i32 addrspace(1)* %arg
639  ret void
640}
641
642; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_result:
643; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
644define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_result(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
645bb:
646  %tmp0 = call i32 @smin(i32 %x, i32 %y)
647  %tmp1 = call i32 @smax(i32 %x, i32 %y)
648  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
649  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
650  store volatile i32 %tmp3, i32 addrspace(1)* %arg
651  store volatile i32 %tmp3, i32 addrspace(1)* %arg
652  ret void
653}
654
655; GCN-LABEL: {{^}}v_test_smed3_i16_pat_0:
656; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
657
658; FIXME: VI not matching med3
659; VI: v_min_i16
660; VI: v_max_i16
661; VI: v_min_i16
662; VI: v_max_i16
663
664; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
665define amdgpu_kernel void @v_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
666bb:
667  %tid = call i32 @llvm.amdgcn.workitem.id.x()
668  %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
669  %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
670  %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
671  %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
672  %x = load i16, i16 addrspace(1)* %gep0
673  %y = load i16, i16 addrspace(1)* %gep1
674  %z = load i16, i16 addrspace(1)* %gep2
675
676  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
677  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
678  %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
679  %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
680  store i16 %tmp3, i16 addrspace(1)* %out.gep
681  ret void
682}
683
684; GCN-LABEL: {{^}}v_test_smed3_i16_pat_1:
685; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
686
687define amdgpu_kernel void @v_test_smed3_i16_pat_1(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
688bb:
689  %tid = call i32 @llvm.amdgcn.workitem.id.x()
690  %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
691  %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
692  %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
693  %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
694  %x = load i16, i16 addrspace(1)* %gep0
695  %y = load i16, i16 addrspace(1)* %gep1
696  %z = load i16, i16 addrspace(1)* %gep2
697
698  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
699  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
700  %tmp2 = call i16 @smax16(i16 %tmp0, i16 %z)
701  %tmp3 = call i16 @smin16(i16 %tmp1, i16 %tmp2)
702  store i16 %tmp3, i16 addrspace(1)* %out.gep
703  ret void
704}
705
706attributes #0 = { nounwind readnone }
707attributes #1 = { nounwind }
708attributes #2 = { nounwind readnone alwaysinline }
709