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