1; RUN: opt -mtriple=amdgcn-unknown-amdhsa -S -amdgpu-annotate-kernel-features < %s | FileCheck -check-prefix=HSA -check-prefix=ALL %s
2; RUN: opt -S -amdgpu-annotate-kernel-features < %s | FileCheck -check-prefix=NOHSA -check-prefix=ALL %s
3
4declare i32 @llvm.r600.read.tgid.x() #0
5declare i32 @llvm.r600.read.tgid.y() #0
6declare i32 @llvm.r600.read.tgid.z() #0
7
8declare i32 @llvm.r600.read.tidig.x() #0
9declare i32 @llvm.r600.read.tidig.y() #0
10declare i32 @llvm.r600.read.tidig.z() #0
11
12declare i32 @llvm.r600.read.local.size.x() #0
13declare i32 @llvm.r600.read.local.size.y() #0
14declare i32 @llvm.r600.read.local.size.z() #0
15
16declare i32 @llvm.r600.read.global.size.x() #0
17declare i32 @llvm.r600.read.global.size.y() #0
18declare i32 @llvm.r600.read.global.size.z() #0
19
20
21; ALL: define void @use_tgid_x(i32 addrspace(1)* %ptr) #1 {
22define void @use_tgid_x(i32 addrspace(1)* %ptr) #1 {
23  %val = call i32 @llvm.r600.read.tgid.x()
24  store i32 %val, i32 addrspace(1)* %ptr
25  ret void
26}
27
28; ALL: define void @use_tgid_y(i32 addrspace(1)* %ptr) #2 {
29define void @use_tgid_y(i32 addrspace(1)* %ptr) #1 {
30  %val = call i32 @llvm.r600.read.tgid.y()
31  store i32 %val, i32 addrspace(1)* %ptr
32  ret void
33}
34
35; ALL: define void @multi_use_tgid_y(i32 addrspace(1)* %ptr) #2 {
36define void @multi_use_tgid_y(i32 addrspace(1)* %ptr) #1 {
37  %val0 = call i32 @llvm.r600.read.tgid.y()
38  store volatile i32 %val0, i32 addrspace(1)* %ptr
39  %val1 = call i32 @llvm.r600.read.tgid.y()
40  store volatile i32 %val1, i32 addrspace(1)* %ptr
41  ret void
42}
43
44; ALL: define void @use_tgid_x_y(i32 addrspace(1)* %ptr) #2 {
45define void @use_tgid_x_y(i32 addrspace(1)* %ptr) #1 {
46  %val0 = call i32 @llvm.r600.read.tgid.x()
47  %val1 = call i32 @llvm.r600.read.tgid.y()
48  store volatile i32 %val0, i32 addrspace(1)* %ptr
49  store volatile i32 %val1, i32 addrspace(1)* %ptr
50  ret void
51}
52
53; ALL: define void @use_tgid_z(i32 addrspace(1)* %ptr) #3 {
54define void @use_tgid_z(i32 addrspace(1)* %ptr) #1 {
55  %val = call i32 @llvm.r600.read.tgid.z()
56  store i32 %val, i32 addrspace(1)* %ptr
57  ret void
58}
59
60; ALL: define void @use_tgid_x_z(i32 addrspace(1)* %ptr) #3 {
61define void @use_tgid_x_z(i32 addrspace(1)* %ptr) #1 {
62  %val0 = call i32 @llvm.r600.read.tgid.x()
63  %val1 = call i32 @llvm.r600.read.tgid.z()
64  store volatile i32 %val0, i32 addrspace(1)* %ptr
65  store volatile i32 %val1, i32 addrspace(1)* %ptr
66  ret void
67}
68
69; ALL: define void @use_tgid_y_z(i32 addrspace(1)* %ptr) #4 {
70define void @use_tgid_y_z(i32 addrspace(1)* %ptr) #1 {
71  %val0 = call i32 @llvm.r600.read.tgid.y()
72  %val1 = call i32 @llvm.r600.read.tgid.z()
73  store volatile i32 %val0, i32 addrspace(1)* %ptr
74  store volatile i32 %val1, i32 addrspace(1)* %ptr
75  ret void
76}
77
78; ALL: define void @use_tgid_x_y_z(i32 addrspace(1)* %ptr) #4 {
79define void @use_tgid_x_y_z(i32 addrspace(1)* %ptr) #1 {
80  %val0 = call i32 @llvm.r600.read.tgid.x()
81  %val1 = call i32 @llvm.r600.read.tgid.y()
82  %val2 = call i32 @llvm.r600.read.tgid.z()
83  store volatile i32 %val0, i32 addrspace(1)* %ptr
84  store volatile i32 %val1, i32 addrspace(1)* %ptr
85  store volatile i32 %val2, i32 addrspace(1)* %ptr
86  ret void
87}
88
89; ALL: define void @use_tidig_x(i32 addrspace(1)* %ptr) #1 {
90define void @use_tidig_x(i32 addrspace(1)* %ptr) #1 {
91  %val = call i32 @llvm.r600.read.tidig.x()
92  store i32 %val, i32 addrspace(1)* %ptr
93  ret void
94}
95
96; ALL: define void @use_tidig_y(i32 addrspace(1)* %ptr) #5 {
97define void @use_tidig_y(i32 addrspace(1)* %ptr) #1 {
98  %val = call i32 @llvm.r600.read.tidig.y()
99  store i32 %val, i32 addrspace(1)* %ptr
100  ret void
101}
102
103; ALL: define void @use_tidig_z(i32 addrspace(1)* %ptr) #6 {
104define void @use_tidig_z(i32 addrspace(1)* %ptr) #1 {
105  %val = call i32 @llvm.r600.read.tidig.z()
106  store i32 %val, i32 addrspace(1)* %ptr
107  ret void
108}
109
110; ALL: define void @use_tidig_x_tgid_x(i32 addrspace(1)* %ptr) #1 {
111define void @use_tidig_x_tgid_x(i32 addrspace(1)* %ptr) #1 {
112  %val0 = call i32 @llvm.r600.read.tidig.x()
113  %val1 = call i32 @llvm.r600.read.tgid.x()
114  store volatile i32 %val0, i32 addrspace(1)* %ptr
115  store volatile i32 %val1, i32 addrspace(1)* %ptr
116  ret void
117}
118
119; ALL: define void @use_tidig_y_tgid_y(i32 addrspace(1)* %ptr) #7 {
120define void @use_tidig_y_tgid_y(i32 addrspace(1)* %ptr) #1 {
121  %val0 = call i32 @llvm.r600.read.tidig.y()
122  %val1 = call i32 @llvm.r600.read.tgid.y()
123  store volatile i32 %val0, i32 addrspace(1)* %ptr
124  store volatile i32 %val1, i32 addrspace(1)* %ptr
125  ret void
126}
127
128; ALL: define void @use_tidig_x_y_z(i32 addrspace(1)* %ptr) #8 {
129define void @use_tidig_x_y_z(i32 addrspace(1)* %ptr) #1 {
130  %val0 = call i32 @llvm.r600.read.tidig.x()
131  %val1 = call i32 @llvm.r600.read.tidig.y()
132  %val2 = call i32 @llvm.r600.read.tidig.z()
133  store volatile i32 %val0, i32 addrspace(1)* %ptr
134  store volatile i32 %val1, i32 addrspace(1)* %ptr
135  store volatile i32 %val2, i32 addrspace(1)* %ptr
136  ret void
137}
138
139; ALL: define void @use_all_workitems(i32 addrspace(1)* %ptr) #9 {
140define void @use_all_workitems(i32 addrspace(1)* %ptr) #1 {
141  %val0 = call i32 @llvm.r600.read.tidig.x()
142  %val1 = call i32 @llvm.r600.read.tidig.y()
143  %val2 = call i32 @llvm.r600.read.tidig.z()
144  %val3 = call i32 @llvm.r600.read.tgid.x()
145  %val4 = call i32 @llvm.r600.read.tgid.y()
146  %val5 = call i32 @llvm.r600.read.tgid.z()
147  store volatile i32 %val0, i32 addrspace(1)* %ptr
148  store volatile i32 %val1, i32 addrspace(1)* %ptr
149  store volatile i32 %val2, i32 addrspace(1)* %ptr
150  store volatile i32 %val3, i32 addrspace(1)* %ptr
151  store volatile i32 %val4, i32 addrspace(1)* %ptr
152  store volatile i32 %val5, i32 addrspace(1)* %ptr
153  ret void
154}
155
156; HSA: define void @use_get_local_size_x(i32 addrspace(1)* %ptr) #10 {
157; NOHSA: define void @use_get_local_size_x(i32 addrspace(1)* %ptr) #1 {
158define void @use_get_local_size_x(i32 addrspace(1)* %ptr) #1 {
159  %val = call i32 @llvm.r600.read.local.size.x()
160  store i32 %val, i32 addrspace(1)* %ptr
161  ret void
162}
163
164; HSA: define void @use_get_local_size_y(i32 addrspace(1)* %ptr) #10 {
165; NOHSA: define void @use_get_local_size_y(i32 addrspace(1)* %ptr) #1 {
166define void @use_get_local_size_y(i32 addrspace(1)* %ptr) #1 {
167  %val = call i32 @llvm.r600.read.local.size.y()
168  store i32 %val, i32 addrspace(1)* %ptr
169  ret void
170}
171
172; HSA: define void @use_get_local_size_z(i32 addrspace(1)* %ptr) #10 {
173; NOHSA: define void @use_get_local_size_z(i32 addrspace(1)* %ptr) #1 {
174define void @use_get_local_size_z(i32 addrspace(1)* %ptr) #1 {
175  %val = call i32 @llvm.r600.read.local.size.z()
176  store i32 %val, i32 addrspace(1)* %ptr
177  ret void
178}
179
180attributes #0 = { nounwind readnone }
181attributes #1 = { nounwind }
182
183; HSA: attributes #0 = { nounwind readnone }
184; HSA: attributes #1 = { nounwind }
185; HSA: attributes #2 = { nounwind "amdgpu-work-group-id-y" }
186; HSA: attributes #3 = { nounwind "amdgpu-work-group-id-z" }
187; HSA: attributes #4 = { nounwind "amdgpu-work-group-id-y" "amdgpu-work-group-id-z" }
188; HSA: attributes #5 = { nounwind "amdgpu-work-item-id-y" }
189; HSA: attributes #6 = { nounwind "amdgpu-work-item-id-z" }
190; HSA: attributes #7 = { nounwind "amdgpu-work-group-id-y" "amdgpu-work-item-id-y" }
191; HSA: attributes #8 = { nounwind "amdgpu-work-item-id-y" "amdgpu-work-item-id-z" }
192; HSA: attributes #9 = { nounwind "amdgpu-work-group-id-y" "amdgpu-work-group-id-z" "amdgpu-work-item-id-y" "amdgpu-work-item-id-z" }
193; HSA: attributes #10 = { nounwind "amdgpu-dispatch-ptr" }
194