blob: 5cb6cc3ff677f434bad36e174b3b9768e828543e [file] [log] [blame]
Matt Arsenault711b3902015-08-07 20:18:34 +00001; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tahiti < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-SI %s
Tom Stellard70580f82015-07-20 14:28:41 +00002; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=bonaire < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-CI %s
3; RUN: opt -S -codegenprepare -mtriple=amdgcn-unknown-unknown -mcpu=tonga < %s | FileCheck -check-prefix=OPT -check-prefix=OPT-VI %s
Matt Arsenault711b3902015-08-07 20:18:34 +00004; RUN: llc -march=amdgcn -mcpu=tahiti -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
Tom Stellard70580f82015-07-20 14:28:41 +00005; RUN: llc -march=amdgcn -mcpu=bonaire -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=CI %s
6; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-promote-alloca < %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
Matt Arsenault73e06fa2015-06-04 16:17:42 +00007
8declare i32 @llvm.r600.read.tidig.x() #0
9
10; OPT-LABEL: @test_sink_global_small_offset_i32(
Tom Stellard70580f82015-07-20 14:28:41 +000011; OPT-CI-NOT: getelementptr i32, i32 addrspace(1)* %in
12; OPT-VI: getelementptr i32, i32 addrspace(1)* %in
Matt Arsenault73e06fa2015-06-04 16:17:42 +000013; OPT: br i1
Tom Stellard70580f82015-07-20 14:28:41 +000014; OPT-CI: ptrtoint
Matt Arsenault73e06fa2015-06-04 16:17:42 +000015
16; GCN-LABEL: {{^}}test_sink_global_small_offset_i32:
17; GCN: {{^}}BB0_2:
18define void @test_sink_global_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond) {
19entry:
20 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
21 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 7
22 %tmp0 = icmp eq i32 %cond, 0
23 br i1 %tmp0, label %endif, label %if
24
25if:
26 %tmp1 = load i32, i32 addrspace(1)* %in.gep
27 br label %endif
28
29endif:
30 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
31 store i32 %x, i32 addrspace(1)* %out.gep
32 br label %done
33
34done:
35 ret void
36}
37
38; OPT-LABEL: @test_sink_global_small_max_i32_ds_offset(
39; OPT: %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
40; OPT: br i1
41
42; GCN-LABEL: {{^}}test_sink_global_small_max_i32_ds_offset:
43; GCN: s_and_saveexec_b64
44; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
45; GCN: {{^}}BB1_2:
46; GCN: s_or_b64 exec
47define void @test_sink_global_small_max_i32_ds_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
48entry:
49 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
50 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 65535
51 %tmp0 = icmp eq i32 %cond, 0
52 br i1 %tmp0, label %endif, label %if
53
54if:
55 %tmp1 = load i8, i8 addrspace(1)* %in.gep
56 %tmp2 = sext i8 %tmp1 to i32
57 br label %endif
58
59endif:
60 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
61 store i32 %x, i32 addrspace(1)* %out.gep
62 br label %done
63
64done:
65 ret void
66}
67
68; GCN-LABEL: {{^}}test_sink_global_small_max_mubuf_offset:
69; GCN: s_and_saveexec_b64
70; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 offset:4095{{$}}
71; GCN: {{^}}BB2_2:
72; GCN: s_or_b64 exec
73define void @test_sink_global_small_max_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
74entry:
75 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i32 1024
76 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4095
77 %tmp0 = icmp eq i32 %cond, 0
78 br i1 %tmp0, label %endif, label %if
79
80if:
81 %tmp1 = load i8, i8 addrspace(1)* %in.gep
82 %tmp2 = sext i8 %tmp1 to i32
83 br label %endif
84
85endif:
86 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
87 store i32 %x, i32 addrspace(1)* %out.gep
88 br label %done
89
90done:
91 ret void
92}
93
94; GCN-LABEL: {{^}}test_sink_global_small_max_plus_1_mubuf_offset:
95; GCN: s_and_saveexec_b64
96; GCN: buffer_load_sbyte {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, s{{[0-9]+$}}
97; GCN: {{^}}BB3_2:
98; GCN: s_or_b64 exec
99define void @test_sink_global_small_max_plus_1_mubuf_offset(i32 addrspace(1)* %out, i8 addrspace(1)* %in, i32 %cond) {
100entry:
101 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 99999
102 %in.gep = getelementptr i8, i8 addrspace(1)* %in, i64 4096
103 %tmp0 = icmp eq i32 %cond, 0
104 br i1 %tmp0, label %endif, label %if
105
106if:
107 %tmp1 = load i8, i8 addrspace(1)* %in.gep
108 %tmp2 = sext i8 %tmp1 to i32
109 br label %endif
110
111endif:
112 %x = phi i32 [ %tmp2, %if ], [ 0, %entry ]
113 store i32 %x, i32 addrspace(1)* %out.gep
114 br label %done
115
116done:
117 ret void
118}
119
Matt Arsenault73e06fa2015-06-04 16:17:42 +0000120; OPT-LABEL: @test_sink_scratch_small_offset_i32(
121; OPT-NOT: getelementptr [512 x i32]
122; OPT: br i1
123; OPT: ptrtoint
124
125; GCN-LABEL: {{^}}test_sink_scratch_small_offset_i32:
126; GCN: s_and_saveexec_b64
127; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
128; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen offset:4092{{$}}
Matt Arsenault711b3902015-08-07 20:18:34 +0000129; GCN: {{^}}BB4_2:
Matt Arsenault73e06fa2015-06-04 16:17:42 +0000130define void @test_sink_scratch_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
131entry:
132 %alloca = alloca [512 x i32], align 4
133 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
134 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
135 %add.arg = add i32 %arg, 8
136 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1023
137 %tmp0 = icmp eq i32 %cond, 0
138 br i1 %tmp0, label %endif, label %if
139
140if:
141 store volatile i32 123, i32* %alloca.gep
142 %tmp1 = load volatile i32, i32* %alloca.gep
143 br label %endif
144
145endif:
146 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
147 store i32 %x, i32 addrspace(1)* %out.gep.0
148 %load = load volatile i32, i32* %alloca.gep
149 store i32 %load, i32 addrspace(1)* %out.gep.1
150 br label %done
151
152done:
153 ret void
154}
155
156; OPT-LABEL: @test_no_sink_scratch_large_offset_i32(
157; OPT: %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
158; OPT: br i1
159; OPT-NOT: ptrtoint
160
161; GCN-LABEL: {{^}}test_no_sink_scratch_large_offset_i32:
162; GCN: s_and_saveexec_b64
163; GCN: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
164; GCN: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen{{$}}
Matt Arsenault711b3902015-08-07 20:18:34 +0000165; GCN: {{^}}BB5_2:
Matt Arsenault73e06fa2015-06-04 16:17:42 +0000166define void @test_no_sink_scratch_large_offset_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %cond, i32 %arg) {
167entry:
168 %alloca = alloca [512 x i32], align 4
169 %out.gep.0 = getelementptr i32, i32 addrspace(1)* %out, i64 999998
170 %out.gep.1 = getelementptr i32, i32 addrspace(1)* %out, i64 999999
171 %add.arg = add i32 %arg, 8
172 %alloca.gep = getelementptr [512 x i32], [512 x i32]* %alloca, i32 0, i32 1024
173 %tmp0 = icmp eq i32 %cond, 0
174 br i1 %tmp0, label %endif, label %if
175
176if:
177 store volatile i32 123, i32* %alloca.gep
178 %tmp1 = load volatile i32, i32* %alloca.gep
179 br label %endif
180
181endif:
182 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
183 store i32 %x, i32 addrspace(1)* %out.gep.0
184 %load = load volatile i32, i32* %alloca.gep
185 store i32 %load, i32 addrspace(1)* %out.gep.1
186 br label %done
187
188done:
189 ret void
190}
191
192; GCN-LABEL: {{^}}test_sink_global_vreg_sreg_i32:
Tom Stellard70580f82015-07-20 14:28:41 +0000193; VI-DAG: s_movk_i32 flat_scratch_lo, 0x0
194; VI-DAG: s_movk_i32 flat_scratch_hi, 0x0
Matt Arsenault73e06fa2015-06-04 16:17:42 +0000195; GCN: s_and_saveexec_b64
Tom Stellard70580f82015-07-20 14:28:41 +0000196; CI: buffer_load_dword {{v[0-9]+}}, {{v\[[0-9]+:[0-9]+\]}}, {{s\[[0-9]+:[0-9]+\]}}, 0 addr64{{$}}
197; VI: flat_load_dword v{{[0-9]+}}, v[{{[0-9]+:[0-9]+}}]
Matt Arsenault711b3902015-08-07 20:18:34 +0000198; GCN: {{^}}BB6_2:
Matt Arsenault73e06fa2015-06-04 16:17:42 +0000199define void @test_sink_global_vreg_sreg_i32(i32 addrspace(1)* %out, i32 addrspace(1)* %in, i32 %offset, i32 %cond) {
200entry:
201 %offset.ext = zext i32 %offset to i64
202 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
203 %in.gep = getelementptr i32, i32 addrspace(1)* %in, i64 %offset.ext
204 %tmp0 = icmp eq i32 %cond, 0
205 br i1 %tmp0, label %endif, label %if
206
207if:
208 %tmp1 = load i32, i32 addrspace(1)* %in.gep
209 br label %endif
210
211endif:
212 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
213 store i32 %x, i32 addrspace(1)* %out.gep
214 br label %done
215
216done:
217 ret void
218}
219
220attributes #0 = { nounwind readnone }
221attributes #1 = { nounwind }
Matt Arsenault711b3902015-08-07 20:18:34 +0000222
223
224
225; OPT-LABEL: @test_sink_constant_small_offset_i32
226; OPT-NOT: getelementptr i32, i32 addrspace(2)*
227; OPT: br i1
228
229; GCN-LABEL: {{^}}test_sink_constant_small_offset_i32:
230; GCN: s_and_saveexec_b64
231; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x7{{$}}
232; GCN: s_or_b64 exec, exec
233define void @test_sink_constant_small_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
234entry:
235 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
236 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 7
237 %tmp0 = icmp eq i32 %cond, 0
238 br i1 %tmp0, label %endif, label %if
239
240if:
241 %tmp1 = load i32, i32 addrspace(2)* %in.gep
242 br label %endif
243
244endif:
245 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
246 store i32 %x, i32 addrspace(1)* %out.gep
247 br label %done
248
249done:
250 ret void
251}
252
253; OPT-LABEL: @test_sink_constant_max_8_bit_offset_i32
254; OPT-NOT: getelementptr i32, i32 addrspace(2)*
255; OPT: br i1
256
257; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_i32:
258; GCN: s_and_saveexec_b64
259; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xff{{$}}
260; GCN: s_or_b64 exec, exec
261define void @test_sink_constant_max_8_bit_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
262entry:
263 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
264 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 255
265 %tmp0 = icmp eq i32 %cond, 0
266 br i1 %tmp0, label %endif, label %if
267
268if:
269 %tmp1 = load i32, i32 addrspace(2)* %in.gep
270 br label %endif
271
272endif:
273 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
274 store i32 %x, i32 addrspace(1)* %out.gep
275 br label %done
276
277done:
278 ret void
279}
280
281; OPT-LABEL: @test_sink_constant_max_8_bit_offset_p1_i32
282; OPT-SI: getelementptr i32, i32 addrspace(2)*
283; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)*
284; OPT-VI-NOT: getelementptr i32, i32 addrspace(2)*
285; OPT: br i1
286
287; GCN-LABEL: {{^}}test_sink_constant_max_8_bit_offset_p1_i32:
288; GCN: s_and_saveexec_b64
289; SI: s_movk_i32 [[OFFSET:s[0-9]+]], 0x400
290
291; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
292; GCN: s_or_b64 exec, exec
293define void @test_sink_constant_max_8_bit_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
294entry:
295 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
296 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 256
297 %tmp0 = icmp eq i32 %cond, 0
298 br i1 %tmp0, label %endif, label %if
299
300if:
301 %tmp1 = load i32, i32 addrspace(2)* %in.gep
302 br label %endif
303
304endif:
305 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
306 store i32 %x, i32 addrspace(1)* %out.gep
307 br label %done
308
309done:
310 ret void
311}
312
313; OPT-LABEL: @test_sink_constant_max_32_bit_offset_i32
314; OPT-SI: getelementptr i32, i32 addrspace(2)*
315; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)*
316; OPT: br i1
317
318; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_i32:
319; GCN: s_and_saveexec_b64
320; GCN-DAG: s_mov_b32 s{{[0-9]+}}, 3{{$}}
321; GCN-DAG: s_mov_b32 s{{[0-9]+}}, -4{{$}}
322; GCN: s_add_u32
323; GCN: s_addc_u32
324; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}}
325; GCN: s_or_b64 exec, exec
326define void @test_sink_constant_max_32_bit_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
327entry:
328 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
329 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 4294967295
330 %tmp0 = icmp eq i32 %cond, 0
331 br i1 %tmp0, label %endif, label %if
332
333if:
334 %tmp1 = load i32, i32 addrspace(2)* %in.gep
335 br label %endif
336
337endif:
338 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
339 store i32 %x, i32 addrspace(1)* %out.gep
340 br label %done
341
342done:
343 ret void
344}
345
346; OPT-LABEL: @test_sink_constant_max_32_bit_offset_p1_i32
347; OPT: getelementptr i32, i32 addrspace(2)*
348; OPT: br i1
349
350; GCN-LABEL: {{^}}test_sink_constant_max_32_bit_offset_p1_i32:
351; GCN: s_and_saveexec_b64
352; GCN: s_add_u32
353; GCN: s_addc_u32
354; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x0{{$}}
355; GCN: s_or_b64 exec, exec
356define void @test_sink_constant_max_32_bit_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
357entry:
358 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
359 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 17179869181
360 %tmp0 = icmp eq i32 %cond, 0
361 br i1 %tmp0, label %endif, label %if
362
363if:
364 %tmp1 = load i32, i32 addrspace(2)* %in.gep
365 br label %endif
366
367endif:
368 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
369 store i32 %x, i32 addrspace(1)* %out.gep
370 br label %done
371
372done:
373 ret void
374}
375
376; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_i32:
377; GCN: s_and_saveexec_b64
378; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0xffffc{{$}}
379; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
380
381; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x3ffff{{$}}
382; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0xffffc{{$}}
383
384; GCN: s_or_b64 exec, exec
385define void @test_sink_constant_max_20_bit_byte_offset_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
386entry:
387 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
388 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 262143
389 %tmp0 = icmp eq i32 %cond, 0
390 br i1 %tmp0, label %endif, label %if
391
392if:
393 %tmp1 = load i32, i32 addrspace(2)* %in.gep
394 br label %endif
395
396endif:
397 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
398 store i32 %x, i32 addrspace(1)* %out.gep
399 br label %done
400
401done:
402 ret void
403}
404
405; OPT-LABEL: @test_sink_constant_max_20_bit_byte_offset_p1_i32
406; OPT-SI: getelementptr i32, i32 addrspace(2)*
407; OPT-CI-NOT: getelementptr i32, i32 addrspace(2)*
408; OPT-VI: getelementptr i32, i32 addrspace(2)*
409; OPT: br i1
410
411; GCN-LABEL: {{^}}test_sink_constant_max_20_bit_byte_offset_p1_i32:
412; GCN: s_and_saveexec_b64
413; SI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}}
414; SI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
415
416; CI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0x40000{{$}}
417
418; VI: s_mov_b32 [[OFFSET:s[0-9]+]], 0x100000{{$}}
419; VI: s_load_dword s{{[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, [[OFFSET]]{{$}}
420
421; GCN: s_or_b64 exec, exec
422define void @test_sink_constant_max_20_bit_byte_offset_p1_i32(i32 addrspace(1)* %out, i32 addrspace(2)* %in, i32 %cond) {
423entry:
424 %out.gep = getelementptr i32, i32 addrspace(1)* %out, i64 999999
425 %in.gep = getelementptr i32, i32 addrspace(2)* %in, i64 262144
426 %tmp0 = icmp eq i32 %cond, 0
427 br i1 %tmp0, label %endif, label %if
428
429if:
430 %tmp1 = load i32, i32 addrspace(2)* %in.gep
431 br label %endif
432
433endif:
434 %x = phi i32 [ %tmp1, %if ], [ 0, %entry ]
435 store i32 %x, i32 addrspace(1)* %out.gep
436 br label %done
437
438done:
439 ret void
440}