Skip to content

Commit 6d522aa

Browse files
authored
[HIP][CodeGen] Make local variable use correct address space for CGDecl (#5374)
The code: ``` cgh.parallel_for_work_group<class WkGrp>( sycl::range<1>{N / 2}, sycl::range<1>{2}, [=](sycl::group<1> myGroup) { auto floo = 2.0; myGroup.parallel_for_work_item( [&](sycl::h_item<1> it) { acc[it.get_global_id()] = floo; }); }); ``` Was failing for the HIP backend. The variable `floo` is in local memory. Since the default address space for variables is `private`, the address space needs to be changed to `local`. The line `LangAS AS = GetGlobalVarAddressSpace(&D); ` correctly gets the appropriate address space. However, when checking for the value of the address space, the new address space is not used, rather the old one ``` if (Ty.getAddressSpace() == LangAS::opencl_local || Ty.getAddressSpace() == LangAS::sycl_local || ``` This results in `floo` being initialized as ``` Init = EmitNullConstant(Ty); ``` Which is incorrect. Instead of ``` Init = llvm::UndefValue::get(LTy); ``` On AMD, `floo` not being an `UndefValue` throws an assert later on in the compilation chain in `llvm/lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp` ``` void AMDGPUAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { if (GV->getAddressSpace() == AMDGPUAS::LOCAL_ADDRESS) { if (GV->hasInitializer() && !isa<UndefValue>(GV->getInitializer())) { OutContext.reportError({}, Twine(GV->getName()) + ": unsupported initializer for address space"); return; } ``` Therefore it is necessary to use the address space returned by `GetGlobalVarAddressSpace(&D)`, instead of the default address space when seeing whether the variable should be initialized as an UndefValue or a NullConstant. This results in the proper initialization of this kind of local variable as an `UndefValue`.
1 parent 50435a6 commit 6d522aa

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,7 @@ llvm::Constant *CodeGenModule::getOrCreateStaticVarDecl(
266266
// OpenCL/SYCL variables in local address space and CUDA shared
267267
// variables cannot have an initializer.
268268
llvm::Constant *Init = nullptr;
269-
if (Ty.getAddressSpace() == LangAS::opencl_local ||
270-
Ty.getAddressSpace() == LangAS::sycl_local ||
269+
if (AS == LangAS::opencl_local || AS == LangAS::sycl_local ||
271270
D.hasAttr<CUDASharedAttr>() || D.hasAttr<LoaderUninitializedAttr>())
272271
Init = llvm::UndefValue::get(LTy);
273272
else

clang/test/CodeGenSYCL/wg_init.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown -disable-llvm-passes -emit-llvm %s -o - | FileCheck %s
2+
3+
// This test checks that a local variable initialized within a
4+
// parallel_for_work_group scope is initialized as an UndefValue in addrspace(3)
5+
// in LLVM IR.
6+
7+
#include "Inputs/sycl.hpp"
8+
9+
using namespace sycl;
10+
11+
int main() {
12+
queue q;
13+
q.submit([&](handler &h) {
14+
h.parallel_for_work_group<class kernel>(
15+
range<1>{1}, range<1>{1}, [=](group<1> G) {
16+
int WG_VAR = 10;
17+
});
18+
});
19+
return 0;
20+
}
21+
22+
// CHECK: @{{.*}}WG_VAR = internal addrspace(3) global {{.*}} undef, {{.*}}

0 commit comments

Comments
 (0)