1; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx803 -enable-si-insert-waitcnts=1 -verify-machineinstrs < %s | FileCheck --check-prefix=GCN %s
2
3declare i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
4declare i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
5declare i32 @llvm.amdgcn.workitem.id.x()
6declare i32 @llvm.amdgcn.workgroup.id.x()
7declare void @llvm.amdgcn.s.barrier()
8
9@test_local.temp = internal addrspace(3) global [1 x i32] undef, align 4
10@test_global_local.temp = internal addrspace(3) global [1 x i32] undef, align 4
11
12; GCN-LABEL: {{^}}test_local
13; GCN: v_mov_b32_e32 v[[VAL:[0-9]+]], 0x777
14; GCN: ds_write_b32 v{{[0-9]+}}, v[[VAL]]
15; GCN: s_waitcnt lgkmcnt(0){{$}}
16; GCN-NEXT: s_barrier
17; GCN: flat_store_dword
18define amdgpu_kernel void @test_local(i32 addrspace(1)*) {
19  %2 = alloca i32 addrspace(1)*, align 4
20  store i32 addrspace(1)* %0, i32 addrspace(1)** %2, align 4
21  %3 = call i32 @llvm.amdgcn.workitem.id.x()
22  %4 = zext i32 %3 to i64
23  %5 = icmp eq i64 %4, 0
24  br i1 %5, label %6, label %7
25
26; <label>:6:                                      ; preds = %1
27  store i32 1911, i32 addrspace(3)* getelementptr inbounds ([1 x i32], [1 x i32] addrspace(3)* @test_local.temp, i64 0, i64 0), align 4
28  br label %7
29
30; <label>:7:                                      ; preds = %6, %1
31  fence syncscope("workgroup") release
32  call void @llvm.amdgcn.s.barrier()
33  fence syncscope("workgroup") acquire
34  %8 = load i32, i32 addrspace(3)* getelementptr inbounds ([1 x i32], [1 x i32] addrspace(3)* @test_local.temp, i64 0, i64 0), align 4
35  %9 = load i32 addrspace(1)*, i32 addrspace(1)** %2, align 4
36  %10 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
37  %11 = call i32 @llvm.amdgcn.workitem.id.x()
38  %12 = call i32 @llvm.amdgcn.workgroup.id.x()
39  %13 = getelementptr inbounds i8, i8 addrspace(2)* %10, i64 4
40  %14 = bitcast i8 addrspace(2)* %13 to i16 addrspace(2)*
41  %15 = load i16, i16 addrspace(2)* %14, align 4
42  %16 = zext i16 %15 to i32
43  %17 = mul i32 %12, %16
44  %18 = add i32 %17, %11
45  %19 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
46  %20 = zext i32 %18 to i64
47  %21 = bitcast i8 addrspace(2)* %19 to i64 addrspace(2)*
48  %22 = load i64, i64 addrspace(2)* %21, align 8
49  %23 = add i64 %22, %20
50  %24 = getelementptr inbounds i32, i32 addrspace(1)* %9, i64 %23
51  store i32 %8, i32 addrspace(1)* %24, align 4
52  ret void
53}
54
55; GCN-LABEL: {{^}}test_global
56; GCN: v_add_i32_e32 v{{[0-9]+}}, vcc, 0x888, v{{[0-9]+}}
57; GCN: flat_store_dword
58; GCN: s_waitcnt vmcnt(0) lgkmcnt(0){{$}}
59; GCN-NEXT: s_barrier
60define amdgpu_kernel void @test_global(i32 addrspace(1)*) {
61  %2 = alloca i32 addrspace(1)*, align 4
62  %3 = alloca i32, align 4
63  store i32 addrspace(1)* %0, i32 addrspace(1)** %2, align 4
64  store i32 0, i32* %3, align 4
65  br label %4
66
67; <label>:4:                                      ; preds = %58, %1
68  %5 = load i32, i32* %3, align 4
69  %6 = sext i32 %5 to i64
70  %7 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
71  %8 = call i32 @llvm.amdgcn.workitem.id.x()
72  %9 = call i32 @llvm.amdgcn.workgroup.id.x()
73  %10 = getelementptr inbounds i8, i8 addrspace(2)* %7, i64 4
74  %11 = bitcast i8 addrspace(2)* %10 to i16 addrspace(2)*
75  %12 = load i16, i16 addrspace(2)* %11, align 4
76  %13 = zext i16 %12 to i32
77  %14 = mul i32 %9, %13
78  %15 = add i32 %14, %8
79  %16 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
80  %17 = zext i32 %15 to i64
81  %18 = bitcast i8 addrspace(2)* %16 to i64 addrspace(2)*
82  %19 = load i64, i64 addrspace(2)* %18, align 8
83  %20 = add i64 %19, %17
84  %21 = icmp ult i64 %6, %20
85  br i1 %21, label %22, label %61
86
87; <label>:22:                                     ; preds = %4
88  %23 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
89  %24 = call i32 @llvm.amdgcn.workitem.id.x()
90  %25 = call i32 @llvm.amdgcn.workgroup.id.x()
91  %26 = getelementptr inbounds i8, i8 addrspace(2)* %23, i64 4
92  %27 = bitcast i8 addrspace(2)* %26 to i16 addrspace(2)*
93  %28 = load i16, i16 addrspace(2)* %27, align 4
94  %29 = zext i16 %28 to i32
95  %30 = mul i32 %25, %29
96  %31 = add i32 %30, %24
97  %32 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
98  %33 = zext i32 %31 to i64
99  %34 = bitcast i8 addrspace(2)* %32 to i64 addrspace(2)*
100  %35 = load i64, i64 addrspace(2)* %34, align 8
101  %36 = add i64 %35, %33
102  %37 = add i64 %36, 2184
103  %38 = trunc i64 %37 to i32
104  %39 = load i32 addrspace(1)*, i32 addrspace(1)** %2, align 4
105  %40 = load i32, i32* %3, align 4
106  %41 = sext i32 %40 to i64
107  %42 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
108  %43 = call i32 @llvm.amdgcn.workitem.id.x()
109  %44 = call i32 @llvm.amdgcn.workgroup.id.x()
110  %45 = getelementptr inbounds i8, i8 addrspace(2)* %42, i64 4
111  %46 = bitcast i8 addrspace(2)* %45 to i16 addrspace(2)*
112  %47 = load i16, i16 addrspace(2)* %46, align 4
113  %48 = zext i16 %47 to i32
114  %49 = mul i32 %44, %48
115  %50 = add i32 %49, %43
116  %51 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
117  %52 = zext i32 %50 to i64
118  %53 = bitcast i8 addrspace(2)* %51 to i64 addrspace(2)*
119  %54 = load i64, i64 addrspace(2)* %53, align 8
120  %55 = add i64 %54, %52
121  %56 = add i64 %41, %55
122  %57 = getelementptr inbounds i32, i32 addrspace(1)* %39, i64 %56
123  store i32 %38, i32 addrspace(1)* %57, align 4
124  fence syncscope("workgroup") release
125  call void @llvm.amdgcn.s.barrier()
126  fence syncscope("workgroup") acquire
127  br label %58
128
129; <label>:58:                                     ; preds = %22
130  %59 = load i32, i32* %3, align 4
131  %60 = add nsw i32 %59, 1
132  store i32 %60, i32* %3, align 4
133  br label %4
134
135; <label>:61:                                     ; preds = %4
136  ret void
137}
138
139; GCN-LABEL: {{^}}test_global_local
140; GCN: v_mov_b32_e32 v[[VAL:[0-9]+]], 0x999
141; GCN: ds_write_b32 v{{[0-9]+}}, v[[VAL]]
142; GCN: s_waitcnt vmcnt(0) lgkmcnt(0){{$}}
143; GCN-NEXT: s_barrier
144; GCN: flat_store_dword
145define amdgpu_kernel void @test_global_local(i32 addrspace(1)*) {
146  %2 = alloca i32 addrspace(1)*, align 4
147  store i32 addrspace(1)* %0, i32 addrspace(1)** %2, align 4
148  %3 = load i32 addrspace(1)*, i32 addrspace(1)** %2, align 4
149  %4 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
150  %5 = call i32 @llvm.amdgcn.workitem.id.x()
151  %6 = call i32 @llvm.amdgcn.workgroup.id.x()
152  %7 = getelementptr inbounds i8, i8 addrspace(2)* %4, i64 4
153  %8 = bitcast i8 addrspace(2)* %7 to i16 addrspace(2)*
154  %9 = load i16, i16 addrspace(2)* %8, align 4
155  %10 = zext i16 %9 to i32
156  %11 = mul i32 %6, %10
157  %12 = add i32 %11, %5
158  %13 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
159  %14 = zext i32 %12 to i64
160  %15 = bitcast i8 addrspace(2)* %13 to i64 addrspace(2)*
161  %16 = load i64, i64 addrspace(2)* %15, align 8
162  %17 = add i64 %16, %14
163  %18 = getelementptr inbounds i32, i32 addrspace(1)* %3, i64 %17
164  store i32 1, i32 addrspace(1)* %18, align 4
165  %19 = call i32 @llvm.amdgcn.workitem.id.x()
166  %20 = zext i32 %19 to i64
167  %21 = icmp eq i64 %20, 0
168  br i1 %21, label %22, label %23
169
170; <label>:22:                                     ; preds = %1
171  store i32 2457, i32 addrspace(3)* getelementptr inbounds ([1 x i32], [1 x i32] addrspace(3)* @test_global_local.temp, i64 0, i64 0), align 4
172  br label %23
173
174; <label>:23:                                     ; preds = %22, %1
175  fence syncscope("workgroup") release
176  call void @llvm.amdgcn.s.barrier()
177  fence syncscope("workgroup") acquire
178  %24 = load i32, i32 addrspace(3)* getelementptr inbounds ([1 x i32], [1 x i32] addrspace(3)* @test_global_local.temp, i64 0, i64 0), align 4
179  %25 = load i32 addrspace(1)*, i32 addrspace(1)** %2, align 4
180  %26 = call i8 addrspace(2)* @llvm.amdgcn.dispatch.ptr()
181  %27 = call i32 @llvm.amdgcn.workitem.id.x()
182  %28 = call i32 @llvm.amdgcn.workgroup.id.x()
183  %29 = getelementptr inbounds i8, i8 addrspace(2)* %26, i64 4
184  %30 = bitcast i8 addrspace(2)* %29 to i16 addrspace(2)*
185  %31 = load i16, i16 addrspace(2)* %30, align 4
186  %32 = zext i16 %31 to i32
187  %33 = mul i32 %28, %32
188  %34 = add i32 %33, %27
189  %35 = call i8 addrspace(2)* @llvm.amdgcn.implicitarg.ptr()
190  %36 = zext i32 %34 to i64
191  %37 = bitcast i8 addrspace(2)* %35 to i64 addrspace(2)*
192  %38 = load i64, i64 addrspace(2)* %37, align 8
193  %39 = add i64 %38, %36
194  %40 = getelementptr inbounds i32, i32 addrspace(1)* %25, i64 %39
195  store i32 %24, i32 addrspace(1)* %40, align 4
196  ret void
197}
198