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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to