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=gfx901 -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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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; FIXME: Should keep scalar or not promote
368; GCN-LABEL: {{^}}s_test_smed3_i16_pat_0:
369; GCN: s_sext_i32_i16
370; GCN: s_sext_i32_i16
371; GCN: s_sext_i32_i16
372; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
373define void @s_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 %x, i16 %y, i16 %z) #1 {
374bb:
375  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
376  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
377  %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
378  %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
379  store i16 %tmp3, i16 addrspace(1)* %arg
380  ret void
381}
382
383; GCN-LABEL: {{^}}s_test_smed3_i8_pat_0:
384; GCN: s_sext_i32_i8
385; GCN: s_sext_i32_i8
386; GCN: s_sext_i32_i8
387; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
388define void @s_test_smed3_i8_pat_0(i8 addrspace(1)* %arg, i8 %x, i8 %y, i8 %z) #1 {
389bb:
390  %tmp0 = call i8 @smin8(i8 %x, i8 %y)
391  %tmp1 = call i8 @smax8(i8 %x, i8 %y)
392  %tmp2 = call i8 @smin8(i8 %tmp1, i8 %z)
393  %tmp3 = call i8 @smax8(i8 %tmp0, i8 %tmp2)
394  store i8 %tmp3, i8 addrspace(1)* %arg
395  ret void
396}
397
398; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
399; GCN-NOT: v_med3_i32
400define void @s_test_smed3_i32_pat_0_multi_use_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
401bb:
402  %tmp0 = call i32 @smin(i32 %x, i32 %y)
403  %tmp1 = call i32 @smax(i32 %x, i32 %y)
404  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
405  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
406  store volatile i32 %tmp0, i32 addrspace(1)* %arg
407  store volatile i32 %tmp3, i32 addrspace(1)* %arg
408  ret void
409}
410
411; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_1:
412; GCN-NOT: v_med3_i32
413define void @s_test_smed3_i32_pat_0_multi_use_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
414bb:
415  %tmp0 = call i32 @smin(i32 %x, i32 %y)
416  %tmp1 = call i32 @smax(i32 %x, i32 %y)
417  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
418  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
419  store volatile i32 %tmp1, i32 addrspace(1)* %arg
420  store volatile i32 %tmp3, i32 addrspace(1)* %arg
421  ret void
422}
423
424; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_2:
425; GCN-NOT: v_med3_i32
426define void @s_test_smed3_i32_pat_0_multi_use_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
427bb:
428  %tmp0 = call i32 @smin(i32 %x, i32 %y)
429  %tmp1 = call i32 @smax(i32 %x, i32 %y)
430  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
431  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
432  store volatile i32 %tmp2, i32 addrspace(1)* %arg
433  store volatile i32 %tmp3, i32 addrspace(1)* %arg
434  ret void
435}
436
437; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_result:
438; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
439define void @s_test_smed3_i32_pat_0_multi_use_result(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
440bb:
441  %tmp0 = call i32 @smin(i32 %x, i32 %y)
442  %tmp1 = call i32 @smax(i32 %x, i32 %y)
443  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
444  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
445  store volatile i32 %tmp3, i32 addrspace(1)* %arg
446  store volatile i32 %tmp3, i32 addrspace(1)* %arg
447  ret void
448}
449
450; GCN-LABEL: {{^}}v_test_smed3_i16_pat_0:
451; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
452
453; FIXME: VI not matching med3
454; VI: v_min_i16
455; VI: v_max_i16
456; VI: v_min_i16
457; VI: v_max_i16
458
459; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
460define void @v_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
461bb:
462  %tid = call i32 @llvm.amdgcn.workitem.id.x()
463  %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
464  %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
465  %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
466  %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
467  %x = load i16, i16 addrspace(1)* %gep0
468  %y = load i16, i16 addrspace(1)* %gep1
469  %z = load i16, i16 addrspace(1)* %gep2
470
471  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
472  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
473  %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
474  %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
475  store i16 %tmp3, i16 addrspace(1)* %out.gep
476  ret void
477}
478
479attributes #0 = { nounwind readnone }
480attributes #1 = { nounwind }
481attributes #2 = { nounwind readnone alwaysinline }
482