https://github.com/koparasy updated 
https://github.com/llvm/llvm-project/pull/213728

>From a81e0c8a8531d8a8e97cf80f0fe11ff4fce8d486 Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <[email protected]>
Date: Mon, 3 Aug 2026 10:37:17 -0700
Subject: [PATCH 1/3] [CIR] Support SYCL kernel call statement in host codegen

---
 clang/lib/CIR/CodeGen/CIRGenFunction.h        |  6 +++
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 20 +++++++++
 clang/lib/CIR/CodeGen/CIRGenSYCL.cpp          | 35 +++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenStmt.cpp          |  4 +-
 clang/lib/CIR/CodeGen/CMakeLists.txt          |  1 +
 .../kernel-call-stmt-device-nyi.cpp           | 23 ++++++++++
 .../test/CIR/CodeGenSYCL/kernel-call-stmt.cpp | 45 +++++++++++++++++++
 7 files changed, 133 insertions(+), 1 deletion(-)
 create mode 100644 clang/lib/CIR/CodeGen/CIRGenSYCL.cpp
 create mode 100644 clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp
 create mode 100644 clang/test/CIR/CodeGenSYCL/kernel-call-stmt.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h 
b/clang/lib/CIR/CodeGen/CIRGenFunction.h
index 4ba3ee59f49b0..5c0fac6f0330c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.h
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h
@@ -48,6 +48,10 @@ class LoopOp;
 } // namespace acc
 } // namespace mlir
 
+namespace clang {
+class SYCLKernelCallStmt;
+} // namespace clang
+
 namespace clang::CIRGen {
 
 struct CGCoroData;
@@ -2267,6 +2271,8 @@ class CIRGenFunction : public CIRGenTypeCache {
                                      bool buildingTopLevelCase);
   mlir::LogicalResult emitSwitchStmt(const clang::SwitchStmt &s);
 
+  mlir::LogicalResult emitSYCLKernelCallStmt(const SYCLKernelCallStmt &s);
+
   std::optional<mlir::Value>
   emitTargetBuiltinExpr(unsigned builtinID, const clang::CallExpr *e,
                         ReturnValueSlot &returnValue);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index a7143408c9bee..b475b17cd4816 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -432,6 +432,26 @@ void CIRGenModule::emitDeferred() {
   curDeclsToEmit.swap(deferredDeclsToEmit);
 
   for (const GlobalDecl &d : curDeclsToEmit) {
+    // Functions declared with the sycl_kernel_entry_point attribute are
+    // emitted normally during host compilation. During device compilation, 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()) {
+        // Functions with an invalid sycl_kernel_entry_point attribute are
+        // ignored during device compilation.
+        if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
+          // Generating the SYCL kernel caller offload entry point is not yet
+          // implemented in CIR.
+          errorNYI(fd->getSourceRange(),
+                   "SYCL kernel caller offload entry point");
+        }
+        // Do not emit the sycl_kernel_entry_point attributed function.
+        continue;
+      }
+    }
+
     emitGlobalDecl(d);
 
     // If we found out that we need to emit more decls, do that recursively.
