Index: include/clang/Basic/Attr.td =================================================================== --- include/clang/Basic/Attr.td +++ include/clang/Basic/Attr.td @@ -962,10 +962,11 @@ let LangOpts = [CUDA]; } -def CUDADeviceBuiltinTextureType : IgnoredAttr { +def CUDADeviceBuiltinTextureType : TypeAttr { let Spellings = [GNU<"device_builtin_texture_type">, Declspec<"__device_builtin_texture_type__">]; let LangOpts = [CUDA]; + let Documentation = [DeviceBuiltinTextureTypeDocs]; } def CUDAGlobal : InheritableAttr { Index: include/clang/Basic/AttrDocs.td =================================================================== --- include/clang/Basic/AttrDocs.td +++ include/clang/Basic/AttrDocs.td @@ -4157,3 +4157,19 @@ ``__attribute__((malloc))``. }]; } + +def DeviceBuiltinTextureTypeDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The GNU style attribute __attribute__((device_builtin_texture_type)) or MSVC +style attribute __declspec(device_builtin_texture_type) can be added to the +definition of a class template to indicate it is the HIP builtin texture type. +It is ignored for CUDA and other languages. + + .. code-block:: c++ + + template + struct __attribute__((device_builtin_texture_type)) texture { ... } + + }]; +} \ No newline at end of file Index: lib/AST/TypePrinter.cpp =================================================================== --- lib/AST/TypePrinter.cpp +++ lib/AST/TypePrinter.cpp @@ -1511,6 +1511,7 @@ case attr::SPtr: case attr::UPtr: case attr::AddressSpace: + case attr::CUDADeviceBuiltinTextureType: llvm_unreachable("This attribute should have been handled already"); case attr::NSReturnsRetained: Index: lib/CodeGen/CodeGenModule.cpp =================================================================== --- lib/CodeGen/CodeGenModule.cpp +++ lib/CodeGen/CodeGenModule.cpp @@ -2388,6 +2388,12 @@ return ConstantAddress(Aliasee, Alignment); } +static bool isCUDATextureType(const QualType &T) { + return T->isRecordType() && T->getAs() + ->getDecl() + ->hasAttr(); +} + void CodeGenModule::EmitGlobal(GlobalDecl GD) { const auto *Global = cast(GD.getDecl()); @@ -2414,7 +2420,8 @@ if (!Global->hasAttr() && !Global->hasAttr() && !Global->hasAttr() && - !Global->hasAttr()) + !Global->hasAttr() && + !(isCUDATextureType(Global->getType()) && LangOpts.HIP)) return; } else { // We need to emit host-side 'shadows' for all global @@ -3769,7 +3776,9 @@ !getLangOpts().CUDAIsDevice && (D->hasAttr() || D->hasAttr() || D->hasAttr()); - if (getLangOpts().CUDA && (IsCUDASharedVar || IsCUDAShadowVar)) + if (getLangOpts().CUDA && + (IsCUDASharedVar || IsCUDAShadowVar || + (getLangOpts().CUDAIsDevice && isCUDATextureType(D->getType())))) Init = llvm::UndefValue::get(getTypes().ConvertType(ASTTy)); else if (!InitExpr) { // This is a tentative definition; tentative definitions are @@ -3880,7 +3889,8 @@ // global variables become internal definitions. These have to // be internal in order to prevent name conflicts with global // host variables with the same name in a different TUs. - if (D->hasAttr() || D->hasAttr()) { + if (D->hasAttr() || D->hasAttr() || + (isCUDATextureType(D->getType()) && LangOpts.HIP)) { Linkage = llvm::GlobalValue::InternalLinkage; // Shadow variables and their properties must be registered Index: lib/CodeGen/TargetInfo.cpp =================================================================== --- lib/CodeGen/TargetInfo.cpp +++ lib/CodeGen/TargetInfo.cpp @@ -7848,7 +7848,13 @@ return D->hasAttr() || (isa(D) && D->hasAttr()) || (isa(D) && - (D->hasAttr() || D->hasAttr())); + (D->hasAttr() || D->hasAttr() || + (cast(D)->getType()->isRecordType() && + cast(D) + ->getType() + ->getAs() + ->getDecl() + ->hasAttr()))); } void AMDGPUTargetCodeGenInfo::setTargetAttributes( Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -6786,6 +6786,9 @@ case ParsedAttr::AT_CUDAHost: handleSimpleAttributeWithExclusions(S, D, AL); break; + case ParsedAttr::AT_CUDADeviceBuiltinTextureType: + handleSimpleAttribute(S, D, AL); + break; case ParsedAttr::AT_GNUInline: handleGNUInlineAttr(S, D, AL); break; Index: test/CodeGenCUDA/texture.cu =================================================================== --- /dev/null +++ test/CodeGenCUDA/texture.cu @@ -0,0 +1,28 @@ +// REQUIRES: amdgpu-registered-target + +// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -std=c++11 -fcuda-is-device \ +// RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CUDADEV %s +// RUN: %clang_cc1 -triple x86_64 -std=c++11 \ +// RUN: -emit-llvm -o - %s | FileCheck -check-prefixes=CUDAHOST %s + +// RUN: %clang_cc1 -triple amdgcn -fcuda-is-device -std=c++11 -fvisibility hidden -fapply-global-visibility-to-externs \ +// 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 + +struct textureReference { + int a; +}; + +template +struct __attribute__((device_builtin_texture_type)) texture : public textureReference { +texture() { a = 1; } +}; + +texture tex; +// CUDADEV-NOT: @tex +// CUDAHOST-NOT: call i32 @__hipRegisterVar{{.*}}@tex +// HIPDEV: @tex = protected addrspace(1) global %struct.texture undef +// HIPDEV-NOT: declare{{.*}}void @_ZN7textureIfLi2ELi1EEC1Ev +// HIPHOST: define{{.*}}@_ZN7textureIfLi2ELi1EEC1Ev +// HIPHOST: call i32 @__hipRegisterVar{{.*}}@tex Index: test/SemaCUDA/attr-declspec.cu =================================================================== --- test/SemaCUDA/attr-declspec.cu +++ test/SemaCUDA/attr-declspec.cu @@ -6,11 +6,12 @@ // RUN: %clang_cc1 -DEXPECT_WARNINGS -fms-extensions -fsyntax-only -verify -x c %s #if defined(EXPECT_WARNINGS) -// expected-warning@+12 {{'__device__' attribute ignored}} -// expected-warning@+12 {{'__global__' attribute ignored}} -// expected-warning@+12 {{'__constant__' attribute ignored}} -// expected-warning@+12 {{'__shared__' attribute ignored}} -// expected-warning@+12 {{'__host__' attribute ignored}} +// expected-warning@+13 {{'__device__' attribute ignored}} +// expected-warning@+13 {{'__global__' attribute ignored}} +// expected-warning@+13 {{'__constant__' attribute ignored}} +// expected-warning@+13 {{'__shared__' attribute ignored}} +// expected-warning@+13 {{'__host__' attribute ignored}} +// expected-warning@+19 {{'__device_builtin_texture_type__' attribute ignored}} // // (Currently we don't for the other attributes. They are implemented with // IgnoredAttr, which is ignored irrespective of any LangOpts.) Index: test/SemaCUDA/attributes-on-non-cuda.cu =================================================================== --- test/SemaCUDA/attributes-on-non-cuda.cu +++ test/SemaCUDA/attributes-on-non-cuda.cu @@ -7,11 +7,12 @@ // RUN: %clang_cc1 -DEXPECT_WARNINGS -fsyntax-only -verify -x c %s #if defined(EXPECT_WARNINGS) -// expected-warning@+12 {{'device' attribute ignored}} -// expected-warning@+12 {{'global' attribute ignored}} -// expected-warning@+12 {{'constant' attribute ignored}} -// expected-warning@+12 {{'shared' attribute ignored}} -// expected-warning@+12 {{'host' attribute ignored}} +// expected-warning@+13 {{'device' attribute ignored}} +// expected-warning@+13 {{'global' attribute ignored}} +// expected-warning@+13 {{'constant' attribute ignored}} +// expected-warning@+13 {{'shared' attribute ignored}} +// expected-warning@+13 {{'host' attribute ignored}} +// expected-warning@+20 {{'device_builtin_texture_type' attribute ignored}} // // NOTE: IgnoredAttr in clang which is used for the rest of // attributes ignores LangOpts, so there are no warnings.