[clang] [CIR] Narrow blanket -fopenmp NYI guards to OGCG conditions (PR #233671)
Arseniy Obolenskiy via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 20 21:24:57 PDT 2026
https://github.com/aobolensk updated https://github.com/llvm/llvm-project/pull/233671
>From 19f43db687f175908974776191dc36e19d9d8990 Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Tue, 20 Oct 2026 06:34:44 +0200
Subject: [PATCH 1/2] [CIR] Narrow blanket -fopenmp NYI guards to OGCG
conditions
Ordinary code compiled with -fopenmp hit errorNYI on every assignment, inc/dec, member access and global reference
---
clang/include/clang/CIR/MissingFeatures.h | 2 +
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 22 +++--
clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 6 +-
clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 6 +-
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 11 +--
clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp | 33 ++++++++
clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h | 6 ++
.../CIR/CodeGenOpenMP/non-openmp-code.cpp | 80 +++++++++++++++++++
8 files changed, 146 insertions(+), 20 deletions(-)
create mode 100644 clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h
index 0ff6c6d44d1916..0a3c594e1a8bfb 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -274,6 +274,8 @@ struct MissingFeatures {
static bool msvcBuiltins() { return false; }
static bool openCL() { return false; }
static bool openMP() { return false; }
+ static bool openMPLastprivateConditional() { return false; }
+ static bool openMPNontemporalDecl() { return false; }
static bool sycl() { return false; }
static bool opTBAA() { return false; }
static bool peepholeProtection() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 9072a22cef52bd..b790e2e73cdfda 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -463,8 +463,17 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
// Check if the variable is marked as declare target with link clause in
// device codegen.
- if (cgf.getLangOpts().OpenMP)
- cgf.cgm.errorNYI(e->getSourceRange(), "emitGlobalVarDeclLValue: OpenMP");
+ if (cgf.getLangOpts().OpenMPIsTargetDevice) {
+ std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> res =
+ OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(vd);
+ if (res && (*res == OMPDeclareTargetDeclAttr::MT_Link ||
+ ((*res == OMPDeclareTargetDeclAttr::MT_To ||
+ *res == OMPDeclareTargetDeclAttr::MT_Enter) &&
+ cgf.cgm.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())))
+ cgf.cgm.errorNYI(e->getSourceRange(),
+ "emitGlobalVarDeclLValue: OpenMP declare target "
+ "indirect access");
+ }
// Traditional LLVM codegen handles thread local separately, CIR handles
// as part of getAddrOfGlobalVar.
@@ -1906,7 +1915,9 @@ LValue CIRGenFunction::emitMemberExpr(const MemberExpr *e) {
// If the member was explicitly marked as nontemporal, mark it as
// nontemporal. If the base lvalue is marked as nontemporal, mark access
// to children as nontemporal too.
- cgm.errorNYI(e->getSourceRange(), "emitMemberExpr: OpenMP");
+ assert(!cir::MissingFeatures::openMPNontemporalDecl());
+ if (baseLV.isNontemporal())
+ lv.setNontemporal(true);
}
return lv;
}
@@ -2272,10 +2283,7 @@ LValue CIRGenFunction::emitBinaryOperatorLValue(const BinaryOperator *e) {
else
emitStoreThroughLValue(rv, lv);
- if (getLangOpts().OpenMP) {
- cgm.errorNYI(e->getSourceRange(), "openmp");
- return {};
- }
+ assert(!cir::MissingFeatures::openMPLastprivateConditional());
return lv;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 7dd24a6d076e81..a17c3c340a417a 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -1086,8 +1086,7 @@ LValue CIRGenFunction::emitComplexAssignmentLValue(const BinaryOperator *e) {
mlir::Value value; // ignored
LValue lvalue = ComplexExprEmitter(*this).emitBinAssignLValue(e, value);
- if (getLangOpts().OpenMP)
- cgm.errorNYI("emitComplexAssignmentLValue OpenMP");
+ assert(!cir::MissingFeatures::openMPLastprivateConditional());
return lvalue;
}
@@ -1143,8 +1142,7 @@ mlir::Value CIRGenFunction::emitComplexPrePostIncDec(const UnaryOperator *e,
// Store the updated result through the lvalue.
emitStoreOfComplex(loc, incVal, lv, /*isInit=*/false);
- if (getLangOpts().OpenMP)
- cgm.errorNYI(loc, "emitComplexPrePostIncDec OpenMP");
+ assert(!cir::MissingFeatures::openMPLastprivateConditional());
// If this is a postinc, return the value read from memory, otherwise use the
// updated value.
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 2082963025238c..7173feda7759fc 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -627,8 +627,7 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> {
mlir::Value emitFixedPointIncDec(const UnaryOperator *e, mlir::Value value,
QualType type);
mlir::Value emitScalarPrePostIncDec(const UnaryOperator *e, LValue lv) {
- if (cgf.getLangOpts().OpenMP)
- cgf.cgm.errorNYI(e->getSourceRange(), "inc/dec OpenMP");
+ assert(!cir::MissingFeatures::openMPLastprivateConditional());
QualType type = e->getSubExpr()->getType();
@@ -1731,8 +1730,7 @@ LValue ScalarExprEmitter::emitCompoundAssignLValue(
else
cgf.emitStoreThroughLValue(RValue::get(result), lhsLV);
- if (cgf.getLangOpts().OpenMP)
- cgf.cgm.errorNYI(e->getSourceRange(), "openmp");
+ assert(!cir::MissingFeatures::openMPLastprivateConditional());
return lhsLV;
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 614a731158e455..d1a748d86777f0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1023,8 +1023,8 @@ LangAS CIRGenModule::getGlobalVarAddressSpace(const VarDecl *d) {
return LangAS::cuda_device;
}
- if (langOpts.OpenMP)
- errorNYI("OpenMP global address space");
+ if (langOpts.OpenMP && d && d->hasAttr<OMPAllocateDeclAttr>())
+ errorNYI(d->getSourceRange(), "OpenMP global address space");
return getTargetCIRGenInfo().getGlobalVarAddressSpace(*this, d);
}
@@ -1253,7 +1253,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) ==
@@ -1329,8 +1331,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 93ec2248f76eb0..db747fa112ebc4 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,38 @@ 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");
+}
+
+bool CIRGenOpenMPRuntime::hasRequiresUnifiedSharedMemory() const {
+ // OGCG also sets this from '#pragma omp requires unified_shared_memory'.
+ assert(!cir::MissingFeatures::openMP());
+ return cgm.getLangOpts().OpenMPForceUSM;
+}
+
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 d22200512e4839..fb368e06c5b2ac 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
@@ -48,6 +48,12 @@ 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);
+
+ /// Return whether unified shared memory is required.
+ bool hasRequiresUnifiedSharedMemory() const;
+
/// 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/non-openmp-code.cpp b/clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
new file mode 100644
index 00000000000000..43a009073a76fa
--- /dev/null
+++ b/clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
@@ -0,0 +1,80 @@
+// 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-prefixes=LLVM,LLVMCIR
+// RUN: %clang_cc1 -fopenmp -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefixes=LLVM,OGCG
+
+// Ordinary code compiled with -fopenmp.
+
+int g;
+
+// CIR: cir.global external @g = #cir.int<0> : !s32i
+// LLVM: @g = global i32 0
+
+struct S {
+ int x;
+};
+
+void scalar_ops(S *s, int v) {
+ g = v;
+ g += v;
+ ++g;
+ s->x = g;
+}
+
+// CIR: cir.func{{.*}} @_Z10scalar_opsP1Si
+// 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: %[[G1_VAL:.*]] = cir.load{{.*}} %[[G1]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[ADD:.*]] = cir.add nsw %[[G1_VAL]], %{{.*}} : !s32i
+// CIR: cir.store{{.*}} %[[ADD]], %[[G1]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[G2:.*]] = cir.get_global @g : !cir.ptr<!s32i>
+// CIR: %[[G2_VAL:.*]] = cir.load{{.*}} %[[G2]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[INC:.*]] = cir.inc nsw %[[G2_VAL]] : !s32i
+// CIR: cir.store{{.*}} %[[INC]], %[[G2]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[X:.*]] = cir.get_member %{{.*}}[0] {name = "x"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i>
+// CIR: cir.store{{.*}} %{{.*}}, %[[X]] : !s32i, !cir.ptr<!s32i>
+
+// LLVM: define{{.*}} void @_Z10scalar_opsP1Si
+// LLVM: store i32 %{{.*}}, ptr @g
+// LLVM: %[[G1:.*]] = load i32, ptr @g
+// LLVM: %[[ADD:.*]] = add nsw i32 %[[G1]], %{{.*}}
+// LLVM: store i32 %[[ADD]], ptr @g
+// LLVM: %[[G2:.*]] = load i32, ptr @g
+// LLVM: %[[INC:.*]] = add nsw i32 %[[G2]], 1
+// LLVM: store i32 %[[INC]], ptr @g
+// LLVM: %[[X:.*]] = getelementptr inbounds nuw %struct.S, ptr %{{.*}}, i32 0, i32 0
+// LLVM: store i32 %{{.*}}, ptr %[[X]]
+
+void complex_ops(float _Complex *c, float _Complex v) {
+ *c = v;
+ ++*c;
+}
+
+// CIR: cir.func{{.*}} @_Z11complex_opsPCfS_
+// CIR: %[[V:.*]] = cir.load align(4) %{{.*}} : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[C_PTR:.*]] = cir.load deref{{.*}} %{{.*}} : !cir.ptr<!cir.ptr<!cir.complex<!cir.float>>>, !cir.ptr<!cir.complex<!cir.float>>
+// CIR: cir.store{{.*}} %[[V]], %[[C_PTR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[C_PTR2:.*]] = cir.load deref{{.*}} %{{.*}} : !cir.ptr<!cir.ptr<!cir.complex<!cir.float>>>, !cir.ptr<!cir.complex<!cir.float>>
+// CIR: %[[C:.*]] = cir.load{{.*}} %[[C_PTR2]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
+// CIR: %[[REAL:.*]] = cir.complex.real %[[C]] : !cir.complex<!cir.float> -> !cir.float
+// CIR: %[[IMAG:.*]] = cir.complex.imag %[[C]] : !cir.complex<!cir.float> -> !cir.float
+// CIR: %[[INC:.*]] = cir.fadd %[[REAL]], %{{.*}} : !cir.float
+// CIR: %[[RES:.*]] = cir.complex.create %[[INC]], %[[IMAG]] : !cir.float -> !cir.complex<!cir.float>
+// CIR: cir.store{{.*}} %[[RES]], %{{.*}} : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
+
+// LLVMCIR: define{{.*}} void @_Z11complex_opsPCfS_
+// LLVMCIR: store { float, float } %{{.*}}, ptr %{{.*}}
+// LLVMCIR: %[[REAL:.*]] = extractvalue { float, float } %{{.*}}, 0
+// LLVMCIR: %[[INC:.*]] = fadd float %[[REAL]], 1.000000e+00
+// LLVMCIR: store { float, float } %{{.*}}, ptr %{{.*}}
+
+// OGCG: define{{.*}} void @_Z11complex_opsPCfS_
+// OGCG: store float %{{.*}}, ptr %{{.*}}
+// OGCG: store float %{{.*}}, ptr %{{.*}}
+// OGCG: %[[REAL:.*]] = load float, ptr %{{.*}}
+// OGCG: %[[INC:.*]] = fadd float %[[REAL]], 1.000000e+00
>From 571a7ecd8395a6d4cfebd5960c3dc26968ff541f Mon Sep 17 00:00:00 2001
From: Arseniy Obolenskiy <arseniy.obolenskiy at amd.com>
Date: Wed, 21 Oct 2026 06:24:35 +0200
Subject: [PATCH 2/2] revert parts
---
clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 13 ++-----
clang/lib/CIR/CodeGen/CIRGenModule.cpp | 7 ++--
clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp | 33 -----------------
clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h | 6 ----
.../CIR/CodeGenOpenMP/non-openmp-code.cpp | 36 +++++++++----------
5 files changed, 21 insertions(+), 74 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index fc73e7bc58af7b..c9f2912a5cdf49 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -463,17 +463,8 @@ static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e,
// Check if the variable is marked as declare target with link clause in
// device codegen.
- if (cgf.getLangOpts().OpenMPIsTargetDevice) {
- std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> res =
- OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(vd);
- if (res && (*res == OMPDeclareTargetDeclAttr::MT_Link ||
- ((*res == OMPDeclareTargetDeclAttr::MT_To ||
- *res == OMPDeclareTargetDeclAttr::MT_Enter) &&
- cgf.cgm.getOpenMPRuntime().hasRequiresUnifiedSharedMemory())))
- cgf.cgm.errorNYI(e->getSourceRange(),
- "emitGlobalVarDeclLValue: OpenMP declare target "
- "indirect access");
- }
+ if (cgf.getLangOpts().OpenMP)
+ cgf.cgm.errorNYI(e->getSourceRange(), "emitGlobalVarDeclLValue: OpenMP");
// Traditional LLVM codegen handles thread local separately, CIR handles
// as part of getAddrOfGlobalVar.
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index d1a748d86777f0..4ef29f59331f78 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -1253,9 +1253,7 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
assert(!cir::MissingFeatures::opGlobalWeakRef());
assert(!cir::MissingFeatures::setDLLStorageClass());
-
- if (langOpts.OpenMP && !langOpts.OpenMPSimd && d)
- getOpenMPRuntime().registerTargetGlobalVariable(d);
+ assert(!cir::MissingFeatures::openMP());
if (entry.getSymType() == ty &&
cir::normalizeDefaultAddressSpace(entryCIRAS) ==
@@ -1331,7 +1329,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, mlir::Type ty,
// Handle things which are present even on external declarations.
if (d) {
if (langOpts.OpenMP && !langOpts.OpenMPSimd)
- getOpenMPRuntime().registerTargetGlobalVariable(d);
+ errorNYI(d->getSourceRange(),
+ "getOrCreateCIRGlobal: OpenMP target global variable");
gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
index db747fa112ebc4..93ec2248f76eb0 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp
@@ -16,7 +16,6 @@
#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;
@@ -173,38 +172,6 @@ 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");
-}
-
-bool CIRGenOpenMPRuntime::hasRequiresUnifiedSharedMemory() const {
- // OGCG also sets this from '#pragma omp requires unified_shared_memory'.
- assert(!cir::MissingFeatures::openMP());
- return cgm.getLangOpts().OpenMPForceUSM;
-}
-
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 fb368e06c5b2ac..d22200512e4839 100644
--- a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
+++ b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h
@@ -48,12 +48,6 @@ 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);
-
- /// Return whether unified shared memory is required.
- bool hasRequiresUnifiedSharedMemory() const;
-
/// 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/non-openmp-code.cpp b/clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
index 43a009073a76fa..d3f4e62b3d10dd 100644
--- a/clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
+++ b/clang/test/CIR/CodeGenOpenMP/non-openmp-code.cpp
@@ -9,44 +9,40 @@
// Ordinary code compiled with -fopenmp.
-int g;
-
-// CIR: cir.global external @g = #cir.int<0> : !s32i
-// LLVM: @g = global i32 0
-
struct S {
int x;
};
void scalar_ops(S *s, int v) {
+ static int g;
g = v;
g += v;
++g;
s->x = g;
}
+// CIR: cir.global "private" internal dso_local @[[G:_ZZ10scalar_opsP1SiE1g]] = #cir.int<0> : !s32i
// CIR: cir.func{{.*}} @_Z10scalar_opsP1Si
-// 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: %[[G1_VAL:.*]] = cir.load{{.*}} %[[G1]] : !cir.ptr<!s32i>, !s32i
-// CIR: %[[ADD:.*]] = cir.add nsw %[[G1_VAL]], %{{.*}} : !s32i
-// CIR: cir.store{{.*}} %[[ADD]], %[[G1]] : !s32i, !cir.ptr<!s32i>
-// CIR: %[[G2:.*]] = cir.get_global @g : !cir.ptr<!s32i>
-// CIR: %[[G2_VAL:.*]] = cir.load{{.*}} %[[G2]] : !cir.ptr<!s32i>, !s32i
-// CIR: %[[INC:.*]] = cir.inc nsw %[[G2_VAL]] : !s32i
-// CIR: cir.store{{.*}} %[[INC]], %[[G2]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[G_PTR:.*]] = cir.get_global @[[G]] : !cir.ptr<!s32i>
+// CIR: cir.store{{.*}} %{{.*}}, %[[G_PTR]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[G1:.*]] = cir.load{{.*}} %[[G_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[ADD:.*]] = cir.add nsw %[[G1]], %{{.*}} : !s32i
+// CIR: cir.store{{.*}} %[[ADD]], %[[G_PTR]] : !s32i, !cir.ptr<!s32i>
+// CIR: %[[G2:.*]] = cir.load{{.*}} %[[G_PTR]] : !cir.ptr<!s32i>, !s32i
+// CIR: %[[INC:.*]] = cir.inc nsw %[[G2]] : !s32i
+// CIR: cir.store{{.*}} %[[INC]], %[[G_PTR]] : !s32i, !cir.ptr<!s32i>
// CIR: %[[X:.*]] = cir.get_member %{{.*}}[0] {name = "x"} : !cir.ptr<!rec_S> -> !cir.ptr<!s32i>
// CIR: cir.store{{.*}} %{{.*}}, %[[X]] : !s32i, !cir.ptr<!s32i>
+// LLVM: @[[G:_ZZ10scalar_opsP1SiE1g]] = internal global i32 0
// LLVM: define{{.*}} void @_Z10scalar_opsP1Si
-// LLVM: store i32 %{{.*}}, ptr @g
-// LLVM: %[[G1:.*]] = load i32, ptr @g
+// LLVM: store i32 %{{.*}}, ptr @[[G]]
+// LLVM: %[[G1:.*]] = load i32, ptr @[[G]]
// LLVM: %[[ADD:.*]] = add nsw i32 %[[G1]], %{{.*}}
-// LLVM: store i32 %[[ADD]], ptr @g
-// LLVM: %[[G2:.*]] = load i32, ptr @g
+// LLVM: store i32 %[[ADD]], ptr @[[G]]
+// LLVM: %[[G2:.*]] = load i32, ptr @[[G]]
// LLVM: %[[INC:.*]] = add nsw i32 %[[G2]], 1
-// LLVM: store i32 %[[INC]], ptr @g
+// LLVM: store i32 %[[INC]], ptr @[[G]]
// LLVM: %[[X:.*]] = getelementptr inbounds nuw %struct.S, ptr %{{.*}}, i32 0, i32 0
// LLVM: store i32 %{{.*}}, ptr %[[X]]
More information about the cfe-commits
mailing list