diff --git a/clang/lib/CIR/CodeGen/CIRGenSYCL.cpp 
b/clang/lib/CIR/CodeGen/CIRGenSYCL.cpp
new file mode 100644
index 0000000000000..9308b1fe4189f
--- /dev/null
+++ b/clang/lib/CIR/CodeGen/CIRGenSYCL.cpp
@@ -0,0 +1,35 @@
+//===--------- CIRGenSYCL.cpp - Emit CIR for SYCL kernels 
-----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This contains code required for the generation of SYCL kernel code.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIRGenFunction.h"
+
+#include "clang/AST/StmtSYCL.h"
+
+using namespace clang;
+using namespace clang::CIRGen;
+
+mlir::LogicalResult
+CIRGenFunction::emitSYCLKernelCallStmt(const SYCLKernelCallStmt &s) {
+  // SYCLKernelCallStmt nodes are only present in the bodies of functions
+  // declared with the sycl_kernel_entry_point attribute. ODR-use of such a
+  // function in code emitted during device compilation should be diagnosed.
+  // During device compilation, the offload kernel entry point is emitted in
+  // place of such a function (see CIRGenModule::emitDeferred), so this
+  // function is only reached during host compilation.
+  assert(!getLangOpts().SYCLIsDevice &&
+         "Attempt to emit a SYCL kernel call statement during device "
+         "compilation");
+
+  // During host compilation, the kernel launch statement is emitted in place
+  // of the original function body.
+  return emitStmt(s.getKernelLaunchStmt(), /*useCurrentScope=*/true);
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp 
b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
index d34769200dbfd..8e4c5f008c5a0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenStmt.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtOpenACC.h"
 #include "clang/AST/StmtOpenMP.h"
+#include "clang/AST/StmtSYCL.h"
 #include "clang/CIR/MissingFeatures.h"
 #include "llvm/Support/SaveAndRestore.h"
 
@@ -210,6 +211,8 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
     return emitIndirectGotoStmt(cast<IndirectGotoStmt>(*s));
   case Stmt::CoreturnStmtClass:
     return emitCoreturnStmt(cast<CoreturnStmt>(*s));
+  case Stmt::SYCLKernelCallStmtClass:
+    return emitSYCLKernelCallStmt(cast<SYCLKernelCallStmt>(*s));
   case Stmt::OpenACCComputeConstructClass:
     return emitOpenACCComputeConstruct(cast<OpenACCComputeConstruct>(*s));
   case Stmt::OpenACCLoopConstructClass:
@@ -431,7 +434,6 @@ mlir::LogicalResult CIRGenFunction::emitStmt(const Stmt *s,
   case Stmt::DefaultStmtClass:
   case Stmt::CaseStmtClass:
   case Stmt::SEHLeaveStmtClass:
-  case Stmt::SYCLKernelCallStmtClass:
   case Stmt::ObjCAtTryStmtClass:
   case Stmt::ObjCAtThrowStmtClass:
   case Stmt::ObjCAtSynchronizedStmtClass:
diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt 
b/clang/lib/CIR/CodeGen/CMakeLists.txt
index 78569b11651e0..1fe9b25dd786c 100644
--- a/clang/lib/CIR/CodeGen/CMakeLists.txt
+++ b/clang/lib/CIR/CodeGen/CMakeLists.txt
@@ -52,6 +52,7 @@ add_clang_library(clangCIR
   CIRGenStmtOpenACC.cpp
   CIRGenStmtOpenACCLoop.cpp
   CIRGenStmtOpenMP.cpp
+  CIRGenSYCL.cpp
   CIRGenTypes.cpp
   CIRGenVTables.cpp
   TargetInfo.cpp
diff --git a/clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp 
b/clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp
new file mode 100644
index 0000000000000..c6522064f2fdc
--- /dev/null
+++ b/clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++20 -fsycl-is-device -triple spir64-unknown-unknown \
+// RUN:   -fclangir -emit-cir -verify %s
+
+// During device compilation, a SYCL kernel caller offload entry point is
+// emitted in place of each sycl_kernel_entry_point attributed function. That
+// lowering is not yet implemented in CIR, so it must be reported as a clean
+// "Not Yet Implemented" diagnostic rather than crashing.
+
+// Required by sycl_kernel_entry_point semantics.
+template <typename KernelName, typename... Ts>
+void sycl_kernel_launch(const char *, Ts...) {}
+
+template <typename KernelName, typename KernelType>
+[[clang::sycl_kernel_entry_point(KernelName)]]
+// expected-error@+1 {{ClangIR code gen Not Yet Implemented: SYCL kernel 
caller offload entry point}}
+void kernel_single_task(KernelType kf) { kf(); }
+
+struct KN;
+struct K {
+  void operator()() const {}
+};
+
+void test() { kernel_single_task<KN>(K{}); }
diff --git a/clang/test/CIR/CodeGenSYCL/kernel-call-stmt.cpp 
b/clang/test/CIR/CodeGenSYCL/kernel-call-stmt.cpp
new file mode 100644
index 0000000000000..3f42bad95dc14
--- /dev/null
+++ b/clang/test/CIR/CodeGenSYCL/kernel-call-stmt.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++20 -fsycl-is-host -triple x86_64-unknown-linux-gnu 
-fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -fsycl-is-host -triple x86_64-unknown-linux-gnu 
-fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -fsycl-is-host -triple x86_64-unknown-linux-gnu 
-emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// Verify that, during host compilation, the body of a function declared with
+// the sycl_kernel_entry_point attribute is lowered to its kernel launch
+// statement rather than reporting a not-yet-implemented error. The kernel
+// entry point body must be replaced by the launch call; the original kernel
+// functor invocation must not be emitted on the host.
+
+// Required by sycl_kernel_entry_point semantics.
+template <typename KernelName, typename... Ts>
+void sycl_kernel_launch(const char *, Ts...) {}
+
+template <typename KernelName, typename KernelType>
+[[clang::sycl_kernel_entry_point(KernelName)]]
+void kernel_single_task(KernelType kf) { kf(); }
+
+struct KN;
+struct K {
+  void operator()() const {}
+};
+
+void test() { kernel_single_task<KN>(K{}); }
+
+// The kernel entry point body is replaced by a call to the sycl_kernel_launch
+// specialization, and does not invoke the kernel functor's operator() on the
+// host.
+// CIR-LABEL: cir.func {{.*}}@_Z18kernel_single_taskI2KN1KEvT0_
+// CIR-NOT:     cir.call @_ZNK1KclEv
+// CIR:         cir.call @_Z18sycl_kernel_launchI2KNJ1KEEvPKcDpT0_
+// CIR:         cir.return
+
+// LLVM-LABEL: define {{.*}}void @_Z18kernel_single_taskI2KN1KEvT0_
+// LLVM-NOT:     call {{.*}}@_ZNK1KclEv
+// LLVM:         call void @_Z18sycl_kernel_launchI2KNJ1KEEvPKcDpT0_
+// LLVM:         ret void
+
+// OGCG-LABEL: define {{.*}}void @_Z18kernel_single_taskI2KN1KEvT0_
+// OGCG-NOT:     call {{.*}}@_ZNK1KclEv
+// OGCG:         call void @_Z18sycl_kernel_launchI2KNJ1KEEvPKcDpT0_
+// OGCG:         ret void

>From 891b22888d7cec2cb1b4e63c015986b5ab73f08d Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <[email protected]>
Date: Mon, 3 Aug 2026 10:48:08 -0700
Subject: [PATCH 2/3] Rename file to align with OG SYCL

---
 ...call-stmt-device-nyi.cpp => kernel-caller-entry-point-nyi.cpp} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename clang/test/CIR/CodeGenSYCL/{kernel-call-stmt-device-nyi.cpp => 
kernel-caller-entry-point-nyi.cpp} (100%)

