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
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) {
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
28 %tmp1 = load i32, ptr addrspace(1) %in.gep
32 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
33 store i32 %x, ptr addrspace(1) %out.gep
40 ; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
41 ; OPT: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 65535
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{{$}}
52 define amdgpu_kernel void @test_sink_global_small_max_i32_ds_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
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
61 %tmp1 = load i8, ptr addrspace(1) %in.gep
62 %tmp2 = sext i8 %tmp1 to i32
66 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
67 store i32 %x, ptr addrspace(1) %out.gep
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{{$}}
81 define amdgpu_kernel void @test_sink_global_small_max_mubuf_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
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
90 %tmp1 = load i8, ptr addrspace(1) %in.gep
91 %tmp2 = sext i8 %tmp1 to i32
95 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
96 store i32 %x, ptr addrspace(1) %out.gep
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]+\]$}}
110 define amdgpu_kernel void @test_sink_global_small_max_plus_1_mubuf_offset(ptr addrspace(1) %out, ptr addrspace(1) %in) {
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
124 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
125 store i32 %x, ptr addrspace(1) %out.gep
132 ; OPT-LABEL: @test_sink_scratch_small_offset_i32(
133 ; OPT-NOT: getelementptr [512 x i32]
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{{$}}
142 define amdgpu_kernel void @test_sink_scratch_small_offset_i32(ptr addrspace(1) %out, ptr addrspace(1) %in, i32 %arg) {
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
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
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]
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) {
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
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
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
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) {
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
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
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) {
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
266 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
267 store i32 %x, ptr addrspace(1) %out.gep
274 ; OPT-LABEL: @test_sink_constant_small_offset_i32
275 ; OPT-NOT: getelementptr i32, ptr addrspace(4)
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) {
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
295 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
296 store i32 %x, ptr addrspace(1) %out.gep
303 ; OPT-LABEL: @test_sink_constant_max_8_bit_offset_i32
304 ; OPT-NOT: getelementptr i32, ptr addrspace(4)
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) {
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
324 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
325 store i32 %x, ptr addrspace(1) %out.gep
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)
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) {
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
357 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
358 store i32 %x, ptr addrspace(1) %out.gep
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)
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) {
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
396 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
397 store i32 %x, ptr addrspace(1) %out.gep
404 ; OPT-LABEL: @test_sink_constant_max_32_bit_offset_p1_i32
405 ; OPT: getelementptr i32, ptr addrspace(4)
408 ; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_p1_i32:
409 ; GCN: s_and_saveexec_b64
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) {
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
427 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
428 store i32 %x, ptr addrspace(1) %out.gep
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) {
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
457 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
458 store i32 %x, ptr addrspace(1) %out.gep
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)
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) {
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
495 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
496 store i32 %x, ptr addrspace(1) %out.gep
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 {
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
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
531 ; Address offset is not a multiple of 4. This is a valid mubuf offset,
534 ; OPT-LABEL: @test_sink_constant_small_max_mubuf_offset_load_i32_align_1(
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) {
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
551 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
552 store i32 %x, ptr addrspace(1) %out.gep
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) {
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
575 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
576 store i32 %x, ptr addrspace(3) %out.gep
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) {
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
600 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
601 store i32 %x, ptr addrspace(3) %out.gep
608 ; OPT-LABEL: @test_wrong_operand_local_small_offset_cmpxchg_i32(
609 ; OPT: %in.gep = getelementptr i32, ptr addrspace(3) %in, i32 7
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) {
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
626 %x = phi ptr addrspace(3) [ %tmp1, %if ], [ null, %entry ]
627 store ptr addrspace(3) %x, ptr addrspace(3) %out.gep
634 ; OPT-LABEL: @test_sink_global_small_min_scratch_global_offset(
635 ; OPT-SICIVI: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4096
637 ; OPT-SICIVI: %tmp1 = load i8, ptr addrspace(1) %in.gep
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) {
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
660 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
661 store i32 %x, ptr addrspace(1) %out.gep
668 ; OPT-LABEL: @test_sink_global_small_min_scratch_global_neg1_offset(
669 ; OPT: %in.gep = getelementptr i8, ptr addrspace(1) %in, i64 -4097
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) {
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
688 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
689 store i32 %x, ptr addrspace(1) %out.gep
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) {
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)
712 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
713 store i32 %x, ptr addrspace(3) %out.gep
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) {
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)
736 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
737 store i32 %x, ptr addrspace(3) %out.gep
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 }