Author: Arseniy Obolenskiy Date: 2026-11-03T15:50:50+01:00 New Revision: 460413ffe35a0fec18fd772586e6f4a1ab9f3ff1
URL: https://github.com/llvm/llvm-project/commit/460413ffe35a0fec18fd772586e6f4a1ab9f3ff1 DIFF: https://github.com/llvm/llvm-project/commit/460413ffe35a0fec18fd772586e6f4a1ab9f3ff1.diff LOG: [CIR][OpenMP] Add emitDeclTargetVarDeclLValue for global variable access (#234075) Limit the global access NYI to declare target variables that need indirect access on the device --------- Co-authored-by: Steffen Larsen <[email protected]> Added: clang/test/CIR/CodeGenOpenMP/simd-global-var.cpp Modified: clang/include/clang/CIR/MissingFeatures.h clang/lib/CIR/CodeGen/CIRGenExpr.cpp clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.h Removed: ################################################################################ diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 1348206f1738ad..323cf2423c354c 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -273,6 +273,7 @@ struct MissingFeatures { static bool openMP() { return false; } static bool openMPLastprivateConditional() { return false; } static bool openMPNontemporalDecl() { return false; } + static bool openMPRequiresUnifiedSharedMemory() { 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 78b07072b34145..ee842ae0d195cb 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -453,6 +453,26 @@ void CIRGenFunction::emitStoreThroughLValue(RValue src, LValue dst, emitStoreOfScalar(src.getValue(), dst, isInit); } +static std::optional<LValue> emitDeclTargetVarDeclLValue(CIRGenFunction &cgf, + const Expr *e, + const VarDecl *vd) { + std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> res = + OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(vd); + if (!res) + return std::nullopt; + // MT_Local uses direct access. + if (*res == OMPDeclareTargetDeclAttr::MT_Local) + return std::nullopt; + // MT_To/MT_Enter without unified memory use direct access. + if ((*res == OMPDeclareTargetDeclAttr::MT_To || + *res == OMPDeclareTargetDeclAttr::MT_Enter) && + !cgf.cgm.getOpenMPRuntime().hasRequiresUnifiedSharedMemory()) + return std::nullopt; + cgf.cgm.errorNYI(e->getSourceRange(), + "emitDeclTargetVarDeclLValue: indirect access"); + return std::nullopt; +} + static LValue emitGlobalVarDeclLValue(CIRGenFunction &cgf, const Expr *e, const VarDecl *vd) { QualType t = e->getType(); @@ -463,8 +483,9 @@ 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) + if (std::optional<LValue> lv = emitDeclTargetVarDeclLValue(cgf, e, vd)) + return *lv; // Traditional LLVM codegen handles thread local separately, CIR handles // as part of getAddrOfGlobalVar. diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenMPRuntime.cpp index 93ec2248f76eb0..d3e99488a6da8b 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,12 @@ bool CIRGenOpenMPRuntime::markAsGlobalTarget(GlobalDecl gd) { return !alreadyEmittedTargetDecls.insert(d).second; } +bool CIRGenOpenMPRuntime::hasRequiresUnifiedSharedMemory() const { + // OGCG also sets this from '#pragma omp requires unified_shared_memory'. + assert(!cir::MissingFeatures::openMPRequiresUnifiedSharedMemory()); + 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..b57537defbfbd0 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); + /// 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/simd-global-var.cpp b/clang/test/CIR/CodeGenOpenMP/simd-global-var.cpp new file mode 100644 index 00000000000000..3b56fc45493469 --- /dev/null +++ b/clang/test/CIR/CodeGenOpenMP/simd-global-var.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -fopenmp-simd -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-simd -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-simd -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM + +int g; + +// CIR: cir.global external @g = #cir.int<0> : !s32i +// LLVM: @g = global i32 0 + +int global_ref(int v) { + g = v; + return g; +} + +// 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: %{{.*}} = cir.load{{.*}} %[[G1]] : !cir.ptr<!s32i>, !s32i + +// LLVM: define{{.*}} i32 @_Z10global_refi +// LLVM: store i32 %{{.*}}, ptr @g +// LLVM: %{{.*}} = load i32, ptr @g _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