diff --git a/clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp 
b/clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point-nyi.cpp
similarity index 100%
rename from clang/test/CIR/CodeGenSYCL/kernel-call-stmt-device-nyi.cpp
rename to clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point-nyi.cpp

>From 8d53d076f0ff0312308082460ff77227d33f7e12 Mon Sep 17 00:00:00 2001
From: Konstantinos Parasyris <[email protected]>
Date: Wed, 5 Aug 2026 16:45:48 -0700
Subject: [PATCH 3/3] Address comments

---
 clang/lib/CIR/CodeGen/CIRGenModule.cpp                       | 5 +----
 ...ler-entry-point-nyi.cpp => kernel-caller-entry-point.cpp} | 0
 2 files changed, 1 insertion(+), 4 deletions(-)
 rename clang/test/CIR/CodeGenSYCL/{kernel-caller-entry-point-nyi.cpp => 
kernel-caller-entry-point.cpp} (100%)

diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index b475b17cd4816..fa1bdd267fc8f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -441,12 +441,9 @@ void CIRGenModule::emitDeferred() {
           fd->isDefined()) {
         // Functions with an invalid sycl_kernel_entry_point attribute are
         // ignored during device compilation.
-        if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr()) {
-          // Generating the SYCL kernel caller offload entry point is not yet
-          // implemented in CIR.
+        if (!fd->getAttr<SYCLKernelEntryPointAttr>()->isInvalidAttr())
           errorNYI(fd->getSourceRange(),
                    "SYCL kernel caller offload entry point");
-        }
         // Do not emit the sycl_kernel_entry_point attributed function.
         continue;
       }
diff --git a/clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point-nyi.cpp 
b/clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point.cpp
similarity index 100%
rename from clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point-nyi.cpp
rename to clang/test/CIR/CodeGenSYCL/kernel-caller-entry-point.cpp

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to