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; Regression test for performIntMed3ImmCombine extending arguments to 32 bit
84; which failed for 64 bit arguments. Previously asserted / crashed.
85; GCN-LABEL: {{^}}test_intMed3ImmCombine_no_32bit_extend:
86; GCN: v_cmp_lt_i64
87; GCN: v_cmp_gt_i64
88define i64 @test_intMed3ImmCombine_no_32bit_extend(i64 %x) {
89  %smax = call i64 @llvm.smax.i64(i64 %x, i64 -2)
90  %smin = call i64 @llvm.smin.i64(i64 %smax, i64 2)
91  ret i64 %smin
92}
93declare i64 @llvm.smax.i64(i64, i64)
94declare i64 @llvm.smin.i64(i64, i64)
95
96; GCN-LABEL: {{^}}v_test_smed3_r_i_i_i16:
97; SICIVI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
98; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, 12, 17
99define amdgpu_kernel void @v_test_smed3_r_i_i_i16(i16 addrspace(1)* %out, i16 addrspace(1)* %aptr) #1 {
100  %tid = call i32 @llvm.amdgcn.workitem.id.x()
101  %gep0 = getelementptr i16, i16 addrspace(1)* %aptr, i32 %tid
102  %outgep = getelementptr i16, i16 addrspace(1)* %out, i32 %tid
103  %a = load i16, i16 addrspace(1)* %gep0
104
105  %icmp0 = icmp sgt i16 %a, 12
106  %i0 = select i1 %icmp0, i16 %a, i16 12
107
108  %icmp1 = icmp slt i16 %i0, 17
109  %i1 = select i1 %icmp1, i16 %i0, i16 17
110
111  store i16 %i1, i16 addrspace(1)* %outgep
112  ret void
113}
114
115
116define internal i32 @smin(i32 %x, i32 %y) #2 {
117  %cmp = icmp slt i32 %x, %y
118  %sel = select i1 %cmp, i32 %x, i32 %y
119  ret i32 %sel
120}
121
122define internal i32 @smax(i32 %x, i32 %y) #2 {
123  %cmp = icmp sgt i32 %x, %y
124  %sel = select i1 %cmp, i32 %x, i32 %y
125  ret i32 %sel
126}
127
128define internal i16 @smin16(i16 %x, i16 %y) #2 {
129  %cmp = icmp slt i16 %x, %y
130  %sel = select i1 %cmp, i16 %x, i16 %y
131  ret i16 %sel
132}
133
134define internal i16 @smax16(i16 %x, i16 %y) #2 {
135  %cmp = icmp sgt i16 %x, %y
136  %sel = select i1 %cmp, i16 %x, i16 %y
137  ret i16 %sel
138}
139
140define internal i8 @smin8(i8 %x, i8 %y) #2 {
141  %cmp = icmp slt i8 %x, %y
142  %sel = select i1 %cmp, i8 %x, i8 %y
143  ret i8 %sel
144}
145
146define internal i8 @smax8(i8 %x, i8 %y) #2 {
147  %cmp = icmp sgt i8 %x, %y
148  %sel = select i1 %cmp, i8 %x, i8 %y
149  ret i8 %sel
150}
151
152; 16 combinations
153
154; 0: max(min(x, y), min(max(x, y), z))
155; 1: max(min(x, y), min(max(y, x), z))
156; 2: max(min(x, y), min(z, max(x, y)))
157; 3: max(min(x, y), min(z, max(y, x)))
158; 4: max(min(y, x), min(max(x, y), z))
159; 5: max(min(y, x), min(max(y, x), z))
160; 6: max(min(y, x), min(z, max(x, y)))
161; 7: max(min(y, x), min(z, max(y, x)))
162;
163; + commute outermost max
164
165
166; FIXME: In these cases we probably should have used scalar operations
167; instead.
168
169; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0:
170; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
171define amdgpu_kernel void @s_test_smed3_i32_pat_0(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
172bb:
173  %tmp0 = call i32 @smin(i32 %x, i32 %y)
174  %tmp1 = call i32 @smax(i32 %x, i32 %y)
175  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
176  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
177  store i32 %tmp3, i32 addrspace(1)* %arg
178  ret void
179}
180
181; GCN-LABEL: {{^}}s_test_smed3_i32_pat_1:
182; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
183define amdgpu_kernel void @s_test_smed3_i32_pat_1(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
184bb:
185  %tmp0 = call i32 @smin(i32 %x, i32 %y)
186  %tmp1 = call i32 @smax(i32 %y, i32 %x)
187  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
188  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
189  store i32 %tmp3, i32 addrspace(1)* %arg
190  ret void
191}
192
193; GCN-LABEL: {{^}}s_test_smed3_i32_pat_2:
194; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
195define amdgpu_kernel void @s_test_smed3_i32_pat_2(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
196bb:
197  %tmp0 = call i32 @smin(i32 %x, i32 %y)
198  %tmp1 = call i32 @smax(i32 %x, i32 %y)
199  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
200  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
201  store i32 %tmp3, i32 addrspace(1)* %arg
202  ret void
203}
204
205; GCN-LABEL: {{^}}s_test_smed3_i32_pat_3:
206; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
207define amdgpu_kernel void @s_test_smed3_i32_pat_3(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
208bb:
209  %tmp0 = call i32 @smin(i32 %x, i32 %y)
210  %tmp1 = call i32 @smax(i32 %y, i32 %x)
211  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
212  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
213  store i32 %tmp3, i32 addrspace(1)* %arg
214  ret void
215}
216
217; GCN-LABEL: {{^}}s_test_smed3_i32_pat_4:
218; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
219define amdgpu_kernel void @s_test_smed3_i32_pat_4(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
220bb:
221  %tmp0 = call i32 @smin(i32 %y, i32 %x)
222  %tmp1 = call i32 @smax(i32 %x, i32 %y)
223  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
224  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
225  store i32 %tmp3, i32 addrspace(1)* %arg
226  ret void
227}
228
229; GCN-LABEL: {{^}}s_test_smed3_i32_pat_5:
230; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
231define amdgpu_kernel void @s_test_smed3_i32_pat_5(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
232bb:
233  %tmp0 = call i32 @smin(i32 %y, i32 %x)
234  %tmp1 = call i32 @smax(i32 %y, i32 %x)
235  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
236  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
237  store i32 %tmp3, i32 addrspace(1)* %arg
238  ret void
239}
240
241; GCN-LABEL: {{^}}s_test_smed3_i32_pat_6:
242; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
243define amdgpu_kernel void @s_test_smed3_i32_pat_6(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
244bb:
245  %tmp0 = call i32 @smin(i32 %y, i32 %x)
246  %tmp1 = call i32 @smax(i32 %x, i32 %y)
247  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
248  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
249  store i32 %tmp3, i32 addrspace(1)* %arg
250  ret void
251}
252
253; GCN-LABEL: {{^}}s_test_smed3_i32_pat_7:
254; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
255define amdgpu_kernel void @s_test_smed3_i32_pat_7(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
256bb:
257  %tmp0 = call i32 @smin(i32 %y, i32 %x)
258  %tmp1 = call i32 @smax(i32 %y, i32 %x)
259  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
260  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
261  store i32 %tmp3, i32 addrspace(1)* %arg
262  ret void
263}
264
265; GCN-LABEL: {{^}}s_test_smed3_i32_pat_8:
266; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
267define amdgpu_kernel void @s_test_smed3_i32_pat_8(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
268bb:
269  %tmp0 = call i32 @smin(i32 %x, i32 %y)
270  %tmp1 = call i32 @smax(i32 %x, i32 %y)
271  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
272  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
273  store i32 %tmp3, i32 addrspace(1)* %arg
274  ret void
275}
276
277; GCN-LABEL: {{^}}s_test_smed3_i32_pat_9:
278; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
279define amdgpu_kernel void @s_test_smed3_i32_pat_9(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
280bb:
281  %tmp0 = call i32 @smin(i32 %x, i32 %y)
282  %tmp1 = call i32 @smax(i32 %y, i32 %x)
283  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
284  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
285  store i32 %tmp3, i32 addrspace(1)* %arg
286  ret void
287}
288
289; GCN-LABEL: {{^}}s_test_smed3_i32_pat_10:
290; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
291define amdgpu_kernel void @s_test_smed3_i32_pat_10(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
292bb:
293  %tmp0 = call i32 @smin(i32 %x, i32 %y)
294  %tmp1 = call i32 @smax(i32 %x, i32 %y)
295  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
296  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
297  store i32 %tmp3, i32 addrspace(1)* %arg
298  ret void
299}
300
301; GCN-LABEL: {{^}}s_test_smed3_i32_pat_11:
302; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
303define amdgpu_kernel void @s_test_smed3_i32_pat_11(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
304bb:
305  %tmp0 = call i32 @smin(i32 %x, i32 %y)
306  %tmp1 = call i32 @smax(i32 %y, i32 %x)
307  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
308  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
309  store i32 %tmp3, i32 addrspace(1)* %arg
310  ret void
311}
312
313; GCN-LABEL: {{^}}s_test_smed3_i32_pat_12:
314; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
315define amdgpu_kernel void @s_test_smed3_i32_pat_12(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
316bb:
317  %tmp0 = call i32 @smin(i32 %y, i32 %x)
318  %tmp1 = call i32 @smax(i32 %x, i32 %y)
319  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
320  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
321  store i32 %tmp3, i32 addrspace(1)* %arg
322  ret void
323}
324
325; GCN-LABEL: {{^}}s_test_smed3_i32_pat_13:
326; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
327define amdgpu_kernel void @s_test_smed3_i32_pat_13(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
328bb:
329  %tmp0 = call i32 @smin(i32 %y, i32 %x)
330  %tmp1 = call i32 @smax(i32 %y, i32 %x)
331  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
332  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
333  store i32 %tmp3, i32 addrspace(1)* %arg
334  ret void
335}
336
337; GCN-LABEL: {{^}}s_test_smed3_i32_pat_14:
338; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
339define amdgpu_kernel void @s_test_smed3_i32_pat_14(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
340bb:
341  %tmp0 = call i32 @smin(i32 %y, i32 %x)
342  %tmp1 = call i32 @smax(i32 %x, i32 %y)
343  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
344  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
345  store i32 %tmp3, i32 addrspace(1)* %arg
346  ret void
347}
348
349; GCN-LABEL: {{^}}s_test_smed3_i32_pat_15:
350; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
351define amdgpu_kernel void @s_test_smed3_i32_pat_15(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
352bb:
353  %tmp0 = call i32 @smin(i32 %y, i32 %x)
354  %tmp1 = call i32 @smax(i32 %y, i32 %x)
355  %tmp2 = call i32 @smin(i32 %z, i32 %tmp1)
356  %tmp3 = call i32 @smax(i32 %tmp2, i32 %tmp0)
357  store i32 %tmp3, i32 addrspace(1)* %arg
358  ret void
359}
360
361; 16 combinations
362
363; 16: min(max(x, y), max(min(x, y), z))
364; 17: min(max(x, y), max(min(y, x), z))
365; 18: min(max(x, y), max(z, min(x, y)))
366; 19: min(max(x, y), max(z, min(y, x)))
367; 20: min(max(y, x), max(min(x, y), z))
368; 21: min(max(y, x), max(min(y, x), z))
369; 22: min(max(y, x), max(z, min(x, y)))
370; 23: min(max(y, x), max(z, min(y, x)))
371;
372; + commute outermost min
373
374; GCN-LABEL: {{^}}s_test_smed3_i32_pat_16:
375; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
376define amdgpu_kernel void @s_test_smed3_i32_pat_16(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
377bb:
378  %tmp0 = call i32 @smin(i32 %x, i32 %y)
379  %tmp1 = call i32 @smax(i32 %x, i32 %y)
380  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
381  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
382  store i32 %tmp3, i32 addrspace(1)* %arg
383  ret void
384}
385
386; GCN-LABEL: {{^}}s_test_smed3_i32_pat_17:
387; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
388define amdgpu_kernel void @s_test_smed3_i32_pat_17(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
389bb:
390  %tmp0 = call i32 @smin(i32 %y, i32 %x)
391  %tmp1 = call i32 @smax(i32 %x, i32 %y)
392  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
393  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
394  store i32 %tmp3, i32 addrspace(1)* %arg
395  ret void
396}
397
398; GCN-LABEL: {{^}}s_test_smed3_i32_pat_18:
399; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
400define amdgpu_kernel void @s_test_smed3_i32_pat_18(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 @smax(i32 %z, i32 %tmp0)
405  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
406  store i32 %tmp3, i32 addrspace(1)* %arg
407  ret void
408}
409
410; GCN-LABEL: {{^}}s_test_smed3_i32_pat_19:
411; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
412define amdgpu_kernel void @s_test_smed3_i32_pat_19(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
413bb:
414  %tmp0 = call i32 @smin(i32 %y, i32 %x)
415  %tmp1 = call i32 @smax(i32 %x, i32 %y)
416  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
417  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
418  store i32 %tmp3, i32 addrspace(1)* %arg
419  ret void
420}
421
422; GCN-LABEL: {{^}}s_test_smed3_i32_pat_20:
423; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
424define amdgpu_kernel void @s_test_smed3_i32_pat_20(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
425bb:
426  %tmp0 = call i32 @smin(i32 %x, i32 %y)
427  %tmp1 = call i32 @smax(i32 %y, i32 %x)
428  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
429  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
430  store i32 %tmp3, i32 addrspace(1)* %arg
431  ret void
432}
433
434; GCN-LABEL: {{^}}s_test_smed3_i32_pat_21:
435; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
436define amdgpu_kernel void @s_test_smed3_i32_pat_21(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
437bb:
438  %tmp0 = call i32 @smin(i32 %y, i32 %x)
439  %tmp1 = call i32 @smax(i32 %y, i32 %x)
440  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
441  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
442  store i32 %tmp3, i32 addrspace(1)* %arg
443  ret void
444}
445
446; GCN-LABEL: {{^}}s_test_smed3_i32_pat_22:
447; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
448define amdgpu_kernel void @s_test_smed3_i32_pat_22(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
449bb:
450  %tmp0 = call i32 @smin(i32 %x, i32 %y)
451  %tmp1 = call i32 @smax(i32 %y, i32 %x)
452  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
453  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
454  store i32 %tmp3, i32 addrspace(1)* %arg
455  ret void
456}
457
458; GCN-LABEL: {{^}}s_test_smed3_i32_pat_23:
459; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
460define amdgpu_kernel void @s_test_smed3_i32_pat_23(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
461bb:
462  %tmp0 = call i32 @smin(i32 %y, i32 %x)
463  %tmp1 = call i32 @smax(i32 %y, i32 %x)
464  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
465  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
466  store i32 %tmp3, i32 addrspace(1)* %arg
467  ret void
468}
469
470; GCN-LABEL: {{^}}s_test_smed3_i32_pat_24:
471; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
472define amdgpu_kernel void @s_test_smed3_i32_pat_24(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
473bb:
474  %tmp0 = call i32 @smin(i32 %x, i32 %y)
475  %tmp1 = call i32 @smax(i32 %x, i32 %y)
476  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
477  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
478  store i32 %tmp3, i32 addrspace(1)* %arg
479  ret void
480}
481
482; GCN-LABEL: {{^}}s_test_smed3_i32_pat_25:
483; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
484define amdgpu_kernel void @s_test_smed3_i32_pat_25(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
485bb:
486  %tmp0 = call i32 @smin(i32 %y, i32 %x)
487  %tmp1 = call i32 @smax(i32 %x, i32 %y)
488  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
489  %tmp3 = call i32 @smin(i32 %tmp1, i32 %tmp2)
490  store i32 %tmp3, i32 addrspace(1)* %arg
491  ret void
492}
493
494; GCN-LABEL: {{^}}s_test_smed3_i32_pat_26:
495; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
496define amdgpu_kernel void @s_test_smed3_i32_pat_26(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
497bb:
498  %tmp0 = call i32 @smin(i32 %x, i32 %y)
499  %tmp1 = call i32 @smax(i32 %x, i32 %y)
500  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
501  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
502  store i32 %tmp3, i32 addrspace(1)* %arg
503  ret void
504}
505
506; GCN-LABEL: {{^}}s_test_smed3_i32_pat_27:
507; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
508define amdgpu_kernel void @s_test_smed3_i32_pat_27(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
509bb:
510  %tmp0 = call i32 @smin(i32 %y, i32 %x)
511  %tmp1 = call i32 @smax(i32 %x, i32 %y)
512  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
513  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
514  store i32 %tmp3, i32 addrspace(1)* %arg
515  ret void
516}
517
518; GCN-LABEL: {{^}}s_test_smed3_i32_pat_28:
519; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
520define amdgpu_kernel void @s_test_smed3_i32_pat_28(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
521bb:
522  %tmp0 = call i32 @smin(i32 %x, i32 %y)
523  %tmp1 = call i32 @smax(i32 %y, i32 %x)
524  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
525  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
526  store i32 %tmp3, i32 addrspace(1)* %arg
527  ret void
528}
529
530; GCN-LABEL: {{^}}s_test_smed3_i32_pat_29:
531; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
532define amdgpu_kernel void @s_test_smed3_i32_pat_29(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
533bb:
534  %tmp0 = call i32 @smin(i32 %y, i32 %x)
535  %tmp1 = call i32 @smax(i32 %y, i32 %x)
536  %tmp2 = call i32 @smax(i32 %tmp0, i32 %z)
537  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
538  store i32 %tmp3, i32 addrspace(1)* %arg
539  ret void
540}
541
542; GCN-LABEL: {{^}}s_test_smed3_i32_pat_30:
543; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
544define amdgpu_kernel void @s_test_smed3_i32_pat_30(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
545bb:
546  %tmp0 = call i32 @smin(i32 %x, i32 %y)
547  %tmp1 = call i32 @smax(i32 %y, i32 %x)
548  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
549  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
550  store i32 %tmp3, i32 addrspace(1)* %arg
551  ret void
552}
553
554; GCN-LABEL: {{^}}s_test_smed3_i32_pat_31:
555; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
556define amdgpu_kernel void @s_test_smed3_i32_pat_31(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
557bb:
558  %tmp0 = call i32 @smin(i32 %y, i32 %x)
559  %tmp1 = call i32 @smax(i32 %y, i32 %x)
560  %tmp2 = call i32 @smax(i32 %z, i32 %tmp0)
561  %tmp3 = call i32 @smin(i32 %tmp2, i32 %tmp1)
562  store i32 %tmp3, i32 addrspace(1)* %arg
563  ret void
564}
565
566; FIXME: Should keep scalar or not promote
567; GCN-LABEL: {{^}}s_test_smed3_i16_pat_0:
568; GCN: s_sext_i32_i16
569; GCN: s_sext_i32_i16
570; GCN: s_sext_i32_i16
571; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
572define 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 {
573bb:
574  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
575  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
576  %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
577  %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
578  store i16 %tmp3, i16 addrspace(1)* %arg
579  ret void
580}
581
582; GCN-LABEL: {{^}}s_test_smed3_i8_pat_0:
583; GCN: s_sext_i32_i8
584; GCN: s_sext_i32_i8
585; GCN: s_sext_i32_i8
586; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
587define 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 {
588bb:
589  %tmp0 = call i8 @smin8(i8 %x, i8 %y)
590  %tmp1 = call i8 @smax8(i8 %x, i8 %y)
591  %tmp2 = call i8 @smin8(i8 %tmp1, i8 %z)
592  %tmp3 = call i8 @smax8(i8 %tmp0, i8 %tmp2)
593  store i8 %tmp3, i8 addrspace(1)* %arg
594  ret void
595}
596
597; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_0:
598; GCN-NOT: v_med3_i32
599define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_0(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 %tmp0, 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_1:
611; GCN-NOT: v_med3_i32
612define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_1(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 %tmp1, 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_2:
624; GCN-NOT: v_med3_i32
625define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_2(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 %tmp2, i32 addrspace(1)* %arg
632  store volatile i32 %tmp3, i32 addrspace(1)* %arg
633  ret void
634}
635
636; GCN-LABEL: {{^}}s_test_smed3_i32_pat_0_multi_use_result:
637; GCN: v_med3_i32 v{{[0-9]+}}, s{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
638define amdgpu_kernel void @s_test_smed3_i32_pat_0_multi_use_result(i32 addrspace(1)* %arg, i32 %x, i32 %y, i32 %z) #1 {
639bb:
640  %tmp0 = call i32 @smin(i32 %x, i32 %y)
641  %tmp1 = call i32 @smax(i32 %x, i32 %y)
642  %tmp2 = call i32 @smin(i32 %tmp1, i32 %z)
643  %tmp3 = call i32 @smax(i32 %tmp0, i32 %tmp2)
644  store volatile i32 %tmp3, i32 addrspace(1)* %arg
645  store volatile i32 %tmp3, i32 addrspace(1)* %arg
646  ret void
647}
648
649; GCN-LABEL: {{^}}v_test_smed3_i16_pat_0:
650; SI: v_med3_i32 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
651
652; FIXME: VI not matching med3
653; VI: v_min_i16
654; VI: v_max_i16
655; VI: v_min_i16
656; VI: v_max_i16
657
658; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
659define amdgpu_kernel void @v_test_smed3_i16_pat_0(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
660bb:
661  %tid = call i32 @llvm.amdgcn.workitem.id.x()
662  %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
663  %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
664  %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
665  %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
666  %x = load i16, i16 addrspace(1)* %gep0
667  %y = load i16, i16 addrspace(1)* %gep1
668  %z = load i16, i16 addrspace(1)* %gep2
669
670  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
671  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
672  %tmp2 = call i16 @smin16(i16 %tmp1, i16 %z)
673  %tmp3 = call i16 @smax16(i16 %tmp0, i16 %tmp2)
674  store i16 %tmp3, i16 addrspace(1)* %out.gep
675  ret void
676}
677
678; GCN-LABEL: {{^}}v_test_smed3_i16_pat_1:
679; GFX9: v_med3_i16 v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}, v{{[0-9]+}}
680
681define amdgpu_kernel void @v_test_smed3_i16_pat_1(i16 addrspace(1)* %arg, i16 addrspace(1)* %out, i16 addrspace(1)* %a.ptr) #1 {
682bb:
683  %tid = call i32 @llvm.amdgcn.workitem.id.x()
684  %gep0 = getelementptr inbounds i16, i16 addrspace(1)* %a.ptr, i32 %tid
685  %gep1 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 3
686  %gep2 = getelementptr inbounds i16, i16 addrspace(1)* %gep0, i32 8
687  %out.gep = getelementptr inbounds i16, i16 addrspace(1)* %out, i32 %tid
688  %x = load i16, i16 addrspace(1)* %gep0
689  %y = load i16, i16 addrspace(1)* %gep1
690  %z = load i16, i16 addrspace(1)* %gep2
691
692  %tmp0 = call i16 @smin16(i16 %x, i16 %y)
693  %tmp1 = call i16 @smax16(i16 %x, i16 %y)
694  %tmp2 = call i16 @smax16(i16 %tmp0, i16 %z)
695  %tmp3 = call i16 @smin16(i16 %tmp1, i16 %tmp2)
696  store i16 %tmp3, i16 addrspace(1)* %out.gep
697  ret void
698}
699
700attributes #0 = { nounwind readnone }
701attributes #1 = { nounwind }
702attributes #2 = { nounwind readnone alwaysinline }
703