[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / llvm / test / CodeGen / AMDGPU / cgp-addressing-modes.ll
blob0e61547c27b453b3b8a6a2a35e6061b3b94b9f08
1 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tahiti < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-SI -check-prefix=OPT-SICIVI %s
2 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=bonaire < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-CI -check-prefix=OPT-SICIVI %s
3 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tonga -mattr=-flat-for-global < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-VI -check-prefix=OPT-SICIVI %s
4 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=gfx900 < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-GFX9 %s
5 ; RUN: llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca -amdgpu-scalarize-global-loads=false < %s | FileCheck -check-prefix=GCN -check-prefix=SI -check-prefix=SICIVI %s
6 ; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca -amdgpu-scalarize-global-loads=false < %s | FileCheck -check-prefix=GCN -check-prefix=CI -check-prefix=SICIVI %s
7 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-flat-for-global -amdgpu-scalarize-global-loads=false -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=VI -check-prefix=SICIVI %s
8 ; RUN: llc -march=amdgcn -mcpu=gfx900 -mattr=-promote-alloca -amdgpu-scalarize-global-loads=false < %s | FileCheck -check-prefix=GCN -check-prefix=GFX9 %s
10 target datalayout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5"
12 ; OPT-LABEL: @test_sink_global_small_offset_i32(
13 ; OPT-CI-NOT: getelementptr i32, ptr addrspace(1) %in
14 ; OPT-VI: getelementptr i32, ptr addrspace(1) %in
15 ; OPT: br i1
16 ; OPT-CI: getelementptr i8,
18 ; GCN-LABEL: {{^}}test_sink_global_small_offset_i32:
19 define amdgpu_kernel void @test_sink_global_small_offset_i32(ptr addrspace(1) %out, ptr addrspace(1) %in) {
20 entry:
21   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
22   %in.gep = getelementptr i32, ptr addrspace(1) %in, i64 7
23   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
24   %tmp0 = icmp eq i32 %tid, 0
25   br i1 %tmp0, label %endif, label %if
27 if:
28   %tmp1 = load i32, ptr addrspace(1) %in.gep
29   br label %endif
31 endif:
32   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
33   store i32 %x, ptr addrspace(1) %out.gep
34   br label %done
36 done:
37   ret void
40 ; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
41 ; OPT: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 65535
42 ; OPT: br i1
44 ; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset:
45 ; GCN: s_and_saveexec_b64
46 ; SICIVI: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
48 ; GFX9: v_mov_b32_e32 [[VOFFSET:v[0-9]+]], 0xf000{{$}}
49 ; GFX9: global_load_sbyte {{v[0-9]+}}, [[VOFFSET]], {{s\[[0-9]+:[0-9]+\]}} offset:4095{{$}}
50 ; GCN: {{^}}.LBB1_2:
51 ; GCN: s_or_b64 exec
52 define amdgpu_kernel void @test_sink_global_small_max_i32_ds_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
53 entry:
54   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 99999
55   %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 65535
56   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
57   %tmp0 = icmp eq i32 %tid, 0
58   br i1 %tmp0, label %endif, label %if
60 if:
61   %tmp1 = load i8, ptr addrspace(1) %in.gep
62   %tmp2 = sext i8 %tmp1 to i32
63   br label %endif
65 endif:
66   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
67   store i32 %x, ptr addrspace(1) %out.gep
68   br label %done
70 done:
71   ret void
74 ; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset:
75 ; GCN: s_and_saveexec_b64
76 ; SICIVI: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}}
77 ; GFX9: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
78 ; GFX9: global_load_sbyte {{v[0-9]+}}, [[ZERO]], {{s\[[0-9]+:[0-9]+\]}} offset:4095{{$}}
79 ; GCN: {{^}}.LBB2_2:
80 ; GCN: s_or_b64 exec
81 define amdgpu_kernel void @test_sink_global_small_max_mubuf_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
82 entry:
83   %out.gep = getelementptr i32, ptr addrspace(1) %out, i32 1024
84   %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 4095
85   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
86   %tmp0 = icmp eq i32 %tid, 0
87   br i1 %tmp0, label %endif, label %if
89 if:
90   %tmp1 = load i8, ptr addrspace(1) %in.gep
91   %tmp2 = sext i8 %tmp1 to i32
92   br label %endif
94 endif:
95   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
96   store i32 %x, ptr addrspace(1) %out.gep
97   br label %done
99 done:
100   ret void
103 ; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset:
104 ; GCN: s_and_saveexec_b64
105 ; SICIVI: buffer_load_sbyte {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
106 ; GFX9: v_mov_b32_e32 [[VOFFSET:v[0-9]+]], 0x1000{{$}}
107 ; GFX9: global_load_sbyte {{v[0-9]+}}, [[VOFFSET]], {{s\[[0-9]+:[0-9]+\]$}}
108 ; GCN: {{^}}.LBB3_2:
109 ; GCN: s_or_b64 exec
110 define amdgpu_kernel void @test_sink_global_small_max_plus_1_mubuf_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
111 entry:
112   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 99999
113   %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 4096
114   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
115   %tmp0 = icmp eq i32 %tid, 0
116   br i1 %tmp0, label %endif, label %if
119   %tmp1 = load i8, ptr addrspace(1) %in.gep
120   %tmp2 = sext i8 %tmp1 to i32
121   br label %endif
123 endif:
124   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
125   store i32 %x, ptr addrspace(1) %out.gep
126   br label %done
128 done:
129   ret void
132 ; OPT-LABEL: @test_sink_scratch_small_offset_i32(
133 ; OPT-NOT:  getelementptr [512 x i32]
134 ; OPT: br i1
135 ; OPT: getelementptr i8,
137 ; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32:
138 ; GCN: s_and_saveexec_b64
139 ; GCN: buffer_store_dword {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4092{{$}}
140 ; GCN: buffer_load_dword {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4092 glc{{$}}
141 ; GCN: {{^}}.LBB4_2:
142 define amdgpu_kernel void @test_sink_scratch_small_offset_i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %arg) {
143 entry:
144   %alloca = alloca [512 x i32], align 4, addrspace(5)
145   %out.gep.0 = getelementptr i32, ptr addrspace(1) %out, i64 999998
146   %out.gep.1 = getelementptr i32, ptr addrspace(1) %out, i64 999999
147   %add.arg = add i32 %arg, 8
148   %alloca.gep = getelementptr [512 x i32], ptr addrspace(5) %alloca, i32 0, i32 1022
149   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
150   %tmp0 = icmp eq i32 %tid, 0
151   br i1 %tmp0, label %endif, label %if
154   store volatile i32 123, ptr addrspace(5) %alloca.gep
155   %tmp1 = load volatile i32, ptr addrspace(5) %alloca.gep
156   br label %endif
158 endif:
159   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
160   store i32 %x, ptr addrspace(1) %out.gep.0
161   %load = load volatile i32, ptr addrspace(5) %alloca.gep
162   store i32 %load, ptr addrspace(1) %out.gep.1
163   br label %done
165 done:
166   ret void
169 ; This ends up not fitting due to the reserved 4 bytes at offset 0
170 ; OPT-LABEL: @test_sink_scratch_small_offset_i32_reserved(
171 ; OPT-NOT:  getelementptr [512 x i32]
172 ; OPT: br i1
173 ; OPT: getelementptr i8,
175 ; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32_reserved:
176 ; GCN: s_and_saveexec_b64
177 ; GCN: v_mov_b32_e32 [[BASE_FI0:v[0-9]+]], 4
178 ; GCN: buffer_store_dword {{v[0-9]+}}, [[BASE_FI0]], {{s\[[0-9]+:[0-9]+\]}}, 0 offen offset:4092{{$}}
179 ; GCN: v_mov_b32_e32 [[BASE_FI1:v[0-9]+]], 4
180 ; GCN: buffer_load_dword {{v[0-9]+}}, [[BASE_FI1]], {{s\[[0-9]+:[0-9]+\]}}, 0 offen offset:4092 glc{{$}}
181 ; GCN: {{^.LBB[0-9]+}}_2:
183 define amdgpu_kernel void @test_sink_scratch_small_offset_i32_reserved(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %arg) {
184 entry:
185   %alloca = alloca [512 x i32], align 4, addrspace(5)
186   %out.gep.0 = getelementptr i32, ptr addrspace(1) %out, i64 999998
187   %out.gep.1 = getelementptr i32, ptr addrspace(1) %out, i64 999999
188   %add.arg = add i32 %arg, 8
189   %alloca.gep = getelementptr [512 x i32], ptr addrspace(5) %alloca, i32 0, i32 1023
190   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
191   %tmp0 = icmp eq i32 %tid, 0
192   br i1 %tmp0, label %endif, label %if
195   store volatile i32 123, ptr addrspace(5) %alloca.gep
196   %tmp1 = load volatile i32, ptr addrspace(5) %alloca.gep
197   br label %endif
199 endif:
200   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
201   store i32 %x, ptr addrspace(1) %out.gep.0
202   %load = load volatile i32, ptr addrspace(5) %alloca.gep
203   store i32 %load, ptr addrspace(1) %out.gep.1
204   br label %done
206 done:
207   ret void
210 ; OPT-LABEL: @test_no_sink_scratch_large_offset_i32(
211 ; OPT: %alloca.gep = getelementptr [512 x i32], ptr addrspace(5) %alloca, i32 0, i32 1024
212 ; OPT: br i1
213 ; OPT-NOT: ptrtoint
215 ; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32:
216 ; GCN: s_and_saveexec_b64
217 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offen{{$}}
218 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offen glc{{$}}
219 ; GCN: {{^.LBB[0-9]+}}_2:
220 define amdgpu_kernel void @test_no_sink_scratch_large_offset_i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %arg) {
221 entry:
222   %alloca = alloca [512 x i32], align 4, addrspace(5)
223   %out.gep.0 = getelementptr i32, ptr addrspace(1) %out, i64 999998
224   %out.gep.1 = getelementptr i32, ptr addrspace(1) %out, i64 999999
225   %add.arg = add i32 %arg, 8
226   %alloca.gep = getelementptr [512 x i32], ptr addrspace(5) %alloca, i32 0, i32 1024
227   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
228   %tmp0 = icmp eq i32 %tid, 0
229   br i1 %tmp0, label %endif, label %if
232   store volatile i32 123, ptr addrspace(5) %alloca.gep
233   %tmp1 = load volatile i32, ptr addrspace(5) %alloca.gep
234   br label %endif
236 endif:
237   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
238   store i32 %x, ptr addrspace(1) %out.gep.0
239   %load = load volatile i32, ptr addrspace(5) %alloca.gep
240   store i32 %load, ptr addrspace(1) %out.gep.1
241   br label %done
243 done:
244   ret void
247 ; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32:
248 ; GCN: s_and_saveexec_b64
249 ; CI: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
250 ; VI: flat_load_dword v{{[0-9]+}}, v[{{[0-9]+:[0-9]+}}]
251 ; GCN: {{^.LBB[0-9]+}}_2:
252 define amdgpu_kernel void @test_sink_global_vreg_sreg_i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %offset) {
253 entry:
254   %offset.ext = zext i32 %offset to i64
255   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
256   %in.gep = getelementptr i32, ptr addrspace(1) %in, i64 %offset.ext
257   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
258   %tmp0 = icmp eq i32 %tid, 0
259   br i1 %tmp0, label %endif, label %if
262   %tmp1 = load i32, ptr addrspace(1) %in.gep
263   br label %endif
265 endif:
266   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
267   store i32 %x, ptr addrspace(1) %out.gep
268   br label %done
270 done:
271   ret void
274 ; OPT-LABEL: @test_sink_constant_small_offset_i32
275 ; OPT-NOT:  getelementptr i32, ptr addrspace(4)
276 ; OPT: br i1
278 ; GCN-LABEL: {{^}}test_sink_constant_small_offset_i32:
279 ; GCN: s_and_saveexec_b64
280 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x7{{$}}
281 ; GCN: s_or_b64 exec, exec
282 define amdgpu_kernel void @test_sink_constant_small_offset_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
283 entry:
284   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
285   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 7
286   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
287   %tmp0 = icmp eq i32 %tid, 0
288   br i1 %tmp0, label %endif, label %if
291   %tmp1 = load i32, ptr addrspace(4) %in.gep
292   br label %endif
294 endif:
295   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
296   store i32 %x, ptr addrspace(1) %out.gep
297   br label %done
299 done:
300   ret void
303 ; OPT-LABEL: @test_sink_constant_max_8_bit_offset_i32
304 ; OPT-NOT:  getelementptr i32, ptr addrspace(4)
305 ; OPT: br i1
307 ; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_i32:
308 ; GCN: s_and_saveexec_b64
309 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xff{{$}}
310 ; GCN: s_or_b64 exec, exec
311 define amdgpu_kernel void @test_sink_constant_max_8_bit_offset_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
312 entry:
313   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
314   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 255
315   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
316   %tmp0 = icmp eq i32 %tid, 0
317   br i1 %tmp0, label %endif, label %if
320   %tmp1 = load i32, ptr addrspace(4) %in.gep
321   br label %endif
323 endif:
324   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
325   store i32 %x, ptr addrspace(1) %out.gep
326   br label %done
328 done:
329   ret void
332 ; OPT-LABEL: @test_sink_constant_max_8_bit_offset_p1_i32
333 ; OPT-SI:  getelementptr i32, ptr addrspace(4)
334 ; OPT-CI-NOT:  getelementptr i32, ptr addrspace(4)
335 ; OPT-VI-NOT:  getelementptr i32, ptr addrspace(4)
336 ; OPT: br i1
338 ; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_p1_i32:
339 ; GCN: s_and_saveexec_b64
340 ; SI: s_movk_i32 [[OFFSET:s[0-9]+]], 0x400
342 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
343 ; GCN: s_or_b64 exec, exec
344 define amdgpu_kernel void @test_sink_constant_max_8_bit_offset_p1_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
345 entry:
346   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
347   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 256
348   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
349   %tmp0 = icmp eq i32 %tid, 0
350   br i1 %tmp0, label %endif, label %if
353   %tmp1 = load i32, ptr addrspace(4) %in.gep
354   br label %endif
356 endif:
357   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
358   store i32 %x, ptr addrspace(1) %out.gep
359   br label %done
361 done:
362   ret void
365 ; OPT-LABEL: @test_sink_constant_max_32_bit_offset_i32
366 ; OPT-SI: getelementptr i32, ptr addrspace(4)
367 ; OPT-CI-NOT: getelementptr i32, ptr addrspace(4)
368 ; OPT: br i1
370 ; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_i32:
371 ; GCN: s_and_saveexec_b64
372 ; SI: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, -4{{$}}
373 ; SI: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, 3{{$}}
374 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}}
376 ; VI: s_add_u32 s{{[0-9]+}}, s{{[0-9]+}}, -4{{$}}
377 ; VI: s_addc_u32 s{{[0-9]+}}, s{{[0-9]+}}, 3{{$}}
378 ; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}}
380 ; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xffffffff{{$}}
382 ; GCN: s_or_b64 exec, exec
383 define amdgpu_kernel void @test_sink_constant_max_32_bit_offset_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
384 entry:
385   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
386   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 4294967295
387   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
388   %tmp0 = icmp eq i32 %tid, 0
389   br i1 %tmp0, label %endif, label %if
392   %tmp1 = load i32, ptr addrspace(4) %in.gep
393   br label %endif
395 endif:
396   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
397   store i32 %x, ptr addrspace(1) %out.gep
398   br label %done
400 done:
401   ret void
404 ; OPT-LABEL: @test_sink_constant_max_32_bit_offset_p1_i32
405 ; OPT: getelementptr i32, ptr addrspace(4)
406 ; OPT: br i1
408 ; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_p1_i32:
409 ; GCN: s_and_saveexec_b64
410 ; GCN: s_add_u32
411 ; GCN: s_addc_u32
412 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}}
413 ; GCN: s_or_b64 exec, exec
414 define amdgpu_kernel void @test_sink_constant_max_32_bit_offset_p1_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
415 entry:
416   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
417   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 17179869181
418   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
419   %tmp0 = icmp eq i32 %tid, 0
420   br i1 %tmp0, label %endif, label %if
423   %tmp1 = load i32, ptr addrspace(4) %in.gep
424   br label %endif
426 endif:
427   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
428   store i32 %x, ptr addrspace(1) %out.gep
429   br label %done
431 done:
432   ret void
435 ; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_i32:
436 ; GCN: s_and_saveexec_b64
437 ; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0xffffc{{$}}
438 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
440 ; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x3ffff{{$}}
441 ; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xffffc{{$}}
443 ; GCN: s_or_b64 exec, exec
444 define amdgpu_kernel void @test_sink_constant_max_20_bit_byte_offset_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
445 entry:
446   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
447   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 262143
448   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
449   %tmp0 = icmp eq i32 %tid, 0
450   br i1 %tmp0, label %endif, label %if
453   %tmp1 = load i32, ptr addrspace(4) %in.gep
454   br label %endif
456 endif:
457   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
458   store i32 %x, ptr addrspace(1) %out.gep
459   br label %done
461 done:
462   ret void
465 ; OPT-LABEL: @test_sink_constant_max_20_bit_byte_offset_p1_i32
466 ; OPT-SI: getelementptr i32, ptr addrspace(4)
467 ; OPT-CI-NOT: getelementptr i32, ptr addrspace(4)
468 ; OPT-VI: getelementptr i32, ptr addrspace(4)
469 ; OPT: br i1
471 ; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_p1_i32:
472 ; GCN: s_and_saveexec_b64
473 ; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}}
474 ; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
476 ; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x40000{{$}}
478 ; VI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}}
479 ; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
481 ; GCN: s_or_b64 exec, exec
482 define amdgpu_kernel void @test_sink_constant_max_20_bit_byte_offset_p1_i32(ptr addrspace(1) %out, ptr addrspace(4) %in) {
483 entry:
484   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 999999
485   %in.gep = getelementptr i32, ptr addrspace(4) %in, i64 262144
486   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
487   %tmp0 = icmp eq i32 %tid, 0
488   br i1 %tmp0, label %endif, label %if
491   %tmp1 = load i32, ptr addrspace(4) %in.gep
492   br label %endif
494 endif:
495   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
496   store i32 %x, ptr addrspace(1) %out.gep
497   br label %done
499 done:
500   ret void
503 %struct.foo = type { [3 x float], [3 x float] }
505 ; OPT-LABEL: @sink_ds_address(
506 ; OPT: getelementptr inbounds i8,
508 ; GCN-LABEL: {{^}}sink_ds_address:
509 ; GCN: s_load_dword [[SREG1:s[0-9]+]],
510 ; GCN: v_mov_b32_e32 [[VREG1:v[0-9]+]], [[SREG1]]
511 ; GCN-DAG: ds_read2_b32 v[{{[0-9+:[0-9]+}}], [[VREG1]] offset0:3 offset1:5
512 define amdgpu_kernel void @sink_ds_address(ptr addrspace(3) nocapture %ptr) nounwind {
513 entry:
514   %x = getelementptr inbounds %struct.foo, ptr addrspace(3) %ptr, i32 0, i32 1, i32 0
515   %y = getelementptr inbounds %struct.foo, ptr addrspace(3) %ptr, i32 0, i32 1, i32 2
516   br label %bb32
518 bb32:
519   %a = load float, ptr addrspace(3) %x, align 4
520   %b = load float, ptr addrspace(3) %y, align 4
521   %cmp = fcmp one float %a, %b
522   br i1 %cmp, label %bb34, label %bb33
524 bb33:
525   unreachable
527 bb34:
528   unreachable
531 ; Address offset is not a multiple of 4. This is a valid mubuf offset,
532 ; but not smrd.
534 ; OPT-LABEL: @test_sink_constant_small_max_mubuf_offset_load_i32_align_1(
535 ; OPT: br i1 %tmp0,
536 ; OPT: if:
537 ; OPT: getelementptr i8, {{.*}} 4095
538 define amdgpu_kernel void @test_sink_constant_small_max_mubuf_offset_load_i32_align_1(ptr addrspace(1) %out, ptr addrspace(4) %in) {
539 entry:
540   %out.gep = getelementptr i32, ptr addrspace(1) %out, i32 1024
541   %in.gep = getelementptr i8, ptr addrspace(4) %in, i64 4095
542   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
543   %tmp0 = icmp eq i32 %tid, 0
544   br i1 %tmp0, label %endif, label %if
547   %tmp1 = load i32, ptr addrspace(4) %in.gep, align 1
548   br label %endif
550 endif:
551   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
552   store i32 %x, ptr addrspace(1) %out.gep
553   br label %done
555 done:
556   ret void
559 ; OPT-LABEL: @test_sink_local_small_offset_atomicrmw_i32(
560 ; OPT: %sunkaddr = getelementptr i8, ptr addrspace(3) %in, i32 28
561 ; OPT: %tmp1 = atomicrmw add ptr addrspace(3) %sunkaddr, i32 2 seq_cst
562 define amdgpu_kernel void @test_sink_local_small_offset_atomicrmw_i32(ptr addrspace(3) %out, ptr addrspace(3) %in) {
563 entry:
564   %out.gep = getelementptr i32, ptr addrspace(3) %out, i32 999999
565   %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
566   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
567   %tmp0 = icmp eq i32 %tid, 0
568   br i1 %tmp0, label %endif, label %if
571   %tmp1 = atomicrmw add ptr addrspace(3) %in.gep, i32 2 seq_cst
572   br label %endif
574 endif:
575   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
576   store i32 %x, ptr addrspace(3) %out.gep
577   br label %done
579 done:
580   ret void
583 ; OPT-LABEL: @test_sink_local_small_offset_cmpxchg_i32(
584 ; OPT: %sunkaddr = getelementptr i8, ptr addrspace(3) %in, i32 28
585 ; OPT: %tmp1.struct = cmpxchg ptr addrspace(3) %sunkaddr, i32 undef, i32 2 seq_cst monotonic
586 define amdgpu_kernel void @test_sink_local_small_offset_cmpxchg_i32(ptr addrspace(3) %out, ptr addrspace(3) %in) {
587 entry:
588   %out.gep = getelementptr i32, ptr addrspace(3) %out, i32 999999
589   %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
590   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
591   %tmp0 = icmp eq i32 %tid, 0
592   br i1 %tmp0, label %endif, label %if
595   %tmp1.struct = cmpxchg ptr addrspace(3) %in.gep, i32 undef, i32 2 seq_cst monotonic
596   %tmp1 = extractvalue { i32, i1 } %tmp1.struct, 0
597   br label %endif
599 endif:
600   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
601   store i32 %x, ptr addrspace(3) %out.gep
602   br label %done
604 done:
605   ret void
608 ; OPT-LABEL: @test_wrong_operand_local_small_offset_cmpxchg_i32(
609 ; OPT: %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
610 ; OPT: br i1
611 ; OPT: cmpxchg ptr addrspace(3) undef, ptr addrspace(3) %in.gep, ptr addrspace(3) undef seq_cst monotonic
612 define amdgpu_kernel void @test_wrong_operand_local_small_offset_cmpxchg_i32(ptr addrspace(3) %out, ptr addrspace(3) %in) {
613 entry:
614   %out.gep = getelementptr ptr addrspace(3), ptr addrspace(3) %out, i32 999999
615   %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
616   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
617   %tmp0 = icmp eq i32 %tid, 0
618   br i1 %tmp0, label %endif, label %if
621   %tmp1.struct = cmpxchg ptr addrspace(3) undef, ptr addrspace(3) %in.gep, ptr addrspace(3) undef seq_cst monotonic
622   %tmp1 = extractvalue { ptr addrspace(3), i1 } %tmp1.struct, 0
623   br label %endif
625 endif:
626   %x = phi ptr addrspace(3) [ %tmp1, %if ], [ null, %entry ]
627   store ptr addrspace(3) %x, ptr addrspace(3) %out.gep
628   br label %done
630 done:
631   ret void
634 ; OPT-LABEL: @test_sink_global_small_min_scratch_global_offset(
635 ; OPT-SICIVI: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4096
636 ; OPT-SICIV: br
637 ; OPT-SICIVI: %tmp1 = load i8, ptr addrspace(1) %in.gep
639 ; OPT-GFX9: br
640 ; OPT-GFX9: %sunkaddr = getelementptr i8, ptr addrspace(1) %in, i64 -4096
641 ; OPT-GFX9: load i8, ptr addrspace(1) %sunkaddr
643 ; GCN-LABEL: {{^}}test_sink_global_small_min_scratch_global_offset:
644 ; GFX9: v_mov_b32_e32 [[ZERO:v[0-9]+]], 0{{$}}
645 ; GFX9: global_load_sbyte v{{[0-9]+}}, [[ZERO]], s{{\[[0-9]+:[0-9]+\]}} offset:-4096{{$}}
646 define amdgpu_kernel void @test_sink_global_small_min_scratch_global_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
647 entry:
648   %out.gep = getelementptr i32, ptr addrspace(1) %out, i32 1024
649   %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4096
650   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
651   %tmp0 = icmp eq i32 %tid, 0
652   br i1 %tmp0, label %endif, label %if
655   %tmp1 = load i8, ptr addrspace(1) %in.gep
656   %tmp2 = sext i8 %tmp1 to i32
657   br label %endif
659 endif:
660   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
661   store i32 %x, ptr addrspace(1) %out.gep
662   br label %done
664 done:
665   ret void
668 ; OPT-LABEL: @test_sink_global_small_min_scratch_global_neg1_offset(
669 ; OPT: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4097
670 ; OPT: br
671 ; OPT: load i8, ptr addrspace(1) %in.gep
673 ; GCN-LABEL: {{^}}test_sink_global_small_min_scratch_global_neg1_offset:
674 define amdgpu_kernel void @test_sink_global_small_min_scratch_global_neg1_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
675 entry:
676   %out.gep = getelementptr i32, ptr addrspace(1) %out, i64 99999
677   %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4097
678   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
679   %tmp0 = icmp eq i32 %tid, 0
680   br i1 %tmp0, label %endif, label %if
683   %tmp1 = load i8, ptr addrspace(1) %in.gep
684   %tmp2 = sext i8 %tmp1 to i32
685   br label %endif
687 endif:
688   %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
689   store i32 %x, ptr addrspace(1) %out.gep
690   br label %done
692 done:
693   ret void
696 ; OPT-LABEL: @test_sink_small_offset_ds_append(
697 ; OPT: %sunkaddr = getelementptr i8, ptr addrspace(3) %in, i32 28
698 ; OPT: %tmp1 = call i32 @llvm.amdgcn.ds.append.p3(ptr addrspace(3) %sunkaddr, i1 false)
699 define amdgpu_kernel void @test_sink_small_offset_ds_append(ptr addrspace(3) %out, ptr addrspace(3) %in) {
700 entry:
701   %out.gep = getelementptr i32, ptr addrspace(3) %out, i32 999999
702   %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
703   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
704   %tmp0 = icmp eq i32 %tid, 0
705   br i1 %tmp0, label %endif, label %if
708   %tmp1 = call i32 @llvm.amdgcn.ds.append.p3(ptr addrspace(3) %in.gep, i1 false)
709   br label %endif
711 endif:
712   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
713   store i32 %x, ptr addrspace(3) %out.gep
714   br label %done
716 done:
717   ret void
720 ; OPT-LABEL: @test_sink_small_offset_ds_consume(
721 ; OPT: %sunkaddr = getelementptr i8, ptr addrspace(3) %in, i32 28
722 ; OPT: %tmp1 = call i32 @llvm.amdgcn.ds.consume.p3(ptr addrspace(3) %sunkaddr, i1 false)
723 define amdgpu_kernel void @test_sink_small_offset_ds_consume(ptr addrspace(3) %out, ptr addrspace(3) %in) {
724 entry:
725   %out.gep = getelementptr i32, ptr addrspace(3) %out, i32 999999
726   %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
727   %tid = call i32 @llvm.amdgcn.mbcnt.lo(i32 -1, i32 0) #0
728   %tmp0 = icmp eq i32 %tid, 0
729   br i1 %tmp0, label %endif, label %if
732   %tmp1 = call i32 @llvm.amdgcn.ds.consume.p3(ptr addrspace(3) %in.gep, i1 false)
733   br label %endif
735 endif:
736   %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
737   store i32 %x, ptr addrspace(3) %out.gep
738   br label %done
740 done:
741   ret void
744 declare i32 @llvm.amdgcn.mbcnt.lo(i32, i32) #0
745 declare i32 @llvm.amdgcn.ds.append.p3(ptr addrspace(3) nocapture, i1 immarg) #3
746 declare i32 @llvm.amdgcn.ds.consume.p3(ptr addrspace(3) nocapture, i1 immarg) #3
748 attributes #0 = { nounwind readnone }
749 attributes #1 = { nounwind }
750 attributes #2 = { nounwind argmemonly }
751 attributes #3 = { argmemonly convergent nounwind willreturn }