[clang] [CIR][OpenMP] Enable emission of target functions (PR #193204)
Jan Leyonberg via cfe-commits
cfe-commits at lists.llvm.org
Tue Apr 21 05:07:58 PDT 2026
https://github.com/jsjodin created https://github.com/llvm/llvm-project/pull/193204
This PR allows generation of target device functions for OpenMP.
Assisted-by: Cursor / claude-4.6-opus-high
>From b818fc1de0e05f7ac1a138a937449a7cb6314876 Mon Sep 17 00:00:00 2001
From: Jan Leyonberg <jan_sjodin at yahoo.com>
Date: Tue, 21 Apr 2026 06:16:31 -0400
Subject: [PATCH] [CIR][OpenMP] Enable emission of target functions
This PR allows generation of target device functions for OpenMP.
Assisted-by: Cursor / claude-4.6-opus-high
---
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 16 ++++--
.../CodeGenOpenMP/emit-device-functions.cpp | 50 +++++++++++++++++++
2 files changed, 63 insertions(+), 3 deletions(-)
create mode 100644 clang/test/CIR/CodeGenOpenMP/emit-device-functions.cpp
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 2f64fe45a694d..fc34aae34a90b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -2820,9 +2820,19 @@ cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
if (const auto *fd = cast_or_null<FunctionDecl>(d)) {
// For the device mark the function as one that should be emitted.
if (getLangOpts().OpenMPIsTargetDevice && fd->isDefined() && !dontDefer &&
- !isForDefinition)
- errorNYI(fd->getSourceRange(),
- "getOrCreateCIRFunction: OpenMP target function");
+ !isForDefinition) {
+
+ if (const FunctionDecl *fdDef = fd->getDefinition()) {
+ GlobalDecl gdDef;
+ if (const auto *cd = dyn_cast<CXXConstructorDecl>(fdDef))
+ gdDef = GlobalDecl(cd, gd.getCtorType());
+ else if (const auto *dd = dyn_cast<CXXDestructorDecl>(fdDef))
+ gdDef = GlobalDecl(dd, gd.getDtorType());
+ else
+ gdDef = GlobalDecl(fdDef);
+ emitGlobal(gdDef);
+ }
+ }
// Any attempts to use a MultiVersion function should result in retrieving
// the iFunc instead. Name mangling will handle the rest of the changes.
diff --git a/clang/test/CIR/CodeGenOpenMP/emit-device-functions.cpp b/clang/test/CIR/CodeGenOpenMP/emit-device-functions.cpp
new file mode 100644
index 0000000000000..940225de9e8c4
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenMP/emit-device-functions.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-target-device \
+// RUN: -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-target-device \
+// RUN: -fclangir -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fopenmp -fopenmp-is-target-device \
+// RUN: -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+// Test that functions referenced from a device context are emitted:
+// regular functions, constructors, and destructors.
+
+#pragma omp declare target
+
+void regular_func() {}
+
+struct S {
+ int x;
+ S() : x(42) {}
+ ~S() {}
+};
+
+void caller() {
+ regular_func();
+ S s;
+}
+
+#pragma omp end declare target
+
+// CIR-DAG: cir.func {{.*}} @_Z12regular_funcv()
+// CIR-DAG: cir.func {{.*}} @_ZN1SC2Ev({{.*}}) special_member<#cir.cxx_ctor<!rec_S, default>>
+// CIR-DAG: cir.func {{.*}} @_ZN1SC1Ev({{.*}}) special_member<#cir.cxx_ctor<!rec_S, default>>
+// CIR-DAG: cir.func {{.*}} @_ZN1SD2Ev({{.*}}) special_member<#cir.cxx_dtor<!rec_S>>
+// CIR-DAG: cir.func {{.*}} @_ZN1SD1Ev({{.*}}) special_member<#cir.cxx_dtor<!rec_S>>
+// CIR-DAG: cir.func {{.*}} @_Z6callerv()
+
+// LLVM-DAG: define {{.*}} void @_Z12regular_funcv()
+// LLVM-DAG: define {{.*}} void @_ZN1SC2Ev(
+// LLVM-DAG: define {{.*}} void @_ZN1SC1Ev(
+// LLVM-DAG: define {{.*}} void @_ZN1SD2Ev(
+// LLVM-DAG: define {{.*}} void @_ZN1SD1Ev(
+// LLVM-DAG: define {{.*}} void @_Z6callerv()
+
+// OGCG-DAG: define {{.*}} void @_Z12regular_funcv()
+// OGCG-DAG: define {{.*}} void @_ZN1SC2Ev(
+// OGCG-DAG: define {{.*}} void @_ZN1SC1Ev(
+// OGCG-DAG: define {{.*}} void @_ZN1SD2Ev(
+// OGCG-DAG: define {{.*}} void @_ZN1SD1Ev(
+// OGCG-DAG: define {{.*}} void @_Z6callerv()
More information about the cfe-commits
mailing list