https://github.com/aobolensk created 
https://github.com/llvm/llvm-project/pull/234077

Limit the NYI to declare target variables so other globals emit under -fopenmp

>From cba896e0d0c3f4c6b10628a93e7a4575054d2d3b Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <[email protected]>
Date: Wed, 21 Oct 2026 06:59:54 +0200
Subject: [PATCH] [CIR][OpenMP] Add registerTargetGlobalVariable for global
 variables

Limit the NYI to declare target variables so other globals emit under -fopenmp, 
as OGCG does
---
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  7 ++--
 clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp | 27 +++++++++++++
 clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h   |  3 ++
 clang/test/CIR/CodeGenOpenMP/global-var.cpp   | 40 +++++++++++++++++++
 4 files changed, 74 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/CIR/CodeGenOpenMP/global-var.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 6142ee62f3be1..a0940447274f0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1260,7 +1260,9 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, 
mlir::Type ty,
     assert(!cir::MissingFeatures::opGlobalWeakRef());
 
     assert(!cir::MissingFeatures::setDLLStorageClass());
-    assert(!cir::MissingFeatures::openMP());
+
+    if (langOpts.OpenMP && !langOpts.OpenMPSimd && d)
+      getOpenMPRuntime().registerTargetGlobalVariable(d);
 
     if (entry.getSymType() == ty &&
         cir::normalizeDefaultAddressSpace(entryCIRAS) ==
@@ -1336,8 +1338,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, 
mlir::Type ty,
   // Handle things which are present even on external declarations.
   if (d) {
     if (langOpts.OpenMP && !langOpts.OpenMPSimd)
-      errorNYI(d->getSourceRange(),
-               "getOrCreateCIRGlobal: OpenMP target global variable");
+      getOpenMPRuntime().registerTargetGlobalVariable(d);
 
     gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp 
b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
index 93ec2248f76eb..ff03cde1ef127 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
@@ -16,6 +16,7 @@
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
 #include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
 #include "clang/AST/OpenMPClause.h"
+#include "clang/CIR/MissingFeatures.h"
 
 using namespace clang;
 using namespace clang::CIRGen;
@@ -172,6 +173,32 @@ bool CIRGenOpenMPRuntime::markAsGlobalTarget(GlobalDecl 
gd) {
   return !alreadyEmittedTargetDecls.insert(d).second;
 }
 
+// Mirrors CGOpenMPRuntime::registerTargetGlobalVariable.
+void CIRGenOpenMPRuntime::registerTargetGlobalVariable(const VarDecl *vd) {
+  if (cgm.getLangOpts().OMPTargetTriples.empty() &&
+      !cgm.getLangOpts().OpenMPIsTargetDevice)
+    return;
+
+  std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> res =
+      OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(vd);
+
+  if (res && *res != OMPDeclareTargetDeclAttr::MT_Link &&
+      vd->hasExternalStorage())
+    return;
+
+  if (res && *res == OMPDeclareTargetDeclAttr::MT_Local)
+    return;
+
+  if (!res) {
+    // OGCG records non-target variables emitted in device code.
+    assert(!cir::MissingFeatures::openMP());
+    return;
+  }
+
+  cgm.errorNYI(vd->getSourceRange(),
+               "registerTargetGlobalVariable: declare target variable");
+}
+
 void CIRGenOpenMPRuntime::emitDeclareTargetFunction(const FunctionDecl *fd,
                                                     cir::FuncOp funcOp) {
   const auto *attr = fd->getAttr<OMPDeclareTargetDeclAttr>();
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h 
b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
index d22200512e483..4103449421056 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
@@ -48,6 +48,9 @@ class CIRGenOpenMPRuntime {
   /// handled and should be skipped.
   bool markAsGlobalTarget(GlobalDecl gd);
 
+  /// Register a global variable that may need an offload entry.
+  void registerTargetGlobalVariable(const VarDecl *vd);
+
   /// If the function has an OMPDeclareTargetDeclAttr, set the corresponding
   /// omp.declare_target attribute on the emitted cir.func op.
   void emitDeclareTargetFunction(const FunctionDecl *fd, cir::FuncOp funcOp);
diff --git a/clang/test/CIR/CodeGenOpenMP/global-var.cpp 
b/clang/test/CIR/CodeGenOpenMP/global-var.cpp
new file mode 100644
index 0000000000000..8945e21b35ce5
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenMP/global-var.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fopenmp -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 -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -triple 
x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t-offload.cir
+// RUN: FileCheck --input-file=%t-offload.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -fopenmp -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 -fopenmp -triple x86_64-unknown-linux-gnu -emit-llvm %s -o 
%t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM
+
+int g;
+extern int e;
+int *use_e = &e;
+
+// CIR: cir.global external @g = #cir.int<0> : !s32i
+// CIR: cir.global external @use_e = #cir.global_view<@e> : !cir.ptr<!s32i>
+// CIR: cir.global "private" external @e : !s32i
+
+// LLVM: @g = global i32 0
+// LLVM: @use_e = global ptr @e
+// LLVM: @e = external global i32
+
+int global_ref(int v) {
+  g = v;
+  return g + e;
+}
+
+// CIR: cir.func{{.*}} @_Z10global_refi
+// CIR:   %[[G:.*]] = cir.get_global @g : !cir.ptr<!s32i>
+// CIR:   cir.store{{.*}} %{{.*}}, %[[G]] : !s32i, !cir.ptr<!s32i>
+// CIR:   %[[G1:.*]] = cir.get_global @g : !cir.ptr<!s32i>
+// CIR:   %[[G_VAL:.*]] = cir.load{{.*}} %[[G1]] : !cir.ptr<!s32i>, !s32i
+// CIR:   %[[E:.*]] = cir.get_global @e : !cir.ptr<!s32i>
+// CIR:   %[[E_VAL:.*]] = cir.load{{.*}} %[[E]] : !cir.ptr<!s32i>, !s32i
+// CIR:   %{{.*}} = cir.add nsw %[[G_VAL]], %[[E_VAL]] : !s32i
+
+// LLVM: define{{.*}} i32 @_Z10global_refi
+// LLVM:   store i32 %{{.*}}, ptr @g
+// LLVM:   %[[G:.*]] = load i32, ptr @g
+// LLVM:   %[[E:.*]] = load i32, ptr @e
+// LLVM:   %{{.*}} = add nsw i32 %[[G]], %[[E]]

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

Reply via email to