Index: clang/lib/CodeGen/CodeGenModule.cpp =================================================================== --- clang/lib/CodeGen/CodeGenModule.cpp +++ clang/lib/CodeGen/CodeGenModule.cpp @@ -2549,12 +2549,16 @@ // If this is CUDA, be selective about which declarations we emit. if (LangOpts.CUDA) { if (LangOpts.CUDAIsDevice) { + bool IsConstexprVar = false; + if (auto *VD = dyn_cast(Global)) + IsConstexprVar = VD->isConstexpr(); if (!Global->hasAttr() && !Global->hasAttr() && !Global->hasAttr() && !Global->hasAttr() && !Global->getType()->isCUDADeviceBuiltinSurfaceType() && - !Global->getType()->isCUDADeviceBuiltinTextureType()) + !Global->getType()->isCUDADeviceBuiltinTextureType() && + !IsConstexprVar) return; } else { // We need to emit host-side 'shadows' for all global Index: clang/test/CodeGenCUDA/constexpr-variables.cu =================================================================== --- /dev/null +++ clang/test/CodeGenCUDA/constexpr-variables.cu @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -o - -triple nvptx \ +// RUN: -fcuda-is-device | FileCheck --check-prefixes=COM,CXX14 %s +// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - -triple nvptx \ +// RUN: -fcuda-is-device | FileCheck --check-prefixes=COM,CXX17 %s + +#include "Inputs/cuda.h" + +// COM: @_ZL1a = internal {{.*}}constant i32 7 +constexpr int a = 7; +__constant__ const int &use_a = a; + +namespace B { + // COM: @_ZN1BL1bE = internal {{.*}}constant i32 9 + constexpr int b = 9; +} +__constant__ const int &use_B_b = B::b; + +struct Q { + // CXX14: @_ZN1Q1kE = available_externally {{.*}}constant i32 5 + // CXX17: @_ZN1Q1kE = linkonce_odr {{.*}}constant i32 5 + static constexpr int k = 5; +}; +__constant__ const int &use_Q_k = Q::k; + +template struct X { + // CXX14: @_ZN1XIiE1aE = available_externally {{.*}}constant i32 123 + // CXX17: @_ZN1XIiE1aE = linkonce_odr {{.*}}constant i32 123 + static constexpr int a = 123; +}; +__constant__ const int &use_X_a = X::a;