[clang] Sycl builtin kernel name (PR #140230)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 16 02:59:21 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
@llvm/pr-subscribers-clang-codegen
Author: Mariya Podchishchaeva (Fznamznon)
<details>
<summary>Changes</summary>
---
Patch is 27.51 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140230.diff
13 Files Affected:
- (modified) clang/include/clang/Basic/Builtins.h (+1)
- (modified) clang/include/clang/Basic/Builtins.td (+7)
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+6)
- (modified) clang/lib/AST/ExprConstant.cpp (+38)
- (modified) clang/lib/Basic/Builtins.cpp (+3)
- (modified) clang/lib/CodeGen/CGBuiltin.cpp (+77)
- (modified) clang/lib/CodeGen/CodeGenModule.cpp (+7-3)
- (modified) clang/lib/CodeGen/CodeGenModule.h (+11)
- (modified) clang/lib/CodeGen/CodeGenSYCL.cpp (+53-6)
- (modified) clang/lib/Sema/SemaChecking.cpp (+36)
- (added) clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp (+102)
- (added) clang/test/SemaSYCL/builtin-sycl-kernel-name.cpp (+59)
- (added) clang/test/SemaSYCL/builtin-sycl-kernel-param-count.cpp (+44)
``````````diff
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index 3a5e31de2bc50..6d8914d7074d4 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -45,6 +45,7 @@ enum LanguageID : uint16_t {
ALL_OCL_LANGUAGES = 0x800, // builtin for OCL languages.
HLSL_LANG = 0x1000, // builtin requires HLSL.
C23_LANG = 0x2000, // builtin requires C23 or later.
+ SYCL_LANG = 0x4000, // builtin requires SYCL.
ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages.
ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode.
ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode.
diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 11b1e247237a7..632dc8538a2a9 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -4794,6 +4794,13 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
let Prototype = "char const*(...)";
}
+// SYCL
+def SYCLKernelName : LangBuiltin<"SYCL_LANG"> {
+ let Spellings = ["__builtin_sycl_kernel_name"];
+ let Attributes = [NoThrow, Const, Constexpr, CustomTypeChecking];
+ let Prototype = "char const*(...)";
+}
+
// HLSL
def HLSLAddUint64: LangBuiltin<"HLSL_LANG"> {
let Spellings = ["__builtin_hlsl_adduint64"];
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 6e940a318b61d..2da2045415596 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -815,6 +815,9 @@ def warn_unreachable_association : Warning<
InGroup<UnreachableCodeGenericAssoc>;
/// Built-in functions.
+def err_builtin_invalid_argument_count : Error<
+ "builtin %plural{0:takes no arguments|1:takes one argument|"
+ ":requires exactly %0 arguments}0">;
def ext_implicit_lib_function_decl : ExtWarn<
"implicitly declaring library function '%0' with type %1">,
InGroup<ImplicitFunctionDeclare>;
@@ -12789,6 +12792,9 @@ def err_sycl_entry_point_deduced_return_type : Error<
def warn_cuda_maxclusterrank_sm_90 : Warning<
"maxclusterrank requires sm_90 or higher, CUDA arch provided: %0, ignoring "
"%1 attribute">, InGroup<IgnoredAttributes>;
+def err_sycl_kernel_name_invalid_arg : Error<"invalid argument; expected a class "
+ "or structure with a member typedef "
+ "or type alias alias named 'type'">;
// VTable pointer authentication errors
def err_non_polymorphic_vtable_pointer_auth : Error<
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86dbb349fd1a7..5be35c93f0aa1 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -52,6 +52,7 @@
#include "clang/Basic/Builtins.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/TargetBuiltins.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APFixedPoint.h"
#include "llvm/ADT/Sequence.h"
@@ -9918,6 +9919,26 @@ static bool isOneByteCharacterType(QualType T) {
return T->isCharType() || T->isChar8Type();
}
+static const SYCLKernelInfo *GetSYCLKernelInfo(ASTContext &Ctx,
+ const CallExpr *E) {
+ // Argument to the builtin is a type trait which is used to retrieve the
+ // kernel name type.
+ // FIXME: Improve the comment.
+ const Expr *NameExpr = E->getArg(0);
+ // FIXME: Implement diagnostic instead of assert.
+ assert(NameExpr->isEvaluatable(Ctx) &&
+ "KernelNameType should be evaluatable");
+ RecordDecl *RD = NameExpr->getType()->castAs<RecordType>()->getDecl();
+ IdentifierTable &IdentTable = Ctx.Idents;
+ auto Name = DeclarationName(&(IdentTable.get("type")));
+ NamedDecl *ND = (RD->lookup(Name)).front();
+ TypedefNameDecl *TD = cast<TypedefNameDecl>(ND);
+ CanQualType KernelNameType = Ctx.getCanonicalType(TD->getUnderlyingType());
+
+ // Retrieve KernelInfo using the kernel name.
+ return Ctx.findSYCLKernelInfo(KernelNameType);
+}
+
bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
unsigned BuiltinOp) {
if (IsOpaqueConstantCall(E))
@@ -10273,6 +10294,23 @@ bool PointerExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return false;
}
}
+ case Builtin::BI__builtin_sycl_kernel_name: {
+ const SYCLKernelInfo *KernelInfo = GetSYCLKernelInfo(Info.Ctx, E);
+ assert(KernelInfo && "Type does not correspond to a SYCL kernel name.");
+ // Retrieve the mangled name corresponding to kernel name type.
+ std::string ResultStr = KernelInfo->GetKernelName();
+ APInt Size(Info.Ctx.getTypeSize(Info.Ctx.getSizeType()),
+ ResultStr.size() + 1);
+ QualType StrTy =
+ Info.Ctx.getConstantArrayType(Info.Ctx.CharTy.withConst(), Size,
+ nullptr, ArraySizeModifier::Normal, 0);
+ StringLiteral *SL =
+ StringLiteral::Create(Info.Ctx, ResultStr, StringLiteralKind::Ordinary,
+ /*Pascal*/ false, StrTy, SourceLocation());
+ evaluateLValue(SL, Result);
+ Result.addArray(Info, E, cast<ConstantArrayType>(StrTy));
+ return true;
+ }
default:
return false;
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index 885abdc152e3a..f8275656c5d0c 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -185,6 +185,9 @@ static bool builtinIsSupported(const llvm::StringTable &Strings,
/* CUDA Unsupported */
if (!LangOpts.CUDA && BuiltinInfo.Langs == CUDA_LANG)
return false;
+ /* SYCL Unsupported */
+ if (!LangOpts.isSYCL() && BuiltinInfo.Langs == SYCL_LANG)
+ return false;
/* CPlusPlus Unsupported */
if (!LangOpts.CPlusPlus && BuiltinInfo.Langs == CXX_LANG)
return false;
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 4fdf2113cb9dc..2fbe6ae23b837 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -29,6 +29,7 @@
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Frontend/FrontendDiagnostic.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Intrinsics.h"
@@ -2526,6 +2527,66 @@ static RValue EmitHipStdParUnsupportedBuiltin(CodeGenFunction *CGF,
return RValue::get(CGF->Builder.CreateCall(UBF, Args));
}
+static const CanQualType GetKernelNameType(ASTContext &Ctx, const CallExpr *E) {
+ // The first argument to the builtin is an object that designates
+ // the SYCL kernel. The argument is evaluated and its value is
+ // discarded; the SYCL kernel is identified based on the argument
+ // type. The argument type is required to be a class or structure
+ // with a member typedef or type alias named 'type'. The target
+ // type of the 'type' member is the SYCL kernel name type.
+ RecordDecl *RD = E->getArg(0)->getType()->castAs<RecordType>()->getDecl();
+ IdentifierTable &IdentTable = Ctx.Idents;
+ auto Name = DeclarationName(&(IdentTable.get("type")));
+ NamedDecl *ND = (RD->lookup(Name)).front();
+ TypedefNameDecl *TD = cast<TypedefNameDecl>(ND);
+ return Ctx.getCanonicalType(TD->getUnderlyingType());
+}
+
+static llvm::GlobalVariable *
+EmitKernelNameGlobal(CodeGenModule &CGM, ASTContext &Ctx, const CallExpr *E) {
+ CanQualType KernelNameType = GetKernelNameType(Ctx, E);
+
+ // SmallString<256> KernelNameSymbol;
+ // llvm::raw_svector_ostream Out(KernelNameSymbol);
+ // The mangling used for the name of the global variable storing the offload
+ // kernel name is identical to the mangling of the offload kernel name.
+ // CGM.getCXXABI().getMangleContext().mangleSYCLKernelCallerName(KernelNameType,
+ // Out);
+ //
+
+ auto DeviceDiscriminatorOverrider =
+ [](ASTContext &Ctx, const NamedDecl *ND) -> UnsignedOrNone {
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(ND))
+ if (RD->isLambda())
+ return RD->getDeviceLambdaManglingNumber();
+ return std::nullopt;
+ };
+ std::unique_ptr<MangleContext> MC{ItaniumMangleContext::create(
+ Ctx, Ctx.getDiagnostics(), DeviceDiscriminatorOverrider)};
+
+ SmallString<256> KernelNameSymbol;
+ llvm::raw_svector_ostream Out(KernelNameSymbol);
+ //llvm::raw_string_ostream Out(KernelNameSymbol);
+ MC->mangleCanonicalTypeName(KernelNameType, Out);
+
+ llvm::GlobalVariable *GV = new llvm::GlobalVariable(
+ CGM.getModule(), CGM.GlobalsInt8PtrTy,
+ /*isConstant=*/true, llvm::GlobalValue::ExternalLinkage, nullptr,
+ KernelNameSymbol);
+
+ CGM.AddSYCLKernelNameSymbol(KernelNameType, GV);
+
+ return GV;
+}
+
+static const SYCLKernelInfo *GetSYCLKernelInfo(ASTContext &Ctx,
+ const CallExpr *E) {
+ CanQualType KernelNameType = GetKernelNameType(Ctx, E);
+
+ // Retrieve KernelInfo using the kernel name.
+ return Ctx.findSYCLKernelInfo(KernelNameType);
+}
+
RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const CallExpr *E,
ReturnValueSlot ReturnValue) {
@@ -6219,6 +6280,22 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
auto Str = CGM.GetAddrOfConstantCString(Name, "");
return RValue::get(Str.getPointer());
}
+ case Builtin::BI__builtin_sycl_kernel_name: {
+ // Retrieve the kernel info corresponding to kernel name type.
+ const SYCLKernelInfo *KernelInfo = GetSYCLKernelInfo(getContext(), E);
+
+ // This indicates that the builtin was called before the kernel was
+ // invoked. In this case, a global variable is declared, and returned
+ // as the result of the call to the builtin. This global variable is
+ // later initialized to hold the name of the offload kernel when kernel
+ // invocation is processed.
+ if (!KernelInfo)
+ return RValue::get(EmitKernelNameGlobal(CGM, getContext(), E));
+
+ // Emit the mangled name from KernelInfo if available.
+ auto Str = CGM.GetAddrOfConstantCString(KernelInfo->GetKernelName(), "");
+ return RValue::get(Str.getPointer());
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 50041f883cfe5..f21e09387922e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -3319,16 +3319,20 @@ void CodeGenModule::EmitDeferred() {
// a SYCL kernel caller offload entry point function is generated and
// emitted in place of each of these functions.
if (const auto *FD = D.getDecl()->getAsFunction()) {
- if (LangOpts.SYCLIsDevice && FD->hasAttr<SYCLKernelEntryPointAttr>() &&
- FD->isDefined()) {
+ if (FD->hasAttr<SYCLKernelEntryPointAttr>() && FD->isDefined()) {
// Functions with an invalid sycl_kernel_entry_point attribute are
// ignored during device compilation.
- if (!FD->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
+ if (LangOpts.SYCLIsDevice &&
+ !FD->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
// Generate and emit the SYCL kernel caller function.
EmitSYCLKernelCaller(FD, getContext());
// Recurse to emit any symbols directly or indirectly referenced
// by the SYCL kernel caller function.
EmitDeferred();
+ } else {
+ // Initialize the global variables corresponding to SYCL Builtins
+ // used to obtain information about the offload kernel.
+ InitSYCLKernelInfoSymbolsForBuiltins(FD, getContext());
}
// Do not emit the sycl_kernel_entry_point attributed function.
continue;
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 1db5c3bc4e4ef..3f5f11def5648 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -677,6 +677,7 @@ class CodeGenModule : public CodeGenTypeCache {
computeVTPointerAuthentication(const CXXRecordDecl *ThisClass);
AtomicOptions AtomicOpts;
+ llvm::DenseMap<CanQualType, llvm::GlobalVariable *> SYCLKernelNameSymbols;
public:
CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
@@ -1505,6 +1506,10 @@ class CodeGenModule : public CodeGenTypeCache {
/// annotations are emitted during finalization of the LLVM code.
void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
+ void AddSYCLKernelNameSymbol(CanQualType, llvm::GlobalVariable *);
+
+ llvm::GlobalVariable *GetSYCLKernelNameSymbol(CanQualType);
+
bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn,
SourceLocation Loc) const;
@@ -1975,6 +1980,12 @@ class CodeGenModule : public CodeGenTypeCache {
void EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,
ASTContext &Ctx);
+ /// Initialize the global variables corresponding to SYCL Builtins used to
+ /// obtain information about the offload kernel.
+ void
+ InitSYCLKernelInfoSymbolsForBuiltins(const FunctionDecl *KernelEntryPointFn,
+ ASTContext &Ctx);
+
/// Determine whether the definition must be emitted; if this returns \c
/// false, the definition can be emitted lazily if it's used.
bool MustBeEmitted(const ValueDecl *D);
diff --git a/clang/lib/CodeGen/CodeGenSYCL.cpp b/clang/lib/CodeGen/CodeGenSYCL.cpp
index b9a96fe8ab838..9f5efd126ba08 100644
--- a/clang/lib/CodeGen/CodeGenSYCL.cpp
+++ b/clang/lib/CodeGen/CodeGenSYCL.cpp
@@ -25,6 +25,24 @@ static void SetSYCLKernelAttributes(llvm::Function *Fn, CodeGenFunction &CGF) {
Fn->addFnAttr(llvm::Attribute::MustProgress);
}
+static CanQualType GetKernelNameType(const FunctionDecl *KernelEntryPointFn,
+ ASTContext &Ctx) {
+ const auto *KernelEntryPointAttr =
+ KernelEntryPointFn->getAttr<SYCLKernelEntryPointAttr>();
+ assert(KernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute");
+ CanQualType KernelNameType =
+ Ctx.getCanonicalType(KernelEntryPointAttr->getKernelName());
+ return KernelNameType;
+}
+
+static const SYCLKernelInfo *
+GetKernelInfo(const FunctionDecl *KernelEntryPointFn, ASTContext &Ctx) {
+ CanQualType KernelNameType = GetKernelNameType(KernelEntryPointFn, Ctx);
+ const SYCLKernelInfo *KernelInfo = Ctx.findSYCLKernelInfo(KernelNameType);
+ assert(KernelInfo && "Type does not correspond to a kernel name");
+ return KernelInfo;
+}
+
void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,
ASTContext &Ctx) {
assert(Ctx.getLangOpts().SYCLIsDevice &&
@@ -52,12 +70,10 @@ void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,
getTypes().arrangeSYCLKernelCallerDeclaration(Ctx.VoidTy, Args);
llvm::FunctionType *FnTy = getTypes().GetFunctionType(FnInfo);
- // Retrieve the generated name for the SYCL kernel caller function.
- CanQualType KernelNameType =
- Ctx.getCanonicalType(KernelEntryPointAttr->getKernelName());
- const SYCLKernelInfo &KernelInfo = Ctx.getSYCLKernelInfo(KernelNameType);
- auto *Fn = llvm::Function::Create(FnTy, llvm::Function::ExternalLinkage,
- KernelInfo.GetKernelName(), &getModule());
+ // Retrieve the generated name for the SYCL kernel caller function
+ const SYCLKernelInfo *KernelInfo = GetKernelInfo(KernelEntryPointFn, Ctx);
+ auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalVariable::ExternalLinkage,
+ KernelInfo->GetKernelName(), &getModule());
// Emit the SYCL kernel caller function.
CodeGenFunction CGF(*this);
@@ -70,3 +86,34 @@ void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,
SetLLVMFunctionAttributesForDefinition(cast<Decl>(OutlinedFnDecl), Fn);
CGF.FinishFunction();
}
+
+void CodeGenModule::AddSYCLKernelNameSymbol(CanQualType KernelNameType,
+ llvm::GlobalVariable *GV) {
+ SYCLKernelNameSymbols[KernelNameType] = GV;
+}
+
+llvm::GlobalVariable *
+CodeGenModule::GetSYCLKernelNameSymbol(CanQualType KernelNameType) {
+ auto it = SYCLKernelNameSymbols.find(KernelNameType);
+ if (it != SYCLKernelNameSymbols.end())
+ return it->second;
+ return nullptr;
+}
+
+void CodeGenModule::InitSYCLKernelInfoSymbolsForBuiltins(
+ const FunctionDecl *KernelEntryPointFn, ASTContext &Ctx) {
+ CanQualType KernelNameType = GetKernelNameType(KernelEntryPointFn, Ctx);
+ llvm::GlobalVariable *GV = GetSYCLKernelNameSymbol(KernelNameType);
+ if (GV && !GV->hasInitializer()) {
+ const SYCLKernelInfo *KernelInfo = GetKernelInfo(KernelEntryPointFn, Ctx);
+ ConstantAddress KernelNameStrConstantAddr =
+ GetAddrOfConstantCString(KernelInfo->GetKernelName(), "");
+ llvm::Constant *KernelNameStr = KernelNameStrConstantAddr.getPointer();
+ // FIXME: It is unclear to me whether the right API here is
+ // replaceInitializer or setInitializer. Unfortunately since the branch I am
+ // working on is outdated, my workspace does not have replaceInitializer
+ // Hopefully the person continuing to work on builtins can check this out.
+ GV->setInitializer(KernelNameStr);
+ GV->setLinkage(llvm::GlobalValue::PrivateLinkage);
+ }
+}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index d7c62b44a5c50..34786d3372bf4 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2219,6 +2219,26 @@ static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {
return false;
}
+// The argument must be a class or struct with a member
+// named type.
+static bool CheckBuiltinSyclKernelName(Sema &S, CallExpr *TheCall) {
+ QualType ArgTy = TheCall->getArg(0)->getType();
+ const auto *RT = ArgTy->getAs<RecordType>();
+
+ if(!RT)
+ return true;
+
+ RecordDecl *RD = RT->getDecl();
+ IdentifierTable &IdentTable = S.Context.Idents;
+ auto Name = DeclarationName(&(IdentTable.get("type")));
+ DeclContext::lookup_result Lookup = RD->lookup(Name);
+ if (Lookup.empty() || !Lookup.isSingleResult() ||
+ !isa<TypedefNameDecl>(Lookup.front()))
+ return true;
+
+ return false;
+}
+
ExprResult
Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
CallExpr *TheCall) {
@@ -3030,6 +3050,22 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
}
break;
}
+ case Builtin::BI__builtin_sycl_kernel_name: {
+ // Builtin takes 1 argument
+ if (TheCall->getNumArgs() != 1) {
+ Diag(TheCall->getBeginLoc(), diag::err_builtin_invalid_argument_count)
+ << 1;
+ return ExprError();
+ }
+
+ if (CheckBuiltinSyclKernelName(*this, TheCall)) {
+ Diag(TheCall->getArg(0)->getBeginLoc(),
+ diag::err_sycl_kernel_name_invalid_arg);
+ return ExprError();
+ }
+
+ break;
+ }
case Builtin::BI__builtin_popcountg:
if (BuiltinPopcountg(*this, TheCall))
return ExprError();
diff --git a/clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp b/clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp
new file mode 100644
index 0000000000000..d5d596aea2d3f
--- /dev/null
+++ b/clang/test/CodeGenSYCL/builtin-sycl-kernel-name.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -fsycl-is-host -emit-llvm -triple x86_64 %s -o - | FileCheck %s
+
+// Test IR generated by __builtin_sycl_kernel_name(). This builtin accepts a SYCL
+// kernel name type and returns it's mangled name.
+
+class kernel_name_1;
+class kernel_name_2;
+typedef kernel_name_2 kernel_name_TD;
+class kernel_name_3;
+class kernel_name_4;
+class kernel_name_5;
+typedef kernel_name_4 kernel_name_TD2;
+class kernel_name_6;
+
+struct constexpr_kernel_name;
+
+template<typename KN>
+struct kernel_id_t {
+ using type = KN;
+};
+
+struct kernel_id_nt {
+ using type = kernel_name_3;
+};
+
+template <typename name...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/140230
More information about the cfe-commits
mailing list