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_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]+}}
48define 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
53
54  %icmp0 = icmp ugt i32 %a, 12
55  %i0 = select i1 %icmp0, i32 %a, i32 12
56
57  %icmp1 = icmp slt i32 %i0, 17
58  %i1 = select i1 %icmp1, i32 %i0, i32 17
59
60  store i32 %i1, i32 addrspace(1)* %outgep
61  ret void
62}
63
64; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i64:
65; GCN: v_cmp_lt_i64
66; GCN: v_cmp_gt_i64
67define 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
72
73  %icmp0 = icmp sgt i64 %a, 12
74  %i0 = select i1 %icmp0, i64 %a, i64 12
75
76  %icmp1 = icmp slt i64 %i0, 17
77  %i1 = select i1 %icmp1, i64 %i0, i64 17
78
79  store i64 %i1, i64 addrspace(1)* %outgep
80  ret void
81}
82
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
86define 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
91
92  %icmp0 = icmp sgt i16 %a, 12
93  %i0 = select i1 %icmp0, i16 %a, i16 12
94
95  %icmp1 = icmp slt i16 %i0, 17
96  %i1 = select i1 %icmp1, i16 %i0, i16 17
97
98  store i16 %i1, i16 addrspace(1)* %outgep
99  ret void
100}
101
102
103define 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
107}
108
109define 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
113}
114
115define 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
119}
120
121define 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
125}
126
127define 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
131}
132
133define 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
137}
138
139; 16 combinations
140
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)))
149;
150; + commute outermost max
151
152
153; FIXME: In these cases we probably should have used scalar operations
154; instead.
155
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]+}}
158define amdgpu_kernel void @s_test_smed3_i32_pat_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
159bb:
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
166}
167
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]+}}
170define amdgpu_kernel void @s_test_smed3_i32_pat_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
171bb:
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
178}
179
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]+}}
182define amdgpu_kernel void @s_test_smed3_i32_pat_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
183bb:
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
190}
191
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]+}}
194define amdgpu_kernel void @s_test_smed3_i32_pat_3(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
195bb:
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
202}
203
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]+}}
206define amdgpu_kernel void @s_test_smed3_i32_pat_4(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
207bb:
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
214}
215
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]+}}
218define amdgpu_kernel void @s_test_smed3_i32_pat_5(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
219bb:
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
226}
227
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]+}}
230define amdgpu_kernel void @s_test_smed3_i32_pat_6(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
231bb:
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
238}
239
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]+}}
242define amdgpu_kernel void @s_test_smed3_i32_pat_7(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
243bb:
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
250}
251
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]+}}
254define amdgpu_kernel void @s_test_smed3_i32_pat_8(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
255bb:
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
262}
263
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]+}}
266define amdgpu_kernel void @s_test_smed3_i32_pat_9(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
267bb:
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
274}
275
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]+}}
278define amdgpu_kernel void @s_test_smed3_i32_pat_10(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
279bb:
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
286}
287
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]+}}
290define amdgpu_kernel void @s_test_smed3_i32_pat_11(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
291bb:
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
298}
299
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]+}}
302define amdgpu_kernel void @s_test_smed3_i32_pat_12(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
303bb:
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
310}
311
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]+}}
314define amdgpu_kernel void @s_test_smed3_i32_pat_13(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
315bb:
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
322}
323
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]+}}
326define amdgpu_kernel void @s_test_smed3_i32_pat_14(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
327bb:
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
334}
335
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]+}}
338define amdgpu_kernel void @s_test_smed3_i32_pat_15(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
339bb:
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
346}
347
348; 16 combinations
349
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)))
358;
359; + commute outermost min
360
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]+}}
363define amdgpu_kernel void @s_test_smed3_i32_pat_16(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
364bb:
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
371}
372
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]+}}
375define amdgpu_kernel void @s_test_smed3_i32_pat_17(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
376bb:
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
383}
384
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]+}}
387define amdgpu_kernel void @s_test_smed3_i32_pat_18(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
388bb:
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
395}
396
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]+}}
399define amdgpu_kernel void @s_test_smed3_i32_pat_19(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
400bb:
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
407}
408
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]+}}
411define amdgpu_kernel void @s_test_smed3_i32_pat_20(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
412bb:
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
419}
420
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]+}}
423define amdgpu_kernel void @s_test_smed3_i32_pat_21(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
424bb:
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
431}
432
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]+}}
435define amdgpu_kernel void @s_test_smed3_i32_pat_22(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
436bb:
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
443}
444
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]+}}
447define amdgpu_kernel void @s_test_smed3_i32_pat_23(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
448bb:
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
455}
456
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]+}}
459define amdgpu_kernel void @s_test_smed3_i32_pat_24(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
460bb:
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
467}
468
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]+}}
471define amdgpu_kernel void @s_test_smed3_i32_pat_25(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
472bb:
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
479}
480
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]+}}
483define amdgpu_kernel void @s_test_smed3_i32_pat_26(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
484bb:
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
491}
492
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]+}}
495define amdgpu_kernel void @s_test_smed3_i32_pat_27(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
496bb:
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
503}
504
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]+}}
507define amdgpu_kernel void @s_test_smed3_i32_pat_28(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
508bb:
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
515}
516
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]+}}
519define amdgpu_kernel void @s_test_smed3_i32_pat_29(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
520bb:
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
527}
528
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]+}}
531define amdgpu_kernel void @s_test_smed3_i32_pat_30(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
532bb:
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
539}
540
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]+}}
543define amdgpu_kernel void @s_test_smed3_i32_pat_31(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
544bb:
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
551}
552
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]+}}
559define 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 {
560bb:
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
567}
568
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]+}}
574define 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 {
575bb:
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
582}
583
584; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
585; GCN-NOT: v_med3_i32
586define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
587bb:
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
595}
596
597; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_1:
598; GCN-NOT: v_med3_i32
599define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
600bb:
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
608}
609
610; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_2:
611; GCN-NOT: v_med3_i32
612define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
613bb:
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
621}
622
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]+}}
625define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_result(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
626bb:
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
634}
635
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]+}}
638
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
644
645; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
646define amdgpu_kernel void @v_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
647bb:
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
656
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
663}
664
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]+}}
667
668define amdgpu_kernel void @v_test_smed3_i16_pat_1(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
669bb:
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
678
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
685}
686
687attributes #0 = { nounwind readnone }
688attributes #1 = { nounwind }
689attributes #2 = { nounwind readnone alwaysinline }
690