diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d3135ccfb0adf..c5a1a9d25144e 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1276,7 +1276,8 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) { ctor.addInt(Int32Ty, I.Priority); ctor.add(llvm::ConstantExpr::getBitCast(I.Initializer, CtorPFTy)); if (I.AssociatedData) - ctor.add(llvm::ConstantExpr::getBitCast(I.AssociatedData, VoidPtrTy)); + ctor.add(llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast( + I.AssociatedData, VoidPtrTy)); else ctor.addNullPointer(VoidPtrTy); ctor.finishAndAddTo(ctors); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index c9401264140e6..882f826913ab1 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -5264,16 +5264,21 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation, // Make sure to pass the instantiated variable to the consumer at the end. struct PassToConsumerRAII { + Sema &SemaRef; ASTConsumer &Consumer; VarDecl *Var; - PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var) - : Consumer(Consumer), Var(Var) { } + PassToConsumerRAII(Sema &SemaRef, ASTConsumer &Consumer, VarDecl *Var) + : SemaRef(SemaRef), Consumer(Consumer), Var(Var) {} ~PassToConsumerRAII() { - Consumer.HandleCXXStaticMemberVarInstantiation(Var); + // Do not explicitly emit non-const static data member definitions + // on SYCL device. + if (!SemaRef.getLangOpts().SYCLIsDevice || !Var->isStaticDataMember() || + Var->isConstexpr() || Var->getType().isConstQualified()) + Consumer.HandleCXXStaticMemberVarInstantiation(Var); } - } PassToConsumerRAII(Consumer, Var); + } PassToConsumerRAII(*this, Consumer, Var); // If we already have a definition, we're done. if (VarDecl *Def = Var->getDefinition()) { diff --git a/clang/test/CodeGenSYCL/sycl-device-static-init.cpp b/clang/test/CodeGenSYCL/sycl-device-static-init.cpp new file mode 100644 index 0000000000000..8ff1869ed7d74 --- /dev/null +++ b/clang/test/CodeGenSYCL/sycl-device-static-init.cpp @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s +// Test that static initializers do not force the emission of globals on sycl device + +// CHECK: %struct._ZTS16RegisterBaseInit.RegisterBaseInit = type { i8 } +// CHECK-NOT: $_ZN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = comdat any +// CHECK: $_ZN8BaseInitI12TestBaseTypeE3varE = comdat any +// CHECK: @_ZN8BaseInitI12TestBaseTypeE9s_regbaseE = {{.*}} global %struct._ZTS16RegisterBaseInit.RegisterBaseInit +// CHECK-NOT: @_ZN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = weak_odr addrspace(1) global %struct._ZTS16RegisterBaseInit.RegisterBaseInit zeroinitializer, comdat, align 1 +// CHECK: @_ZN8BaseInitI12TestBaseTypeE3varE = weak_odr addrspace(1) constant i32 9, comdat, align 4 +// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init, i8* addrspacecast (i8 addrspace(1)* getelementptr inbounds (%struct._ZTS16RegisterBaseInit.RegisterBaseInit, %struct._ZTS16RegisterBaseInit.RegisterBaseInit addrspace(1)* @_ZN8BaseInitI12TestBaseTypeE9s_regbaseE, i32 0, i32 0) to i8*) }] +// CHECK-NOT: @_ZGVN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = weak_odr global i64 0, comdat($_ZN8BaseInitI12TestBaseTypeE9s_regbaseE), align 8 +// CHECK: define spir_kernel void @_ZTSZ4mainE11fake_kernel() +// CHECK: call spir_func void @"_ZZ4mainENK3$_0clE16RegisterBaseInit +// CHECK: declare spir_func void @_ZN16RegisterBaseInit3fooEv + +struct TestBaseType {}; +struct RegisterBaseInit { + __attribute__((sycl_device)) void foo(); + RegisterBaseInit(); +}; +template +struct BaseInit { + static const RegisterBaseInit s_regbase; + static RegisterBaseInit s_regbase_ncsdm; + static const int var; +}; +template +const RegisterBaseInit BaseInit::s_regbase; +template +RegisterBaseInit BaseInit::s_regbase_ncsdm; +template +const int BaseInit::var = 9; +template struct BaseInit; +template +__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + kernelFunc(BaseInit::s_regbase); +} +int main() { + kernel_single_task([=](RegisterBaseInit s) { + s.foo(); + }); + return 0; +}