Revert "[AArch64] Add DAG combine for extract extend pattern"
[oota-llvm.git] / test / CodeGen / AMDGPU / min.ll
1 ; RUN: llc -march=amdgcn -mcpu=SI < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
2
3 declare i32 @llvm.r600.read.tidig.x() nounwind readnone
4
5 ; FUNC-LABEL: {{^}}v_test_imin_sle_i32:
6 ; SI: v_min_i32_e32
7 define void @v_test_imin_sle_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
8   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
9   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
10   %gep1 = getelementptr i32, i32 addrspace(1)* %bptr, i32 %tid
11   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
12   %a = load i32, i32 addrspace(1)* %gep0, align 4
13   %b = load i32, i32 addrspace(1)* %gep1, align 4
14   %cmp = icmp sle i32 %a, %b
15   %val = select i1 %cmp, i32 %a, i32 %b
16   store i32 %val, i32 addrspace(1)* %outgep, align 4
17   ret void
18 }
19
20 ; FUNC-LABEL: {{^}}s_test_imin_sle_i32:
21 ; SI: s_min_i32
22 define void @s_test_imin_sle_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
23   %cmp = icmp sle i32 %a, %b
24   %val = select i1 %cmp, i32 %a, i32 %b
25   store i32 %val, i32 addrspace(1)* %out, align 4
26   ret void
27 }
28
29 ; FUNC-LABEL: {{^}}s_test_imin_sle_v1i32:
30 ; SI: s_min_i32
31 define void @s_test_imin_sle_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
32   %cmp = icmp sle <1 x i32> %a, %b
33   %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
34   store <1 x i32> %val, <1 x i32> addrspace(1)* %out
35   ret void
36 }
37
38 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i32:
39 ; SI: s_min_i32
40 ; SI: s_min_i32
41 ; SI: s_min_i32
42 ; SI: s_min_i32
43 define void @s_test_imin_sle_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> %a, <4 x i32> %b) nounwind {
44   %cmp = icmp sle <4 x i32> %a, %b
45   %val = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> %b
46   store <4 x i32> %val, <4 x i32> addrspace(1)* %out
47   ret void
48 }
49
50 ; FUNC-LABEL: {{^}}s_test_imin_sle_i8:
51 ; SI: s_min_i32
52 define void @s_test_imin_sle_i8(i8 addrspace(1)* %out, i8 %a, i8 %b) nounwind {
53   %cmp = icmp sle i8 %a, %b
54   %val = select i1 %cmp, i8 %a, i8 %b
55   store i8 %val, i8 addrspace(1)* %out
56   ret void
57 }
58
59 ; XXX - should be able to use s_min if we stop unnecessarily doing
60 ; extloads with mubuf instructions.
61
62 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i8:
63 ; SI: v_min_i32
64 ; SI: v_min_i32
65 ; SI: v_min_i32
66 ; SI: v_min_i32
67 define void @s_test_imin_sle_v4i8(<4 x i8> addrspace(1)* %out, <4 x i8> %a, <4 x i8> %b) nounwind {
68   %cmp = icmp sle <4 x i8> %a, %b
69   %val = select <4 x i1> %cmp, <4 x i8> %a, <4 x i8> %b
70   store <4 x i8> %val, <4 x i8> addrspace(1)* %out
71   ret void
72 }
73
74 ; FUNC-LABEL: {{^}}s_test_imin_sle_v4i16:
75 ; SI: v_min_i32
76 ; SI: v_min_i32
77 ; SI: v_min_i32
78 ; SI: v_min_i32
79 define void @s_test_imin_sle_v4i16(<4 x i16> addrspace(1)* %out, <4 x i16> %a, <4 x i16> %b) nounwind {
80   %cmp = icmp sle <4 x i16> %a, %b
81   %val = select <4 x i1> %cmp, <4 x i16> %a, <4 x i16> %b
82   store <4 x i16> %val, <4 x i16> addrspace(1)* %out
83   ret void
84 }
85
86 ; FUNC-LABEL: @v_test_imin_slt_i32
87 ; SI: v_min_i32_e32
88 define void @v_test_imin_slt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
89   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
90   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
91   %gep1 = getelementptr i32, i32 addrspace(1)* %bptr, i32 %tid
92   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
93   %a = load i32, i32 addrspace(1)* %gep0, align 4
94   %b = load i32, i32 addrspace(1)* %gep1, align 4
95   %cmp = icmp slt i32 %a, %b
96   %val = select i1 %cmp, i32 %a, i32 %b
97   store i32 %val, i32 addrspace(1)* %outgep, align 4
98   ret void
99 }
100
101 ; FUNC-LABEL: @s_test_imin_slt_i32
102 ; SI: s_min_i32
103 define void @s_test_imin_slt_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
104   %cmp = icmp slt i32 %a, %b
105   %val = select i1 %cmp, i32 %a, i32 %b
106   store i32 %val, i32 addrspace(1)* %out, align 4
107   ret void
108 }
109
110 ; FUNC-LABEL: {{^}}s_test_imin_slt_v2i32:
111 ; SI: s_min_i32
112 ; SI: s_min_i32
113 define void @s_test_imin_slt_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a, <2 x i32> %b) nounwind {
114   %cmp = icmp slt <2 x i32> %a, %b
115   %val = select <2 x i1> %cmp, <2 x i32> %a, <2 x i32> %b
116   store <2 x i32> %val, <2 x i32> addrspace(1)* %out
117   ret void
118 }
119
120 ; FUNC-LABEL: {{^}}s_test_imin_slt_imm_i32:
121 ; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
122 define void @s_test_imin_slt_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
123   %cmp = icmp slt i32 %a, 8
124   %val = select i1 %cmp, i32 %a, i32 8
125   store i32 %val, i32 addrspace(1)* %out, align 4
126   ret void
127 }
128
129 ; FUNC-LABEL: {{^}}s_test_imin_sle_imm_i32:
130 ; SI: s_min_i32 {{s[0-9]+}}, {{s[0-9]+}}, 8
131 define void @s_test_imin_sle_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
132   %cmp = icmp sle i32 %a, 8
133   %val = select i1 %cmp, i32 %a, i32 8
134   store i32 %val, i32 addrspace(1)* %out, align 4
135   ret void
136 }
137
138 ; FUNC-LABEL: @v_test_umin_ule_i32
139 ; SI: v_min_u32_e32
140 define void @v_test_umin_ule_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
141   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
142   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
143   %gep1 = getelementptr i32, i32 addrspace(1)* %bptr, i32 %tid
144   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
145   %a = load i32, i32 addrspace(1)* %gep0, align 4
146   %b = load i32, i32 addrspace(1)* %gep1, align 4
147   %cmp = icmp ule i32 %a, %b
148   %val = select i1 %cmp, i32 %a, i32 %b
149   store i32 %val, i32 addrspace(1)* %outgep, align 4
150   ret void
151 }
152
153 ; FUNC-LABEL: @v_test_umin_ule_v3i32
154 ; SI: v_min_u32_e32
155 ; SI: v_min_u32_e32
156 ; SI: v_min_u32_e32
157 ; SI-NOT: v_min_u32_e32
158 ; SI: s_endpgm
159 define void @v_test_umin_ule_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> addrspace(1)* %aptr, <3 x i32> addrspace(1)* %bptr) nounwind {
160   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
161   %gep0 = getelementptr <3 x i32>, <3 x i32> addrspace(1)* %aptr, i32 %tid
162   %gep1 = getelementptr <3 x i32>, <3 x i32> addrspace(1)* %bptr, i32 %tid
163   %outgep = getelementptr <3 x i32>, <3 x i32> addrspace(1)* %out, i32 %tid
164   %a = load <3 x i32>, <3 x i32> addrspace(1)* %gep0
165   %b = load <3 x i32>, <3 x i32> addrspace(1)* %gep1
166   %cmp = icmp ule <3 x i32> %a, %b
167   %val = select <3 x i1> %cmp, <3 x i32> %a, <3 x i32> %b
168   store <3 x i32> %val, <3 x i32> addrspace(1)* %outgep
169   ret void
170 }
171 ; FUNC-LABEL: @s_test_umin_ule_i32
172 ; SI: s_min_u32
173 define void @s_test_umin_ule_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
174   %cmp = icmp ule i32 %a, %b
175   %val = select i1 %cmp, i32 %a, i32 %b
176   store i32 %val, i32 addrspace(1)* %out, align 4
177   ret void
178 }
179
180 ; FUNC-LABEL: @v_test_umin_ult_i32
181 ; SI: v_min_u32_e32
182 define void @v_test_umin_ult_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
183   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
184   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
185   %gep1 = getelementptr i32, i32 addrspace(1)* %bptr, i32 %tid
186   %outgep = getelementptr i32, i32 addrspace(1)* %out, i32 %tid
187   %a = load i32, i32 addrspace(1)* %gep0, align 4
188   %b = load i32, i32 addrspace(1)* %gep1, align 4
189   %cmp = icmp ult i32 %a, %b
190   %val = select i1 %cmp, i32 %a, i32 %b
191   store i32 %val, i32 addrspace(1)* %outgep, align 4
192   ret void
193 }
194
195 ; FUNC-LABEL: @s_test_umin_ult_i32
196 ; SI: s_min_u32
197 define void @s_test_umin_ult_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
198   %cmp = icmp ult i32 %a, %b
199   %val = select i1 %cmp, i32 %a, i32 %b
200   store i32 %val, i32 addrspace(1)* %out, align 4
201   ret void
202 }
203
204 ; FUNC-LABEL: @v_test_umin_ult_i32_multi_use
205 ; SI-NOT: v_min
206 ; SI: v_cmp_lt_u32
207 ; SI-NEXT: v_cndmask_b32
208 ; SI-NOT: v_min
209 ; SI: s_endpgm
210 define void @v_test_umin_ult_i32_multi_use(i32 addrspace(1)* %out0, i1 addrspace(1)* %out1, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
211   %tid = call i32 @llvm.r600.read.tidig.x() nounwind readnone
212   %gep0 = getelementptr i32, i32 addrspace(1)* %aptr, i32 %tid
213   %gep1 = getelementptr i32, i32 addrspace(1)* %bptr, i32 %tid
214   %outgep0 = getelementptr i32, i32 addrspace(1)* %out0, i32 %tid
215   %outgep1 = getelementptr i1, i1 addrspace(1)* %out1, i32 %tid
216   %a = load i32, i32 addrspace(1)* %gep0, align 4
217   %b = load i32, i32 addrspace(1)* %gep1, align 4
218   %cmp = icmp ult i32 %a, %b
219   %val = select i1 %cmp, i32 %a, i32 %b
220   store i32 %val, i32 addrspace(1)* %outgep0, align 4
221   store i1 %cmp, i1 addrspace(1)* %outgep1
222   ret void
223 }
224
225
226 ; FUNC-LABEL: @s_test_umin_ult_v1i32
227 ; SI: s_min_u32
228 define void @s_test_umin_ult_v1i32(<1 x i32> addrspace(1)* %out, <1 x i32> %a, <1 x i32> %b) nounwind {
229   %cmp = icmp ult <1 x i32> %a, %b
230   %val = select <1 x i1> %cmp, <1 x i32> %a, <1 x i32> %b
231   store <1 x i32> %val, <1 x i32> addrspace(1)* %out
232   ret void
233 }
234
235 ; FUNC-LABEL: {{^}}s_test_umin_ult_v8i32:
236 ; SI: s_min_u32
237 ; SI: s_min_u32
238 ; SI: s_min_u32
239 ; SI: s_min_u32
240 ; SI: s_min_u32
241 ; SI: s_min_u32
242 ; SI: s_min_u32
243 ; SI: s_min_u32
244 define void @s_test_umin_ult_v8i32(<8 x i32> addrspace(1)* %out, <8 x i32> %a, <8 x i32> %b) nounwind {
245   %cmp = icmp ult <8 x i32> %a, %b
246   %val = select <8 x i1> %cmp, <8 x i32> %a, <8 x i32> %b
247   store <8 x i32> %val, <8 x i32> addrspace(1)* %out
248   ret void
249 }
250
251 ; FUNC-LABEL: {{^}}s_test_umin_ult_v8i16:
252 ; SI: v_min_u32
253 ; SI: v_min_u32
254 ; SI: v_min_u32
255 ; SI: v_min_u32
256 ; SI: v_min_u32
257 ; SI: v_min_u32
258 ; SI: v_min_u32
259 ; SI: v_min_u32
260 define void @s_test_umin_ult_v8i16(<8 x i16> addrspace(1)* %out, <8 x i16> %a, <8 x i16> %b) nounwind {
261   %cmp = icmp ult <8 x i16> %a, %b
262   %val = select <8 x i1> %cmp, <8 x i16> %a, <8 x i16> %b
263   store <8 x i16> %val, <8 x i16> addrspace(1)* %out
264   ret void
265 }
266
267 ; Make sure redundant and removed
268 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_umin_ult_i16:
269 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
270 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
271 ; SI: s_min_u32 [[MIN:s[0-9]+]], [[A]], [[B]]
272 ; SI-NEXT: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
273 ; SI-NEXT: buffer_store_dword [[VMIN]]
274 define void @simplify_demanded_bits_test_umin_ult_i16(i32 addrspace(1)* %out, i16 zeroext %a, i16 zeroext %b) nounwind {
275   %a.ext = zext i16 %a to i32
276   %b.ext = zext i16 %b to i32
277   %cmp = icmp ult i32 %a.ext, %b.ext
278   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
279   %mask = and i32 %val, 65535
280   store i32 %mask, i32 addrspace(1)* %out
281   ret void
282 }
283
284 ; Make sure redundant sign_extend_inreg removed.
285
286 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_min_slt_i16:
287 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xb
288 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0xc
289 ; SI: s_min_i32 [[MIN:s[0-9]+]], [[A]], [[B]]
290 ; SI-NEXT: v_mov_b32_e32 [[VMIN:v[0-9]+]], [[MIN]]
291 ; SI-NEXT: buffer_store_dword [[VMIN]]
292 define void @simplify_demanded_bits_test_min_slt_i16(i32 addrspace(1)* %out, i16 signext %a, i16 signext %b) nounwind {
293   %a.ext = sext i16 %a to i32
294   %b.ext = sext i16 %b to i32
295   %cmp = icmp slt i32 %a.ext, %b.ext
296   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
297   %shl = shl i32 %val, 16
298   %sextinreg = ashr i32 %shl, 16
299   store i32 %sextinreg, i32 addrspace(1)* %out
300   ret void
301 }
302
303 ; FUNC-LABEL: {{^}}s_test_imin_sle_i16:
304 ; SI: s_min_i32
305 define void @s_test_imin_sle_i16(i16 addrspace(1)* %out, i16 %a, i16 %b) nounwind {
306   %cmp = icmp sle i16 %a, %b
307   %val = select i1 %cmp, i16 %a, i16 %b
308   store i16 %val, i16 addrspace(1)* %out
309   ret void
310 }