[InstCombine] Signed saturation patterns
[llvm-core.git] / test / CodeGen / AMDGPU / max.ll
blobb53d65e1bc300892597ae61a1ae67dfeff2c6c8a
1 ; RUN: llc -march=amdgcn -mcpu=pitcairn < %s | FileCheck -enable-var-scope -check-prefix=SI -check-prefix=FUNC %s
2 ; RUN: llc -march=r600 -mcpu=cypress < %s | FileCheck -enable-var-scope -check-prefix=EG -check-prefix=FUNC %s
5 ; FUNC-LABEL: {{^}}v_test_imax_sge_i32:
6 ; SI: v_max_i32_e32
8 ; EG: MAX_INT
9 define amdgpu_kernel void @v_test_imax_sge_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
10   %tid = call i32 @llvm.r600.read.tidig.x()
11   %gep.in = getelementptr inbounds i32, i32 addrspace(1)* %bptr, i32 %tid
12   %a = load i32, i32 addrspace(1)* %aptr, align 4
13   %b = load i32, i32 addrspace(1)* %gep.in, align 4
14   %cmp = icmp sge i32 %a, %b
15   %val = select i1 %cmp, i32 %a, i32 %b
16   store i32 %val, i32 addrspace(1)* %out, align 4
17   ret void
20 ; FUNC-LABEL: {{^}}v_test_imax_sge_v4i32:
21 ; SI: v_max_i32_e32
22 ; SI: v_max_i32_e32
23 ; SI: v_max_i32_e32
24 ; SI: v_max_i32_e32
26 ; These could be merged into one
27 ; EG: MAX_INT
28 ; EG: MAX_INT
29 ; EG: MAX_INT
30 ; EG: MAX_INT
31 define amdgpu_kernel void @v_test_imax_sge_v4i32(<4 x i32> addrspace(1)* %out, <4 x i32> addrspace(1)* %aptr, <4 x i32> addrspace(1)* %bptr) nounwind {
32   %tid = call i32 @llvm.r600.read.tidig.x()
33   %gep.in = getelementptr inbounds <4 x i32>, <4 x i32> addrspace(1)* %bptr, i32 %tid
34   %a = load <4 x i32>, <4 x i32> addrspace(1)* %aptr, align 4
35   %b = load <4 x i32>, <4 x i32> addrspace(1)* %gep.in, align 4
36   %cmp = icmp sge <4 x i32> %a, %b
37   %val = select <4 x i1> %cmp, <4 x i32> %a, <4 x i32> %b
38   store <4 x i32> %val, <4 x i32> addrspace(1)* %out, align 4
39   ret void
42 ; FUNC-LABEL: @s_test_imax_sge_i32
43 ; SI: s_max_i32
45 ; EG: MAX_INT
46 define amdgpu_kernel void @s_test_imax_sge_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
47   %cmp = icmp sge i32 %a, %b
48   %val = select i1 %cmp, i32 %a, i32 %b
49   store i32 %val, i32 addrspace(1)* %out, align 4
50   ret void
53 ; FUNC-LABEL: {{^}}s_test_imax_sge_imm_i32:
54 ; SI: s_max_i32 {{s[0-9]+}}, {{s[0-9]+}}, 9
56 ; EG: MAX_INT {{.*}}literal.{{[xyzw]}}
57 define amdgpu_kernel void @s_test_imax_sge_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
58   %cmp = icmp sge i32 %a, 9
59   %val = select i1 %cmp, i32 %a, i32 9
60   store i32 %val, i32 addrspace(1)* %out, align 4
61   ret void
64 ; FUNC-LABEL: {{^}}v_test_imax_sge_i8:
65 ; SI: buffer_load_sbyte
66 ; SI: buffer_load_sbyte
67 ; SI: v_max_i32_e32
69 ; EG: MAX_INT
70 define amdgpu_kernel void @v_test_imax_sge_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %aptr, i8 addrspace(1)* %bptr) nounwind {
71   %a = load i8, i8 addrspace(1)* %aptr, align 1
72   %b = load i8, i8 addrspace(1)* %bptr, align 1
73   %cmp = icmp sge i8 %a, %b
74   %val = select i1 %cmp, i8 %a, i8 %b
75   store i8 %val, i8 addrspace(1)* %out, align 1
76   ret void
79 ; FUNC-LABEL: {{^}}s_test_imax_sgt_imm_i32:
80 ; SI: s_max_i32 {{s[0-9]+}}, {{s[0-9]+}}, 9
82 ; EG: MAX_INT {{.*}}literal.{{[xyzw]}}
83 define amdgpu_kernel void @s_test_imax_sgt_imm_i32(i32 addrspace(1)* %out, i32 %a) nounwind {
84   %cmp = icmp sgt i32 %a, 9
85   %val = select i1 %cmp, i32 %a, i32 9
86   store i32 %val, i32 addrspace(1)* %out, align 4
87   ret void
90 ; FUNC-LABEL: {{^}}s_test_imax_sgt_imm_v2i32:
91 ; SI: s_max_i32 {{s[0-9]+}}, {{s[0-9]+}}, 9
92 ; SI: s_max_i32 {{s[0-9]+}}, {{s[0-9]+}}, 9
94 ; EG: MAX_INT {{.*}}literal.{{[xyzw]}}
95 ; EG: MAX_INT {{.*}}literal.{{[xyzw]}}
96 define amdgpu_kernel void @s_test_imax_sgt_imm_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a) nounwind {
97   %cmp = icmp sgt <2 x i32> %a, <i32 9, i32 9>
98   %val = select <2 x i1> %cmp, <2 x i32> %a, <2 x i32> <i32 9, i32 9>
99   store <2 x i32> %val, <2 x i32> addrspace(1)* %out, align 4
100   ret void
103 ; FUNC-LABEL: @v_test_imax_sgt_i32
104 ; SI: v_max_i32_e32
106 ; EG: MAX_INT
107 define amdgpu_kernel void @v_test_imax_sgt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
108   %tid = call i32 @llvm.r600.read.tidig.x()
109   %gep.in = getelementptr inbounds i32, i32 addrspace(1)* %bptr, i32 %tid
110   %a = load i32, i32 addrspace(1)* %aptr, align 4
111   %b = load i32, i32 addrspace(1)* %gep.in, align 4
112   %cmp = icmp sgt i32 %a, %b
113   %val = select i1 %cmp, i32 %a, i32 %b
114   store i32 %val, i32 addrspace(1)* %out, align 4
115   ret void
118 ; FUNC-LABEL: @s_test_imax_sgt_i32
119 ; SI: s_max_i32
121 ; EG: MAX_INT
122 define amdgpu_kernel void @s_test_imax_sgt_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
123   %cmp = icmp sgt i32 %a, %b
124   %val = select i1 %cmp, i32 %a, i32 %b
125   store i32 %val, i32 addrspace(1)* %out, align 4
126   ret void
129 ; FUNC-LABEL: @v_test_umax_uge_i32
130 ; SI: v_max_u32_e32
132 ; EG: MAX_UINT
133 define amdgpu_kernel void @v_test_umax_uge_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
134   %tid = call i32 @llvm.r600.read.tidig.x()
135   %gep.in = getelementptr inbounds i32, i32 addrspace(1)* %bptr, i32 %tid
136   %a = load i32, i32 addrspace(1)* %aptr, align 4
137   %b = load i32, i32 addrspace(1)* %gep.in, align 4
138   %cmp = icmp uge i32 %a, %b
139   %val = select i1 %cmp, i32 %a, i32 %b
140   store i32 %val, i32 addrspace(1)* %out, align 4
141   ret void
144 ; FUNC-LABEL: @s_test_umax_uge_i32
145 ; SI: s_max_u32
147 ; EG: MAX_UINT
148 define amdgpu_kernel void @s_test_umax_uge_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
149   %cmp = icmp uge i32 %a, %b
150   %val = select i1 %cmp, i32 %a, i32 %b
151   store i32 %val, i32 addrspace(1)* %out, align 4
152   ret void
155 ; FUNC-LABEL: {{^}}s_test_umax_uge_v3i32:
156 ; SI: s_max_u32
157 ; SI: s_max_u32
158 ; SI: s_max_u32
159 ; SI-NOT: s_max_u32
160 ; SI: s_endpgm
162 ; EG: MAX_UINT
163 ; EG: MAX_UINT
164 ; EG: MAX_UINT
165 ; EG-NOT: MAX_UINT
166 define amdgpu_kernel void @s_test_umax_uge_v3i32(<3 x i32> addrspace(1)* %out, <3 x i32> %a, <3 x i32> %b) nounwind {
167   %cmp = icmp uge <3 x i32> %a, %b
168   %val = select <3 x i1> %cmp, <3 x i32> %a, <3 x i32> %b
169   store <3 x i32> %val, <3 x i32> addrspace(1)* %out, align 4
170   ret void
173 ; FUNC-LABEL: {{^}}v_test_umax_uge_i8:
174 ; SI: buffer_load_ubyte
175 ; SI: buffer_load_ubyte
176 ; SI: v_max_u32_e32
178 ; EG: MAX_UINT
179 define amdgpu_kernel void @v_test_umax_uge_i8(i8 addrspace(1)* %out, i8 addrspace(1)* %aptr, i8 addrspace(1)* %bptr) nounwind {
180   %a = load i8, i8 addrspace(1)* %aptr, align 1
181   %b = load i8, i8 addrspace(1)* %bptr, align 1
182   %cmp = icmp uge i8 %a, %b
183   %val = select i1 %cmp, i8 %a, i8 %b
184   store i8 %val, i8 addrspace(1)* %out, align 1
185   ret void
188 ; FUNC-LABEL: @v_test_umax_ugt_i32
189 ; SI: v_max_u32_e32
191 ; EG: MAX_UINT
192 define amdgpu_kernel void @v_test_umax_ugt_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %aptr, i32 addrspace(1)* %bptr) nounwind {
193   %tid = call i32 @llvm.r600.read.tidig.x()
194   %gep.in = getelementptr inbounds i32, i32 addrspace(1)* %bptr, i32 %tid
195   %a = load i32, i32 addrspace(1)* %gep.in, align 4
196   %b = load i32, i32 addrspace(1)* %bptr, align 4
197   %cmp = icmp ugt i32 %a, %b
198   %val = select i1 %cmp, i32 %a, i32 %b
199   store i32 %val, i32 addrspace(1)* %out, align 4
200   ret void
203 ; FUNC-LABEL: {{^}}s_test_umax_ugt_i32:
204 ; SI: s_max_u32
206 ; EG: MAX_UINT
207 define amdgpu_kernel void @s_test_umax_ugt_i32(i32 addrspace(1)* %out, i32 %a, i32 %b) nounwind {
208   %cmp = icmp ugt i32 %a, %b
209   %val = select i1 %cmp, i32 %a, i32 %b
210   store i32 %val, i32 addrspace(1)* %out, align 4
211   ret void
214 ; FUNC-LABEL: {{^}}s_test_umax_ugt_imm_v2i32:
215 ; SI-DAG: s_max_u32 {{s[0-9]+}}, {{s[0-9]+}}, 15
216 ; SI-DAG: s_max_u32 {{s[0-9]+}}, {{s[0-9]+}}, 23
218 ; EG: MAX_UINT {{.*}}literal.{{[xyzw]}}
219 ; EG: MAX_UINT {{.*}}literal.{{[xyzw]}}
220 define amdgpu_kernel void @s_test_umax_ugt_imm_v2i32(<2 x i32> addrspace(1)* %out, <2 x i32> %a) nounwind {
221   %cmp = icmp ugt <2 x i32> %a, <i32 15, i32 23>
222   %val = select <2 x i1> %cmp, <2 x i32> %a, <2 x i32> <i32 15, i32 23>
223   store <2 x i32> %val, <2 x i32> addrspace(1)* %out, align 4
224   ret void
227 ; Make sure redundant and removed
228 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_umax_ugt_i16:
229 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0x13
230 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0x1c
231 ; SI: s_max_u32 [[MAX:s[0-9]+]], [[A]], [[B]]
232 ; SI: v_mov_b32_e32 [[VMAX:v[0-9]+]], [[MAX]]
233 ; SI: buffer_store_dword [[VMAX]]
235 ; EG: MAX_UINT
236 define amdgpu_kernel void @simplify_demanded_bits_test_umax_ugt_i16(i32 addrspace(1)* %out, [8 x i32], i16 zeroext %a, [8 x i32], i16 zeroext %b) nounwind {
237   %a.ext = zext i16 %a to i32
238   %b.ext = zext i16 %b to i32
239   %cmp = icmp ugt i32 %a.ext, %b.ext
240   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
241   %mask = and i32 %val, 65535
242   store i32 %mask, i32 addrspace(1)* %out
243   ret void
246 ; Make sure redundant sign_extend_inreg removed.
248 ; FUNC-LABEL: {{^}}simplify_demanded_bits_test_max_slt_i16:
249 ; SI-DAG: s_load_dword [[A:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0x13
250 ; SI-DAG: s_load_dword [[B:s[0-9]+]], {{s\[[0-9]+:[0-9]+\]}}, 0x1c
251 ; SI-DAG: s_sext_i32_i16 [[EXT_A:s[0-9]+]], [[A]]
252 ; SI-DAG: s_sext_i32_i16 [[EXT_B:s[0-9]+]], [[B]]
254 ; SI: s_max_i32 [[MAX:s[0-9]+]], [[EXT_A]], [[EXT_B]]
255 ; SI: v_mov_b32_e32 [[VMAX:v[0-9]+]], [[MAX]]
256 ; SI: buffer_store_dword [[VMAX]]
258 ; EG: MAX_INT
259 define amdgpu_kernel void @simplify_demanded_bits_test_max_slt_i16(i32 addrspace(1)* %out, [8 x i32], i16 signext %a, [8 x i32], i16 signext %b) nounwind {
260   %a.ext = sext i16 %a to i32
261   %b.ext = sext i16 %b to i32
262   %cmp = icmp sgt i32 %a.ext, %b.ext
263   %val = select i1 %cmp, i32 %a.ext, i32 %b.ext
264   %shl = shl i32 %val, 16
265   %sextinreg = ashr i32 %shl, 16
266   store i32 %sextinreg, i32 addrspace(1)* %out
267   ret void
270 ; FUNC-LABEL: {{^}}s_test_imax_sge_i16:
271 ; SI: s_load_dword
272 ; SI: s_load_dword
273 ; SI: s_sext_i32_i16
274 ; SI: s_sext_i32_i16
275 ; SI: s_max_i32
277 ; EG: MAX_INT
278 define amdgpu_kernel void @s_test_imax_sge_i16(i16 addrspace(1)* %out, [8 x i32], i16 %a, [8 x i32], i16 %b) nounwind {
279   %cmp = icmp sge i16 %a, %b
280   %val = select i1 %cmp, i16 %a, i16 %b
281   store i16 %val, i16 addrspace(1)* %out
282   ret void
285 ; 64 bit
286 ; FUNC-LABEL: {{^}}test_umax_ugt_i64
287 ; SI: s_endpgm
289 ; EG: MAX_UINT
290 ; EG: MAX_UINT
291 define amdgpu_kernel void @test_umax_ugt_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
292   %tmp = icmp ugt i64 %a, %b
293   %val = select i1 %tmp, i64 %a, i64 %b
294   store i64 %val, i64 addrspace(1)* %out, align 8
295   ret void
298 ; FUNC-LABEL: {{^}}test_umax_uge_i64
299 ; SI: s_endpgm
301 ; EG: MAX_UINT
302 ; EG: MAX_UINT
303 define amdgpu_kernel void @test_umax_uge_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
304   %tmp = icmp uge i64 %a, %b
305   %val = select i1 %tmp, i64 %a, i64 %b
306   store i64 %val, i64 addrspace(1)* %out, align 8
307   ret void
310 ; FUNC-LABEL: {{^}}test_imax_sgt_i64
311 ; SI: s_endpgm
313 ; EG-DAG: MAX_UINT
314 ; EG-DAG: MAX_INT
315 define amdgpu_kernel void @test_imax_sgt_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
316   %tmp = icmp sgt i64 %a, %b
317   %val = select i1 %tmp, i64 %a, i64 %b
318   store i64 %val, i64 addrspace(1)* %out, align 8
319   ret void
322 ; FUNC-LABEL: {{^}}test_imax_sge_i64
323 ; SI: s_endpgm
325 ; EG-DAG: MAX_UINT
326 ; EG-DAG: MAX_INT
327 define amdgpu_kernel void @test_imax_sge_i64(i64 addrspace(1)* %out, i64 %a, i64 %b) nounwind {
328   %tmp = icmp sge i64 %a, %b
329   %val = select i1 %tmp, i64 %a, i64 %b
330   store i64 %val, i64 addrspace(1)* %out, align 8
331   ret void
335 declare i32 @llvm.r600.read.tidig.x() #0
337 attributes #0 = { nounwind readnone }
338 attributes #1 = { nounwind }