1 ; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown < %s | FileCheck -check-prefix=OPT %s
2 ; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN %s
4 declare i32 @llvm.r600.read.tidig.x() #0
6 ; OPT-LABEL: @test_sink_global_small_offset_i32(
7 ; OPT-NOT: getelementptr i32, i32 addrspace(1)* %in
11 ; GCN-LABEL: {{^}}test_sink_global_small_offset_i32:
13 define void @test_sink_global_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) {
15 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
16 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 7
17 %tmp0 = icmp eq i32 %cond, 0
18 br i1 %tmp0, label %endif, label %if
21 %tmp1 = load i32, i32 addrspace(1)* %in.gep
25 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
26 store i32 %x, i32 addrspace(1)* %out.gep
33 ; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
34 ; OPT: %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
37 ; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset:
38 ; GCN: s_and_saveexec_b64
39 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
42 define void @test_sink_global_small_max_i32_ds_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
44 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
45 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
46 %tmp0 = icmp eq i32 %cond, 0
47 br i1 %tmp0, label %endif, label %if
50 %tmp1 = load i8, i8 addrspace(1)* %in.gep
51 %tmp2 = sext i8 %tmp1 to i32
55 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
56 store i32 %x, i32 addrspace(1)* %out.gep
63 ; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset:
64 ; GCN: s_and_saveexec_b64
65 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}}
68 define void @test_sink_global_small_max_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
70 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024
71 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4095
72 %tmp0 = icmp eq i32 %cond, 0
73 br i1 %tmp0, label %endif, label %if
76 %tmp1 = load i8, i8 addrspace(1)* %in.gep
77 %tmp2 = sext i8 %tmp1 to i32
81 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
82 store i32 %x, i32 addrspace(1)* %out.gep
89 ; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset:
90 ; GCN: s_and_saveexec_b64
91 ; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
94 define void @test_sink_global_small_max_plus_1_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
96 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
97 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4096
98 %tmp0 = icmp eq i32 %cond, 0
99 br i1 %tmp0, label %endif, label %if
102 %tmp1 = load i8, i8 addrspace(1)* %in.gep
103 %tmp2 = sext i8 %tmp1 to i32
107 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
108 store i32 %x, i32 addrspace(1)* %out.gep
115 ; OPT-LABEL: @test_no_sink_flat_small_offset_i32(
116 ; OPT: getelementptr i32, i32 addrspace(4)* %in
120 ; GCN-LABEL: {{^}}test_no_sink_flat_small_offset_i32:
121 ; GCN: flat_load_dword
124 define void @test_no_sink_flat_small_offset_i32(i32 addrspace(4)* %out, i32 addrspace(4)* %in, i32 %cond) {
126 %out.gep = getelementptr i32, i32 addrspace(4)* %out, i64 999999
127 %in.gep = getelementptr i32, i32 addrspace(4)* %in, i64 7
128 %tmp0 = icmp eq i32 %cond, 0
129 br i1 %tmp0, label %endif, label %if
132 %tmp1 = load i32, i32 addrspace(4)* %in.gep
136 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
137 store i32 %x, i32 addrspace(4)* %out.gep
144 ; OPT-LABEL: @test_sink_scratch_small_offset_i32(
145 ; OPT-NOT: getelementptr [512 x i32]
149 ; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32:
150 ; GCN: s_and_saveexec_b64
151 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
152 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
154 define void @test_sink_scratch_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
156 %alloca = alloca [512 x i32], align 4
157 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
158 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
159 %add.arg = add i32 %arg, 8
160 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1023
161 %tmp0 = icmp eq i32 %cond, 0
162 br i1 %tmp0, label %endif, label %if
165 store volatile i32 123, i32* %alloca.gep
166 %tmp1 = load volatile i32, i32* %alloca.gep
170 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
171 store i32 %x, i32 addrspace(1)* %out.gep.0
172 %load = load volatile i32, i32* %alloca.gep
173 store i32 %load, i32 addrspace(1)* %out.gep.1
180 ; OPT-LABEL: @test_no_sink_scratch_large_offset_i32(
181 ; OPT: %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
185 ; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32:
186 ; GCN: s_and_saveexec_b64
187 ; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
188 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
190 define void @test_no_sink_scratch_large_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
192 %alloca = alloca [512 x i32], align 4
193 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
194 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
195 %add.arg = add i32 %arg, 8
196 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
197 %tmp0 = icmp eq i32 %cond, 0
198 br i1 %tmp0, label %endif, label %if
201 store volatile i32 123, i32* %alloca.gep
202 %tmp1 = load volatile i32, i32* %alloca.gep
206 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
207 store i32 %x, i32 addrspace(1)* %out.gep.0
208 %load = load volatile i32, i32* %alloca.gep
209 store i32 %load, i32 addrspace(1)* %out.gep.1
216 ; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32:
217 ; GCN: s_and_saveexec_b64
218 ; GCN: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
220 define void @test_sink_global_vreg_sreg_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %offset, i32 %cond) {
222 %offset.ext = zext i32 %offset to i64
223 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
224 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 %offset.ext
225 %tmp0 = icmp eq i32 %cond, 0
226 br i1 %tmp0, label %endif, label %if
229 %tmp1 = load i32, i32 addrspace(1)* %in.gep
233 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
234 store i32 %x, i32 addrspace(1)* %out.gep
241 attributes #0 = { nounwind readnone }
242 attributes #1 = { nounwind }