https://github.com/Siya-05 updated https://github.com/llvm/llvm-project/pull/236849
>From 0e049de8edf0ecc469976887efc918cb442b30c6 Mon Sep 17 00:00:00 2001 From: Sivapriya <[email protected]> Date: Thu, 29 Oct 2026 16:51:30 +0000 Subject: [PATCH 1/2] [CIR][CUDA] Support host-side texture registration --- .../clang/CIR/Dialect/IR/CIRCUDAAttrs.td | 3 +- clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp | 30 ++++++---- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 12 +++- .../Dialect/Transforms/LoweringPrepare.cpp | 24 +++++++- clang/test/CIR/CodeGenCUDA/texture.cu | 57 +++++++++++++++++++ 5 files changed, 111 insertions(+), 15 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/IR/CIRCUDAAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRCUDAAttrs.td index 8d6cb1bdbdd86d..ff58a0bd8eab1e 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRCUDAAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRCUDAAttrs.td @@ -72,7 +72,8 @@ def CIR_CUDAVarRegistrationInfoAttr : CIR_Attr<"CUDAVarRegistrationInfo", "cu.va "bool":$isExtern, "bool":$isConstant, "bool":$isManaged, - "int32_t":$surfTexType + "int32_t":$surfTexType, + "bool":$normalized ); let hasCustomAssemblyFormat = 1; diff --git a/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp b/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp index 03dfdfba65c7a4..74f38ad1314e7b 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCUDANV.cpp @@ -101,7 +101,8 @@ class CIRGenNVCUDARuntime : public CIRGenCUDARuntime { getDeviceSideName(cast<NamedDecl>(vd)), cir::CUDADeviceVarKind::Variable, isExtern, isConstant, vd->hasAttr<HIPManagedAttr>(), - /*surfTexType=*/0)); + /*surfTexType=*/0, + /*normalized=*/false)); deviceVars.push_back({ var, vd, @@ -119,7 +120,8 @@ class CIRGenNVCUDARuntime : public CIRGenCUDARuntime { getDeviceSideName(cast<NamedDecl>(vd)), cir::CUDADeviceVarKind::Surface, isExtern, /*isConstant=*/false, - /*isManaged=*/false, surfaceType)); + /*isManaged=*/false, surfaceType, + /*normalized=*/false)); deviceVars.push_back({ var, @@ -128,7 +130,8 @@ class CIRGenNVCUDARuntime : public CIRGenCUDARuntime { }); } - void registerDeviceTex(const VarDecl *vd, cir::GlobalOp &var, bool isExtern) { + void registerDeviceTex(const VarDecl *vd, cir::GlobalOp &var, bool isExtern, + int32_t textureType, bool normalized) { auto &builder = cgm.getBuilder(); var->setAttr(cir::CUDAVarRegistrationInfoAttr::getMnemonic(), @@ -137,8 +140,7 @@ class CIRGenNVCUDARuntime : public CIRGenCUDARuntime { getDeviceSideName(cast<NamedDecl>(vd)), cir::CUDADeviceVarKind::Texture, isExtern, /*isConstant=*/false, - /*isManaged=*/false, - /*surfTexType=*/0)); + /*isManaged=*/false, textureType, normalized)); deviceVars.push_back({ var, @@ -457,10 +459,6 @@ void CIRGenNVCUDARuntime::internalizeDeviceSideVar( d->getType()->isCUDADeviceBuiltinTextureType()) { linkage = cir::GlobalLinkageKind::InternalLinkage; } - - if (d->getType()->isCUDADeviceBuiltinTextureType()) - cgm.errorNYI(d->getSourceRange(), - "internalizeDeviceSideVar: CUDA Texture support"); } std::string CIRGenNVCUDARuntime::getDeviceSideName(const NamedDecl *nd) { @@ -538,8 +536,20 @@ void CIRGenNVCUDARuntime::handleVarRegistration(const VarDecl *vd, } else if (vd->getType()->isCUDADeviceBuiltinTextureType()) { // Builtin textures and their template arguments are also registered // with CUDA runtime. + const auto *td = cast<ClassTemplateSpecializationDecl>( + vd->getType()->castAsCXXRecordDecl()); + const TemplateArgumentList &args = td->getTemplateArgs(); + + assert(args.size() == 3 && + "Unexpected number of template arguments of CUDA device " + "builtin texture type."); + + llvm::APSInt textureType = args[1].getAsIntegral(); + llvm::APSInt normalized = args[2].getAsIntegral(); + if (!vd->hasExternalStorage()) - registerDeviceTex(vd, var, !vd->hasDefinition()); + registerDeviceTex(vd, var, !vd->hasDefinition(), + textureType.getSExtValue(), normalized.getZExtValue()); } } diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 0c92e222fe2c5b..9668f9824ec614 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -618,6 +618,11 @@ void CUDAVarRegistrationInfoAttr::print(AsmPrinter &p) const { p << ", managed"; if (getKind() == CUDADeviceVarKind::Surface) p << ", surface_type = " << getSurfTexType(); + else if (getKind() == CUDADeviceVarKind::Texture) { + p << ", texture_type = " << getSurfTexType(); + if (getNormalized()) + p << ", normalized"; + } p << ">"; } @@ -653,6 +658,7 @@ Attribute CUDAVarRegistrationInfoAttr::parse(AsmParser &parser, Type odsType) { bool isConstant = false; bool isManaged = false; int32_t surfTexType = 0; + bool normalized = false; while (parser.parseOptionalGreater().failed()) { if (parser.parseComma()) @@ -668,7 +674,9 @@ Attribute CUDAVarRegistrationInfoAttr::parse(AsmParser &parser, Type odsType) { isConstant = true; else if (flag == "managed") isManaged = true; - else if (flag == "surface_type") { + else if (flag == "normalized") + normalized = true; + else if (flag == "surface_type" || flag == "texture_type") { if (parser.parseEqual() || parser.parseInteger(surfTexType)) return {}; } else { @@ -678,7 +686,7 @@ Attribute CUDAVarRegistrationInfoAttr::parse(AsmParser &parser, Type odsType) { } return get(parser.getContext(), deviceSideName, *kind, isExtern, isConstant, - isManaged, surfTexType); + isManaged, surfTexType, normalized); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp index 0af8f16f190f4e..44ff2c02d0dcb6 100644 --- a/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp +++ b/clang/lib/CIR/Dialect/Transforms/LoweringPrepare.cpp @@ -3356,6 +3356,17 @@ void LoweringPreparePass::buildCUDARegisterVars(cir::CIRBaseBuilderTy &builder, {voidPtrPtrTy, voidPtrTy, voidPtrTy, voidPtrTy, intTy, intTy}, voidTy)); + // void __cudaRegisterTexture(void **fatbinHandle, + // const struct textureReference *hostVar, + // const void **deviceAddress, + // const char *deviceName, + // int textureType, int normalized, int ext); + FuncOp cudaRegisterTexture = buildRuntimeFunction( + globalBuilder, addUnderscoredPrefix(cudaPrefix, "RegisterTexture"), loc, + FuncType::get( + {voidPtrPtrTy, voidPtrTy, voidPtrTy, voidPtrTy, intTy, intTy, intTy}, + voidTy)); + auto makeConstantString = [&](llvm::StringRef str) -> GlobalOp { auto strType = ArrayType::get(&getContext(), charTy, 1 + str.size()); auto tmpString = cir::GlobalOp::create( @@ -3451,8 +3462,17 @@ void LoweringPreparePass::buildCUDARegisterVars(cir::CIRBaseBuilderTy &builder, break; } - case cir::CUDADeviceVarKind::Texture: - llvm_unreachable("Texture registration NYI"); + case cir::CUDADeviceVarKind::Texture: { + auto textureType = ConstantOp::create( + builder, loc, IntAttr::get(intTy, regAttr.getSurfTexType())); + auto normalized = ConstantOp::create( + builder, loc, IntAttr::get(intTy, regAttr.getNormalized() ? 1 : 0)); + + builder.createCallOp(loc, cudaRegisterTexture, + {fatbinHandle, hostVar, deviceName, deviceName, + textureType, normalized, isExtern}); + break; + } } } } diff --git a/clang/test/CIR/CodeGenCUDA/texture.cu b/clang/test/CIR/CodeGenCUDA/texture.cu index 3e669e365c201f..276f6d3f383e7c 100644 --- a/clang/test/CIR/CodeGenCUDA/texture.cu +++ b/clang/test/CIR/CodeGenCUDA/texture.cu @@ -1,9 +1,30 @@ + // REQUIRES: x86-registered-target // REQUIRES: nvptx-registered-target + +//===----------------------------------------------------------------------===// +// Device-side tests +//===----------------------------------------------------------------------===// + // RUN: %clang_cc1 -fclangir -std=c++11 -fcuda-is-device -triple nvptx64-nvidia-cuda -emit-cir -o - %s | FileCheck --check-prefix=CIR-DEVICE %s // RUN: %clang_cc1 -fclangir -std=c++11 -fcuda-is-device -triple nvptx64-nvidia-cuda -emit-llvm -o - %s | FileCheck --check-prefix=LLVM-DEVICE %s // RUN: %clang_cc1 -std=c++11 -fcuda-is-device -triple nvptx64-nvidia-cuda -emit-llvm -o - %s | FileCheck --check-prefix=OGCG-DEVICE %s +//===----------------------------------------------------------------------===// +// Host-side tests +//===----------------------------------------------------------------------===// + +// RUN: echo -n "GPU binary would be here." > %t +// RUN: %clang_cc1 -fclangir -std=c++11 -triple x86_64-unknown-linux-gnu \ +// RUN: -target-sdk-version=12.3 -fcuda-include-gpubinary %t \ +// RUN: -emit-cir -o - %s | FileCheck --check-prefix=CIR-HOST %s +// RUN: %clang_cc1 -fclangir -std=c++11 -triple x86_64-unknown-linux-gnu \ +// RUN: -target-sdk-version=12.3 -fcuda-include-gpubinary %t \ +// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=LLVM-HOST %s +// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu \ +// RUN: -target-sdk-version=12.3 -fcuda-include-gpubinary %t \ +// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=OGCG-HOST %s + struct textureReference { int desc; }; @@ -18,9 +39,45 @@ struct __attribute__((device_builtin_texture_type)) texture : public textureReference {}; texture<float, 2, NormalizedFloat> tex; +texture<float, 1, ElementType> tex_element; + +//===----------------------------------------------------------------------===// +// Device-side checks +//===----------------------------------------------------------------------===// // CIR-DEVICE: cir.global external target_address_space(1) @tex = #cir.undef : !cir.cuda_texture +// CIR-DEVICE: cir.global external target_address_space(1) @tex_element = #cir.undef : !cir.cuda_texture // CIR now matches OG CodeGen and emits undef for CUDA shadow variables. // LLVM-DEVICE: @tex ={{.*}} addrspace(1) externally_initialized global i64 undef +// LLVM-DEVICE: @tex_element ={{.*}} addrspace(1) externally_initialized global i64 undef + // OGCG-DEVICE: @tex ={{.*}} addrspace(1) externally_initialized global i64 undef +// OGCG-DEVICE: @tex_element ={{.*}} addrspace(1) externally_initialized global i64 undef + +//===----------------------------------------------------------------------===// +// Host-side checks +//===----------------------------------------------------------------------===// + +// Check the CUDA texture registration runtime declaration. +// CIR-HOST: cir.func private @__cudaRegisterTexture(!cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>, !cir.ptr<!void>, !cir.ptr<!void>, !s32i, !s32i, !s32i) + +// Check texture registration metadata. +// CIR-HOST-DAG: @tex = {{.*}}cu.var_registration = #cir.cu.var_registration<tex, Texture, texture_type = 2, normalized> +// CIR-HOST-DAG: @tex_element = {{.*}}cu.var_registration = #cir.cu.var_registration<tex_element, Texture, texture_type = 1> + +// Check that the host-side shadow variables are internalized. +// LLVM-HOST-DAG: @tex = internal global +// LLVM-HOST-DAG: @tex_element = internal global + +// Check the CIR-lowered LLVM registration calls. +// LLVM-HOST-LABEL: define internal void @__cuda_register_globals +// LLVM-HOST-SAME: (ptr %[[FATBIN:.*]]) +// LLVM-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex, ptr @[[TEX_NAME:.*]], ptr @[[TEX_NAME]], i32 2, i32 1, i32 0) +// LLVM-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex_element, ptr @[[ELEMENT_NAME:.*]], ptr @[[ELEMENT_NAME]], i32 1, i32 0, i32 0) + +// Check original Clang CodeGen registration calls. +// OGCG-HOST-LABEL: define internal void @__cuda_register_globals +// OGCG-HOST-SAME: (ptr %[[FATBIN:.*]]) +// OGCG-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex, ptr @[[TEX_NAME:.*]], ptr @[[TEX_NAME]], i32 2, i32 1, i32 0) +// OGCG-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex_element, ptr @[[ELEMENT_NAME:.*]], ptr @[[ELEMENT_NAME]], i32 1, i32 0, i32 0) >From 63d9b8e0e684cbe27ede177d0f93f79d51a111a7 Mon Sep 17 00:00:00 2001 From: Sivapriya <[email protected]> Date: Sat, 31 Oct 2026 13:46:21 +0000 Subject: [PATCH 2/2] [CIR][CUDA] Address texture registration review comments --- clang/lib/CIR/Dialect/IR/CIRAttrs.cpp | 22 +++++++++++++++++-- clang/test/CIR/CodeGenCUDA/texture.cu | 30 +++++++++++++++++++------- clang/test/CIR/IR/var-registration.cir | 9 ++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 9668f9824ec614..cf7d85e5c27402 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -674,9 +674,27 @@ Attribute CUDAVarRegistrationInfoAttr::parse(AsmParser &parser, Type odsType) { isConstant = true; else if (flag == "managed") isManaged = true; - else if (flag == "normalized") + else if (flag == "normalized") { + if (*kind != CUDADeviceVarKind::Texture) { + parser.emitError(parser.getCurrentLocation(), + "'normalized' is only valid for Texture"); + return {}; + } normalized = true; - else if (flag == "surface_type" || flag == "texture_type") { + } else if (flag == "surface_type") { + if (*kind != CUDADeviceVarKind::Surface) { + parser.emitError(parser.getCurrentLocation(), + "'surface_type' is only valid for Surface"); + return {}; + } + if (parser.parseEqual() || parser.parseInteger(surfTexType)) + return {}; + } else if (flag == "texture_type") { + if (*kind != CUDADeviceVarKind::Texture) { + parser.emitError(parser.getCurrentLocation(), + "'texture_type' is only valid for Texture"); + return {}; + } if (parser.parseEqual() || parser.parseInteger(surfTexType)) return {}; } else { diff --git a/clang/test/CIR/CodeGenCUDA/texture.cu b/clang/test/CIR/CodeGenCUDA/texture.cu index 276f6d3f383e7c..3d5ab92869b405 100644 --- a/clang/test/CIR/CodeGenCUDA/texture.cu +++ b/clang/test/CIR/CodeGenCUDA/texture.cu @@ -23,7 +23,7 @@ // RUN: -emit-llvm -o - %s | FileCheck --check-prefix=LLVM-HOST %s // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu \ // RUN: -target-sdk-version=12.3 -fcuda-include-gpubinary %t \ -// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=OGCG-HOST %s +// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=LLVM-HOST %s struct textureReference { int desc; @@ -62,6 +62,26 @@ texture<float, 1, ElementType> tex_element; // Check the CUDA texture registration runtime declaration. // CIR-HOST: cir.func private @__cudaRegisterTexture(!cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>, !cir.ptr<!void>, !cir.ptr<!void>, !s32i, !s32i, !s32i) +// Check the CIR registration calls and their arguments. +// CIR-HOST-LABEL: cir.func internal private @__cuda_register_globals( +// CIR-HOST-SAME: %[[FATBIN:.*]]: !cir.ptr<!cir.ptr<!void>> + +// First texture: texture_type = 2, normalized = 1. +// CIR-HOST: %[[TEX_GLOBAL:.*]] = cir.get_global @tex +// CIR-HOST: %[[TEX_PTR:.*]] = cir.cast bitcast %[[TEX_GLOBAL]] +// CIR-HOST: %[[ZERO:.*]] = cir.const #cir.int<0> : !s32i +// CIR-HOST: %[[TEX_TYPE:.*]] = cir.const #cir.int<2> : !s32i +// CIR-HOST: %[[NORMALIZED:.*]] = cir.const #cir.int<1> : !s32i +// CIR-HOST: cir.call @__cudaRegisterTexture(%[[FATBIN]], %[[TEX_PTR]], {{.*}}, {{.*}}, %[[TEX_TYPE]], %[[NORMALIZED]], %[[ZERO]]) + +// Second texture: texture_type = 1, normalized = 0. +// CIR-HOST: %[[ELEMENT_GLOBAL:.*]] = cir.get_global @tex_element +// CIR-HOST: %[[ELEMENT_PTR:.*]] = cir.cast bitcast %[[ELEMENT_GLOBAL]] +// CIR-HOST: %[[ELEMENT_ZERO:.*]] = cir.const #cir.int<0> : !s32i +// CIR-HOST: %[[ELEMENT_TYPE:.*]] = cir.const #cir.int<1> : !s32i +// CIR-HOST: %[[ELEMENT_NORMALIZED:.*]] = cir.const #cir.int<0> : !s32i +// CIR-HOST: cir.call @__cudaRegisterTexture(%[[FATBIN]], %[[ELEMENT_PTR]], {{.*}}, {{.*}}, %[[ELEMENT_TYPE]], %[[ELEMENT_NORMALIZED]], %[[ELEMENT_ZERO]]) + // Check texture registration metadata. // CIR-HOST-DAG: @tex = {{.*}}cu.var_registration = #cir.cu.var_registration<tex, Texture, texture_type = 2, normalized> // CIR-HOST-DAG: @tex_element = {{.*}}cu.var_registration = #cir.cu.var_registration<tex_element, Texture, texture_type = 1> @@ -70,14 +90,8 @@ texture<float, 1, ElementType> tex_element; // LLVM-HOST-DAG: @tex = internal global // LLVM-HOST-DAG: @tex_element = internal global -// Check the CIR-lowered LLVM registration calls. +// Check both CIR-lowered and original Clang CodeGen registration calls. // LLVM-HOST-LABEL: define internal void @__cuda_register_globals // LLVM-HOST-SAME: (ptr %[[FATBIN:.*]]) // LLVM-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex, ptr @[[TEX_NAME:.*]], ptr @[[TEX_NAME]], i32 2, i32 1, i32 0) // LLVM-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex_element, ptr @[[ELEMENT_NAME:.*]], ptr @[[ELEMENT_NAME]], i32 1, i32 0, i32 0) - -// Check original Clang CodeGen registration calls. -// OGCG-HOST-LABEL: define internal void @__cuda_register_globals -// OGCG-HOST-SAME: (ptr %[[FATBIN:.*]]) -// OGCG-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex, ptr @[[TEX_NAME:.*]], ptr @[[TEX_NAME]], i32 2, i32 1, i32 0) -// OGCG-HOST: call void @__cudaRegisterTexture(ptr %[[FATBIN]], ptr @tex_element, ptr @[[ELEMENT_NAME:.*]], ptr @[[ELEMENT_NAME]], i32 1, i32 0, i32 0) diff --git a/clang/test/CIR/IR/var-registration.cir b/clang/test/CIR/IR/var-registration.cir index 27bef91b8c9383..bf791c09b8ebf4 100644 --- a/clang/test/CIR/IR/var-registration.cir +++ b/clang/test/CIR/IR/var-registration.cir @@ -5,4 +5,13 @@ module { // CHECK: cir.global {{.*}} @i = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<i, Variable, extern>} cir.global "private" internal dso_local @i = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<i, Variable, extern>} + + // CHECK: cir.global {{.*}} @surf = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<surf, Surface, surface_type = 2>} + cir.global "private" internal dso_local @surf = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<surf, Surface, surface_type = 2>} + + // CHECK: cir.global {{.*}} @tex = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<tex, Texture, texture_type = 2, normalized>} + cir.global "private" internal dso_local @tex = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<tex, Texture, texture_type = 2, normalized>} + + // CHECK: cir.global {{.*}} @tex_element = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<tex_element, Texture, texture_type = 1>} + cir.global "private" internal dso_local @tex_element = #cir.poison : !s32i align(4) {cu.var_registration = #cir.cu.var_registration<tex_element, Texture, texture_type = 1>} } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
