https://github.com/sarnex updated https://github.com/llvm/llvm-project/pull/137882
>From be91732b261f7a4874a9b1789fbf9bff6359cd58 Mon Sep 17 00:00:00 2001 From: "Sarnie, Nick" <nick.sar...@intel.com> Date: Wed, 30 Apr 2025 13:59:46 -0700 Subject: [PATCH] [clang] Add spir_kernel attribute Signed-off-by: Sarnie, Nick <nick.sar...@intel.com> --- clang/include/clang/Basic/Attr.td | 8 ++++++++ clang/include/clang/Basic/Specifiers.h | 1 + clang/lib/AST/ItaniumMangle.cpp | 1 + clang/lib/AST/Type.cpp | 2 ++ clang/lib/AST/TypePrinter.cpp | 3 +++ clang/lib/Basic/Targets/SPIR.h | 6 ++++-- clang/lib/CodeGen/CGCall.cpp | 2 ++ clang/lib/CodeGen/CGDebugInfo.cpp | 2 ++ clang/lib/CodeGen/Targets/SPIR.cpp | 17 +++++++++++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 6 ++++++ ...gma-attribute-supported-attributes-list.test | 1 + clang/test/Misc/spir-kernel-attr.c | 10 ++++++++++ llvm/include/llvm/BinaryFormat/Dwarf.def | 1 + .../llvm/DebugInfo/DWARF/DWARFTypePrinter.h | 3 +++ 14 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 clang/test/Misc/spir-kernel-attr.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a734eb6658c3d..c3a3db095bb81 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -472,7 +472,9 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>; def TargetX86 : TargetArch<["x86"]>; def TargetX86_64 : TargetArch<["x86_64"]>; def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; +def TargetSPIR : TargetArch<["spir", "spir64"]>; def TargetSPIRV : TargetArch<["spirv", "spirv32", "spirv64"]>; +def TargetAnySPIR : TargetArch<!listconcat(TargetSPIR.Arches, TargetSPIRV.Arches)>; def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>; def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>; def TargetWindows : TargetSpec { @@ -1504,6 +1506,12 @@ def NVPTXKernel : InheritableAttr, TargetSpecificAttr<TargetNVPTX> { let Documentation = [Undocumented]; } +def SPIRKernel : InheritableAttr, TargetSpecificAttr<TargetAnySPIR> { + let Spellings = [Clang<"spir_kernel">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [Undocumented]; +} + def HIPManaged : InheritableAttr { let Spellings = [GNU<"managed">, Declspec<"__managed__">]; let Subjects = SubjectList<[Var]>; diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 491badcc804e7..f9a72f378490e 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -289,6 +289,7 @@ namespace clang { CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) CC_SpirFunction, // default for OpenCL functions on SPIR target + CC_SpirKernel, // __attribute__((spir_kernel)) CC_OpenCLKernel, // inferred for OpenCL kernels CC_Swift, // __attribute__((swiftcall)) CC_SwiftAsync, // __attribute__((swiftasynccall)) diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 33a8728728574..c16005ccaf51f 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3532,6 +3532,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) { case CC_AMDGPUKernelCall: case CC_IntelOclBicc: case CC_SpirFunction: + case CC_SpirKernel: case CC_OpenCLKernel: case CC_PreserveMost: case CC_PreserveAll: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 59369fba2e772..da9ba8e3e971a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3623,6 +3623,8 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) { return "intel_ocl_bicc"; case CC_SpirFunction: return "spir_function"; + case CC_SpirKernel: + return "spir_kernel"; case CC_OpenCLKernel: return "opencl_kernel"; case CC_Swift: diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index cba1a2d98d660..5aa37ca9ec17f 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1115,6 +1115,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info, case CC_OpenCLKernel: // Do nothing. These CCs are not available as attributes. break; + case CC_SpirKernel: + OS << " __attribute__((spir_kernel))"; + break; case CC_Swift: OS << " __attribute__((swiftcall))"; break; diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index bf249e271a870..43c71a1aeb5d5 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -191,8 +191,10 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { } CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { - return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK - : CCCR_Warning; + return (CC == CC_SpirKernel || CC == CC_SpirFunction || + CC == CC_OpenCLKernel) + ? CCCR_OK + : CCCR_Warning; } CallingConv getDefaultCallingConv() const override { diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 83b0e8e965770..a7bbff116b584 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -84,6 +84,8 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) { return llvm::CallingConv::AMDGPU_KERNEL; case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC; + case CC_SpirKernel: + return llvm::CallingConv::SPIR_KERNEL; case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv(); case CC_PreserveMost: diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index f3ec498d4064b..10fba7b772486 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1589,6 +1589,8 @@ static unsigned getDwarfCC(CallingConv CC) { return llvm::dwarf::DW_CC_LLVM_IntelOclBicc; case CC_SpirFunction: return llvm::dwarf::DW_CC_LLVM_SpirFunction; + case CC_SpirKernel: + return llvm::dwarf::DW_CC_LLVM_SpirKernel; case CC_OpenCLKernel: case CC_AMDGPUKernelCall: return llvm::dwarf::DW_CC_LLVM_OpenCLKernel; diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index f35c124f50aa0..29a258e457317 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -60,6 +60,8 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo { llvm::Type *ElementType, llvm::LLVMContext &Ctx) const; void setOCLKernelStubCallingConvention(const FunctionType *&FT) const override; + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; }; class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo { public: @@ -238,6 +240,20 @@ void CommonSPIRTargetCodeGenInfo::setOCLKernelStubCallingConvention( FT, FT->getExtInfo().withCallingConv(CC_SpirFunction)); } +void CommonSPIRTargetCodeGenInfo::setTargetAttributes( + const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); + if (!FD) + return; + + llvm::Function *F = cast<llvm::Function>(GV); + + // Attach kernel metadata directly if compiling for SPIR. + if (FD->hasAttr<SPIRKernelAttr>()) { + F->setCallingConv(llvm::CallingConv::SPIR_KERNEL); + } +} + LangAS SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const { @@ -262,6 +278,7 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, void SPIRVTargetCodeGenInfo::setTargetAttributes( const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { + CommonSPIRTargetCodeGenInfo::setTargetAttributes(D, GV, M); if (!M.getLangOpts().HIP || M.getTarget().getTriple().getVendor() != llvm::Triple::AMD) return; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ab66ae860f86b..56aea1e878f23 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5503,6 +5503,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, llvm::Log2_64(ABIVLen) - 5); break; } + case ParsedAttr::AT_SPIRKernel: + CC = CC_SpirKernel; + break; default: llvm_unreachable("unexpected attribute kind"); } @@ -7152,6 +7155,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_CUDALaunchBounds: handleLaunchBoundsAttr(S, D, AL); break; + case ParsedAttr::AT_SPIRKernel: + handleSimpleAttribute<SPIRKernelAttr>(S, D, AL); + break; case ParsedAttr::AT_Restrict: handleRestrictAttr(S, D, AL); break; diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 7affacb1a109a..53a7ea4c8033b 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -181,6 +181,7 @@ // CHECK-NEXT: ReturnTypestate (SubjectMatchRule_function, SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: ReturnsNonNull (SubjectMatchRule_objc_method, SubjectMatchRule_function) // CHECK-NEXT: ReturnsTwice (SubjectMatchRule_function) +// CHECK-NEXT: SPIRKernel (SubjectMatchRule_function) // CHECK-NEXT: SYCLKernelEntryPoint (SubjectMatchRule_function) // CHECK-NEXT: SYCLSpecialClass (SubjectMatchRule_record) // CHECK-NEXT: ScopedLockable (SubjectMatchRule_record) diff --git a/clang/test/Misc/spir-kernel-attr.c b/clang/test/Misc/spir-kernel-attr.c new file mode 100644 index 0000000000000..40de980716ff2 --- /dev/null +++ b/clang/test/Misc/spir-kernel-attr.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -triple spir -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple spir64 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple spirv32 -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple spirv64 -emit-llvm %s -o - | FileCheck %s +__attribute__((spir_kernel)) void foo(void) {} + +[[clang::spir_kernel]] void bar(void) {} + +// CHECK-COUNT-2: spir_kernel diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def index e52324a8ebc12..575ab05f4e3c4 100644 --- a/llvm/include/llvm/BinaryFormat/Dwarf.def +++ b/llvm/include/llvm/BinaryFormat/Dwarf.def @@ -1127,6 +1127,7 @@ HANDLE_DW_CC(0xcd, LLVM_PreserveNone) HANDLE_DW_CC(0xce, LLVM_RISCVVectorCall) HANDLE_DW_CC(0xcf, LLVM_SwiftTail) HANDLE_DW_CC(0xd0, LLVM_RISCVVLSCall) +HANDLE_DW_CC(0xd1, LLVM_SpirKernel) // From GCC source code (include/dwarf2.h): This DW_CC_ value is not currently // generated by any toolchain. It is used internally to GDB to indicate OpenCL // C functions that have been compiled with the IBM XL C for OpenCL compiler and diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h index bd25f6c30ebf1..82337774f2396 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h @@ -741,6 +741,9 @@ void DWARFTypePrinter<DieType>::appendSubroutineNameAfter( // instantiated with function types with these calling conventions won't // have distinct names - so we'd need to fix that too) break; + case dwarf::CallingConvention::DW_CC_LLVM_SpirKernel: + OS << " __attribute((spir_kernel))"; + break; case dwarf::CallingConvention::DW_CC_LLVM_Swift: // SwiftAsync missing OS << " __attribute__((swiftcall))"; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits