diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1037,7 +1037,7 @@ void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); /// Add a global to a list to be added to the llvm.used metadata. - void addUsedGlobal(llvm::GlobalValue *GV); + void addUsedGlobal(llvm::GlobalValue *GV, bool SkipCheck = false); /// Add a global to a list to be added to the llvm.compiler.used metadata. void addCompilerUsedGlobal(llvm::GlobalValue *GV); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1916,9 +1916,9 @@ } } -void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) { - assert(!GV->isDeclaration() && - "Only globals with definition can force usage."); +void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV, bool SkipCheck) { + assert(SkipCheck || (!GV->isDeclaration() && + "Only globals with definition can force usage.")); LLVMUsed.emplace_back(GV); } @@ -4071,9 +4071,17 @@ } } - if (!IsHIPPinnedShadowVar) + // HIPPinnedShadowVar should remain in the final code object irrespective of + // whether it is used or not within the code. Add it to used list, so that + // it will not get eliminated when it is unused. Also, it is an extern var + // within device code, and it should *not* get initialized within device code. + if (IsHIPPinnedShadowVar) + addUsedGlobal(GV, /*SkipCheck=*/true); + else GV->setInitializer(Init); - if (emitter) emitter->finalize(GV); + + if (emitter) + emitter->finalize(GV); // If it is safe to mark the global 'constant', do so now. GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor && diff --git a/clang/test/CodeGenCUDA/hip-pinned-shadow.cu b/clang/test/CodeGenCUDA/hip-pinned-shadow.cu --- a/clang/test/CodeGenCUDA/hip-pinned-shadow.cu +++ b/clang/test/CodeGenCUDA/hip-pinned-shadow.cu @@ -4,6 +4,8 @@ // RUN: -emit-llvm -o - -x hip %s | FileCheck -check-prefixes=HIPDEV %s // RUN: %clang_cc1 -triple x86_64 -std=c++11 \ // RUN: -emit-llvm -o - -x hip %s | FileCheck -check-prefixes=HIPHOST %s +// RUN: %clang_cc1 -triple amdgcn -fcuda-is-device -std=c++11 -fvisibility hidden -fapply-global-visibility-to-externs \ +// RUN: -O3 -emit-llvm -o - -x hip %s | FileCheck -check-prefixes=HIPDEVUNSED %s struct textureReference { int a; @@ -21,3 +23,5 @@ // HIPDEV-NOT: declare{{.*}}void @_ZN7textureIfLi2ELi1EEC1Ev // HIPHOST: define{{.*}}@_ZN7textureIfLi2ELi1EEC1Ev // HIPHOST: call i32 @__hipRegisterVar{{.*}}@tex{{.*}}i32 0, i32 4, i32 0, i32 0) +// HIPDEVUNSED: @tex = external addrspace(1) global %struct.texture +// HIPDEVUNSED-NOT: declare{{.*}}void @_ZN7textureIfLi2ELi1EEC1Ev