1 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=bonaire < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-CI %s
2 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tonga < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-VI %s
3 ; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=CI %s
4 ; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
6 declare i32 @llvm.r600.read.tidig.x() #0
8 ; OPT-LABEL: @test_sink_global_small_offset_i32(
9 ; OPT-CI-NOT: getelementptr i32, i32 addrspace(1)* %in
10 ; OPT-VI: getelementptr i32, i32 addrspace(1)* %in
14 ; GCN-LABEL: {{^}}test_sink_global_small_offset_i32:
16 define void @test_sink_global_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) {
18 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
19 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 7
20 %tmp0 = icmp eq i32 %cond, 0
21 br i1 %tmp0, label %endif, label %if
24 %tmp1 = load i32, i32 addrspace(1)* %in.gep
28 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
29 store i32 %x, i32 addrspace(1)* %out.gep
36 ; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
37 ; OPT: %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
40 ; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset:
41 ; GCN: s_and_saveexec_b64
42 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
45 define void @test_sink_global_small_max_i32_ds_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
47 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
48 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
49 %tmp0 = icmp eq i32 %cond, 0
50 br i1 %tmp0, label %endif, label %if
53 %tmp1 = load i8, i8 addrspace(1)* %in.gep
54 %tmp2 = sext i8 %tmp1 to i32
58 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
59 store i32 %x, i32 addrspace(1)* %out.gep
66 ; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset:
67 ; GCN: s_and_saveexec_b64
68 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}}
71 define void @test_sink_global_small_max_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
73 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024
74 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4095
75 %tmp0 = icmp eq i32 %cond, 0
76 br i1 %tmp0, label %endif, label %if
79 %tmp1 = load i8, i8 addrspace(1)* %in.gep
80 %tmp2 = sext i8 %tmp1 to i32
84 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
85 store i32 %x, i32 addrspace(1)* %out.gep
92 ; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset:
93 ; GCN: s_and_saveexec_b64
94 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
97 define void @test_sink_global_small_max_plus_1_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
99 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
100 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4096
101 %tmp0 = icmp eq i32 %cond, 0
102 br i1 %tmp0, label %endif, label %if
105 %tmp1 = load i8, i8 addrspace(1)* %in.gep
106 %tmp2 = sext i8 %tmp1 to i32
110 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
111 store i32 %x, i32 addrspace(1)* %out.gep
118 ; OPT-LABEL: @test_no_sink_flat_small_offset_i32(
119 ; OPT: getelementptr i32, i32 addrspace(4)* %in
123 ; GCN-LABEL: {{^}}test_no_sink_flat_small_offset_i32:
124 ; GCN: flat_load_dword
127 define void @test_no_sink_flat_small_offset_i32(i32 addrspace(4)* %out, i32 addrspace(4)* %in, i32 %cond) {
129 %out.gep = getelementptr i32, i32 addrspace(4)* %out, i64 999999
130 %in.gep = getelementptr i32, i32 addrspace(4)* %in, i64 7
131 %tmp0 = icmp eq i32 %cond, 0
132 br i1 %tmp0, label %endif, label %if
135 %tmp1 = load i32, i32 addrspace(4)* %in.gep
139 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
140 store i32 %x, i32 addrspace(4)* %out.gep
147 ; OPT-LABEL: @test_sink_scratch_small_offset_i32(
148 ; OPT-NOT: getelementptr [512 x i32]
152 ; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32:
153 ; GCN: s_and_saveexec_b64
154 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
155 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
157 define void @test_sink_scratch_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
159 %alloca = alloca [512 x i32], align 4
160 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
161 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
162 %add.arg = add i32 %arg, 8
163 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1023
164 %tmp0 = icmp eq i32 %cond, 0
165 br i1 %tmp0, label %endif, label %if
168 store volatile i32 123, i32* %alloca.gep
169 %tmp1 = load volatile i32, i32* %alloca.gep
173 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
174 store i32 %x, i32 addrspace(1)* %out.gep.0
175 %load = load volatile i32, i32* %alloca.gep
176 store i32 %load, i32 addrspace(1)* %out.gep.1
183 ; OPT-LABEL: @test_no_sink_scratch_large_offset_i32(
184 ; OPT: %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
188 ; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32:
189 ; GCN: s_and_saveexec_b64
190 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
191 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
193 define void @test_no_sink_scratch_large_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
195 %alloca = alloca [512 x i32], align 4
196 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
197 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
198 %add.arg = add i32 %arg, 8
199 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
200 %tmp0 = icmp eq i32 %cond, 0
201 br i1 %tmp0, label %endif, label %if
204 store volatile i32 123, i32* %alloca.gep
205 %tmp1 = load volatile i32, i32* %alloca.gep
209 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
210 store i32 %x, i32 addrspace(1)* %out.gep.0
211 %load = load volatile i32, i32* %alloca.gep
212 store i32 %load, i32 addrspace(1)* %out.gep.1
219 ; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32:
220 ; VI-DAG: s_movk_i32 flat_scratch_lo, 0x0
221 ; VI-DAG: s_movk_i32 flat_scratch_hi, 0x0
222 ; GCN: s_and_saveexec_b64
223 ; CI: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
224 ; VI: flat_load_dword v{{[0-9]+}}, v[{{[0-9]+:[0-9]+}}]
226 define void @test_sink_global_vreg_sreg_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %offset, i32 %cond) {
228 %offset.ext = zext i32 %offset to i64
229 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
230 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 %offset.ext
231 %tmp0 = icmp eq i32 %cond, 0
232 br i1 %tmp0, label %endif, label %if
235 %tmp1 = load i32, i32 addrspace(1)* %in.gep
239 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
240 store i32 %x, i32 addrspace(1)* %out.gep
247 attributes #0 = { nounwind readnone }
248 attributes #1 = { nounwind }