• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -verify-machineinstrs -march=amdgcn -mcpu=SI < %s | FileCheck --check-prefix=GCN --check-prefix=DEFAULT-SCRATCH %s
2; RUN: llc -verify-machineinstrs -march=amdgcn -mcpu=tonga < %s | FileCheck --check-prefix=GCN --check-prefix=DEFAULT-SCRATCH %s
3; RUN: llc -verify-machineinstrs -march=amdgcn -mattr=+huge-scratch-buffer -mcpu=SI < %s | FileCheck --check-prefix=GCN --check-prefix=HUGE-SCRATCH %s
4; RUN: llc -verify-machineinstrs -march=amdgcn -mattr=+huge-scratch-buffer -mcpu=tonga < %s | FileCheck --check-prefix=GCN --check-prefix=HUGE-SCRATCH %s
5
6; When a frame index offset is more than 12-bits, make sure we don't store
7; it in mubuf's offset field.
8
9; Also, make sure we use the same register for storing the scratch buffer addresss
10; for both stores. This register is allocated by the register scavenger, so we
11; should be able to reuse the same regiser for each scratch buffer access.
12
13; GCN-LABEL: {{^}}legal_offset_fi:
14; GCN: v_mov_b32_e32 [[OFFSET:v[0-9]+]], 0{{$}}
15; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen
16; GCN: v_mov_b32_e32 [[OFFSET]], 0x8000
17; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen{{$}}
18
19define void @legal_offset_fi(i32 addrspace(1)* %out, i32 %cond, i32 %if_offset, i32 %else_offset) {
20entry:
21  %scratch0 = alloca [8192 x i32]
22  %scratch1 = alloca [8192 x i32]
23
24  %scratchptr0 = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 0
25  store i32 1, i32* %scratchptr0
26
27  %scratchptr1 = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 0
28  store i32 2, i32* %scratchptr1
29
30  %cmp = icmp eq i32 %cond, 0
31  br i1 %cmp, label %if, label %else
32
33if:
34  %if_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %if_offset
35  %if_value = load i32, i32* %if_ptr
36  br label %done
37
38else:
39  %else_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %else_offset
40  %else_value = load i32, i32* %else_ptr
41  br label %done
42
43done:
44  %value = phi i32 [%if_value, %if], [%else_value, %else]
45  store i32 %value, i32 addrspace(1)* %out
46  ret void
47
48  ret void
49
50}
51
52; GCN-LABEL: {{^}}legal_offset_fi_offset
53; GCN: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen
54; GCN: v_add_i32_e32 [[OFFSET:v[0-9]+]], vcc, 0x8000
55; GCN: buffer_store_dword v{{[0-9]+}}, [[OFFSET]], s[{{[0-9]+}}:{{[0-9]+}}], s{{[0-9]+}} offen{{$}}
56
57define void @legal_offset_fi_offset(i32 addrspace(1)* %out, i32 %cond, i32 addrspace(1)* %offsets, i32 %if_offset, i32 %else_offset) {
58entry:
59  %scratch0 = alloca [8192 x i32]
60  %scratch1 = alloca [8192 x i32]
61
62  %offset0 = load i32, i32 addrspace(1)* %offsets
63  %scratchptr0 = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %offset0
64  store i32 %offset0, i32* %scratchptr0
65
66  %offsetptr1 = getelementptr i32, i32 addrspace(1)* %offsets, i32 1
67  %offset1 = load i32, i32 addrspace(1)* %offsetptr1
68  %scratchptr1 = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %offset1
69  store i32 %offset1, i32* %scratchptr1
70
71  %cmp = icmp eq i32 %cond, 0
72  br i1 %cmp, label %if, label %else
73
74if:
75  %if_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch0, i32 0, i32 %if_offset
76  %if_value = load i32, i32* %if_ptr
77  br label %done
78
79else:
80  %else_ptr = getelementptr [8192 x i32], [8192 x i32]* %scratch1, i32 0, i32 %else_offset
81  %else_value = load i32, i32* %else_ptr
82  br label %done
83
84done:
85  %value = phi i32 [%if_value, %if], [%else_value, %else]
86  store i32 %value, i32 addrspace(1)* %out
87  ret void
88}
89
90; GCN-LABEL: @neg_vaddr_offset
91; We can't prove %offset is positive, so we must do the computation with the
92; immediate in an add instruction instead of folding offset and the immediate into
93; the store instruction.
94; GCN: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen{{$}}
95define void @neg_vaddr_offset(i32 %offset) {
96entry:
97  %array = alloca [8192 x i32]
98  %ptr_offset = add i32 %offset, 4
99  %ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 %ptr_offset
100  store i32 0, i32* %ptr
101  ret void
102}
103
104; GCN-LABEL: @pos_vaddr_offse
105; DEFAULT-SCRATCH: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen offset:16
106; HUGE-SCRATCH: buffer_store_dword v{{[0-9]+}}, v{{[0-9]+}}, s[{{[0-9]+:[0-9]+}}], s{{[0-9]+}} offen{{$}}
107define void @pos_vaddr_offset(i32 addrspace(1)* %out, i32 %offset) {
108entry:
109  %array = alloca [8192 x i32]
110  %ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 4
111  store i32 0, i32* %ptr
112  %load_ptr = getelementptr [8192 x i32], [8192 x i32]* %array, i32 0, i32 %offset
113  %val = load i32, i32* %load_ptr
114  store i32 %val, i32 addrspace(1)* %out
115  ret void
116}
117