[clang] [llvm] [clang] Add spir_kernel attribute (PR #137882)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 1 07:15:08 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Nick Sarnie (sarnex)
<details>
<summary>Changes</summary>
SPIR kernels have a specific calling convention, so add an attribute to explicitly specify this calling convention when targetting pure SPIR/SPIRV.
---
Full diff: https://github.com/llvm/llvm-project/pull/137882.diff
14 Files Affected:
- (modified) clang/include/clang/Basic/Attr.td (+8)
- (modified) clang/include/clang/Basic/Specifiers.h (+1)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+1)
- (modified) clang/lib/AST/Type.cpp (+2)
- (modified) clang/lib/AST/TypePrinter.cpp (+3)
- (modified) clang/lib/Basic/Targets/SPIR.h (+4-2)
- (modified) clang/lib/CodeGen/CGCall.cpp (+2)
- (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+2)
- (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+17)
- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+6)
- (modified) clang/test/Misc/pragma-attribute-supported-attributes-list.test (+1)
- (added) clang/test/Misc/spir-kernel-attr.c (+10)
- (modified) llvm/include/llvm/BinaryFormat/Dwarf.def (+1)
- (modified) llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h (+3)
``````````diff
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))";
``````````
</details>
https://github.com/llvm/llvm-project/pull/137882
More information about the cfe-commits
mailing list