AMDGPU: Use assert zext for workgroup sizes
[oota-llvm.git] / test / CodeGen / AMDGPU / work-item-intrinsics.ll
1 ; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=GCN -check-prefix=FUNC %s
2 ; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=VI -check-prefix=GCN -check-prefix=FUNC %s
3 ; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
4
5
6 ; FUNC-LABEL: {{^}}ngroups_x:
7 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
8 ; EG: MOV [[VAL]], KC0[0].X
9
10 ; GCN: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0
11 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
12 ; GCN: buffer_store_dword [[VVAL]]
13 define void @ngroups_x (i32 addrspace(1)* %out) {
14 entry:
15   %0 = call i32 @llvm.r600.read.ngroups.x() #0
16   store i32 %0, i32 addrspace(1)* %out
17   ret void
18 }
19
20 ; FUNC-LABEL: {{^}}ngroups_y:
21 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
22 ; EG: MOV [[VAL]], KC0[0].Y
23
24 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x1
25 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x4
26 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
27 ; GCN: buffer_store_dword [[VVAL]]
28 define void @ngroups_y (i32 addrspace(1)* %out) {
29 entry:
30   %0 = call i32 @llvm.r600.read.ngroups.y() #0
31   store i32 %0, i32 addrspace(1)* %out
32   ret void
33 }
34
35 ; FUNC-LABEL: {{^}}ngroups_z:
36 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
37 ; EG: MOV [[VAL]], KC0[0].Z
38
39 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x2
40 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x8
41 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
42 ; GCN: buffer_store_dword [[VVAL]]
43 define void @ngroups_z (i32 addrspace(1)* %out) {
44 entry:
45   %0 = call i32 @llvm.r600.read.ngroups.z() #0
46   store i32 %0, i32 addrspace(1)* %out
47   ret void
48 }
49
50 ; FUNC-LABEL: {{^}}global_size_x:
51 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
52 ; EG: MOV [[VAL]], KC0[0].W
53
54 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x3
55 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0xc
56 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
57 ; GCN: buffer_store_dword [[VVAL]]
58 define void @global_size_x (i32 addrspace(1)* %out) {
59 entry:
60   %0 = call i32 @llvm.r600.read.global.size.x() #0
61   store i32 %0, i32 addrspace(1)* %out
62   ret void
63 }
64
65 ; FUNC-LABEL: {{^}}global_size_y:
66 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
67 ; EG: MOV [[VAL]], KC0[1].X
68
69 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x4
70 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x10
71 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
72 ; GCN: buffer_store_dword [[VVAL]]
73 define void @global_size_y (i32 addrspace(1)* %out) {
74 entry:
75   %0 = call i32 @llvm.r600.read.global.size.y() #0
76   store i32 %0, i32 addrspace(1)* %out
77   ret void
78 }
79
80 ; FUNC-LABEL: {{^}}global_size_z:
81 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
82 ; EG: MOV [[VAL]], KC0[1].Y
83
84 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x5
85 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x14
86 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
87 ; GCN: buffer_store_dword [[VVAL]]
88 define void @global_size_z (i32 addrspace(1)* %out) {
89 entry:
90   %0 = call i32 @llvm.r600.read.global.size.z() #0
91   store i32 %0, i32 addrspace(1)* %out
92   ret void
93 }
94
95 ; FUNC-LABEL: {{^}}local_size_x:
96 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
97 ; EG: MOV [[VAL]], KC0[1].Z
98
99 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x6
100 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x18
101 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
102 ; GCN: buffer_store_dword [[VVAL]]
103 define void @local_size_x (i32 addrspace(1)* %out) {
104 entry:
105   %0 = call i32 @llvm.r600.read.local.size.x() #0
106   store i32 %0, i32 addrspace(1)* %out
107   ret void
108 }
109
110 ; FUNC-LABEL: {{^}}local_size_y:
111 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
112 ; EG: MOV [[VAL]], KC0[1].W
113
114 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x7
115 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x1c
116 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
117 ; GCN: buffer_store_dword [[VVAL]]
118 define void @local_size_y (i32 addrspace(1)* %out) {
119 entry:
120   %0 = call i32 @llvm.r600.read.local.size.y() #0
121   store i32 %0, i32 addrspace(1)* %out
122   ret void
123 }
124
125 ; FUNC-LABEL: {{^}}local_size_z:
126 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
127 ; EG: MOV [[VAL]], KC0[2].X
128
129 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x8
130 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x20
131 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
132 ; GCN: buffer_store_dword [[VVAL]]
133 define void @local_size_z (i32 addrspace(1)* %out) {
134 entry:
135   %0 = call i32 @llvm.r600.read.local.size.z() #0
136   store i32 %0, i32 addrspace(1)* %out
137   ret void
138 }
139
140 ; FUNC-LABEL: {{^}}get_work_dim:
141 ; EG: MEM_RAT_CACHELESS STORE_RAW [[VAL:T[0-9]+\.X]]
142 ; EG: MOV [[VAL]], KC0[2].Z
143
144 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0xb
145 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x2c
146 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
147 ; GCN: buffer_store_dword [[VVAL]]
148 define void @get_work_dim (i32 addrspace(1)* %out) {
149 entry:
150   %0 = call i32 @llvm.AMDGPU.read.workdim() #0
151   store i32 %0, i32 addrspace(1)* %out
152   ret void
153 }
154
155 ; The tgid values are stored in sgprs offset by the number of user sgprs.
156 ; Currently we always use exactly 2 user sgprs for the pointer to the
157 ; kernel arguments, but this may change in the future.
158
159 ; FUNC-LABEL: {{^}}tgid_x:
160 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], s4
161 ; GCN: buffer_store_dword [[VVAL]]
162 define void @tgid_x (i32 addrspace(1)* %out) {
163 entry:
164   %0 = call i32 @llvm.r600.read.tgid.x() #0
165   store i32 %0, i32 addrspace(1)* %out
166   ret void
167 }
168
169 ; FUNC-LABEL: {{^}}tgid_y:
170 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], s5
171 ; GCN: buffer_store_dword [[VVAL]]
172 define void @tgid_y (i32 addrspace(1)* %out) {
173 entry:
174   %0 = call i32 @llvm.r600.read.tgid.y() #0
175   store i32 %0, i32 addrspace(1)* %out
176   ret void
177 }
178
179 ; FUNC-LABEL: {{^}}tgid_z:
180 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], s6
181 ; GCN: buffer_store_dword [[VVAL]]
182 define void @tgid_z (i32 addrspace(1)* %out) {
183 entry:
184   %0 = call i32 @llvm.r600.read.tgid.z() #0
185   store i32 %0, i32 addrspace(1)* %out
186   ret void
187 }
188
189 ; FUNC-LABEL: {{^}}tidig_x:
190 ; GCN: buffer_store_dword v0
191 define void @tidig_x (i32 addrspace(1)* %out) {
192 entry:
193   %0 = call i32 @llvm.r600.read.tidig.x() #0
194   store i32 %0, i32 addrspace(1)* %out
195   ret void
196 }
197
198 ; FUNC-LABEL: {{^}}tidig_y:
199 ; GCN: buffer_store_dword v1
200 define void @tidig_y (i32 addrspace(1)* %out) {
201 entry:
202   %0 = call i32 @llvm.r600.read.tidig.y() #0
203   store i32 %0, i32 addrspace(1)* %out
204   ret void
205 }
206
207 ; FUNC-LABEL: {{^}}tidig_z:
208 ; GCN: buffer_store_dword v2
209 define void @tidig_z (i32 addrspace(1)* %out) {
210 entry:
211   %0 = call i32 @llvm.r600.read.tidig.z() #0
212   store i32 %0, i32 addrspace(1)* %out
213   ret void
214 }
215
216 ; FUNC-LABEL: {{^}}local_size_x_known_bits:
217 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x6
218 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x18
219 ; GCN-NOT: 0xffff
220 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
221 ; GCN-NEXT: buffer_store_dword [[VVAL]]
222 define void @local_size_x_known_bits(i32 addrspace(1)* %out) {
223 entry:
224   %size = call i32 @llvm.r600.read.local.size.x() #0
225   %shl = shl i32 %size, 16
226   %shr = lshr i32 %shl, 16
227   store i32 %shr, i32 addrspace(1)* %out
228   ret void
229 }
230
231 ; FUNC-LABEL: {{^}}local_size_y_known_bits:
232 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x7
233 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x1c
234 ; GCN-NOT: 0xffff
235 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
236 ; GCN-NEXT: buffer_store_dword [[VVAL]]
237 define void @local_size_y_known_bits(i32 addrspace(1)* %out) {
238 entry:
239   %size = call i32 @llvm.r600.read.local.size.y() #0
240   %shl = shl i32 %size, 16
241   %shr = lshr i32 %shl, 16
242   store i32 %shr, i32 addrspace(1)* %out
243   ret void
244 }
245
246 ; FUNC-LABEL: {{^}}local_size_z_known_bits:
247 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x8
248 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x20
249 ; GCN-NOT: 0xffff
250 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
251 ; GCN-NEXT: buffer_store_dword [[VVAL]]
252 define void @local_size_z_known_bits(i32 addrspace(1)* %out) {
253 entry:
254   %size = call i32 @llvm.r600.read.local.size.z() #0
255   %shl = shl i32 %size, 16
256   %shr = lshr i32 %shl, 16
257   store i32 %shr, i32 addrspace(1)* %out
258   ret void
259 }
260
261 ; FUNC-LABEL: {{^}}get_work_dim_known_bits:
262 ; SI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0xb
263 ; VI: s_load_dword [[VAL:s[0-9]+]], s[0:1], 0x2c
264 ; GCN-NOT: 0xff
265 ; GCN: v_mov_b32_e32 [[VVAL:v[0-9]+]], [[VAL]]
266 ; GCN: buffer_store_dword [[VVAL]]
267 define void @get_work_dim_known_bits(i32 addrspace(1)* %out) {
268 entry:
269   %dim = call i32 @llvm.AMDGPU.read.workdim() #0
270   %shl = shl i32 %dim, 24
271   %shr = lshr i32 %shl, 24
272   store i32 %shr, i32 addrspace(1)* %out
273   ret void
274 }
275
276 declare i32 @llvm.r600.read.ngroups.x() #0
277 declare i32 @llvm.r600.read.ngroups.y() #0
278 declare i32 @llvm.r600.read.ngroups.z() #0
279
280 declare i32 @llvm.r600.read.global.size.x() #0
281 declare i32 @llvm.r600.read.global.size.y() #0
282 declare i32 @llvm.r600.read.global.size.z() #0
283
284 declare i32 @llvm.r600.read.local.size.x() #0
285 declare i32 @llvm.r600.read.local.size.y() #0
286 declare i32 @llvm.r600.read.local.size.z() #0
287
288 declare i32 @llvm.r600.read.tgid.x() #0
289 declare i32 @llvm.r600.read.tgid.y() #0
290 declare i32 @llvm.r600.read.tgid.z() #0
291
292 declare i32 @llvm.r600.read.tidig.x() #0
293 declare i32 @llvm.r600.read.tidig.y() #0
294 declare i32 @llvm.r600.read.tidig.z() #0
295
296 declare i32 @llvm.AMDGPU.read.workdim() #0
297
298 attributes #0 = { readnone }