[llvm-branch-commits] [mlir] [MLIR][OpenMP] Unify device shared memory logic (PR #182856)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Feb 23 06:45:04 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-mlir-llvm

Author: Sergio Afonso (skatrak)

<details>
<summary>Changes</summary>

This patch creates a utils library for the OpenMP dialect with functions used by MLIR to LLVM IR translation as well as the stack-to-shared pass to determine which allocations must use local stack memory or device shared memory.

---

Patch is 20.93 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/182856.diff


8 Files Affected:

- (added) mlir/include/mlir/Dialect/OpenMP/Utils/Utils.h (+53) 
- (modified) mlir/lib/Dialect/OpenMP/CMakeLists.txt (+1) 
- (modified) mlir/lib/Dialect/OpenMP/Transforms/CMakeLists.txt (+1) 
- (modified) mlir/lib/Dialect/OpenMP/Transforms/StackToShared.cpp (+13-85) 
- (added) mlir/lib/Dialect/OpenMP/Utils/CMakeLists.txt (+13) 
- (added) mlir/lib/Dialect/OpenMP/Utils/Utils.cpp (+104) 
- (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/CMakeLists.txt (+1) 
- (modified) mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp (+10-93) 


``````````diff
diff --git a/mlir/include/mlir/Dialect/OpenMP/Utils/Utils.h b/mlir/include/mlir/Dialect/OpenMP/Utils/Utils.h
new file mode 100644
index 0000000000000..ce625c7170efe
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenMP/Utils/Utils.h
@@ -0,0 +1,53 @@
+//===- Utils.h - OpenMP dialect utilities -----------------------*- C++ -*-===//
+//
+// 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 header file defines prototypes for various OpenMP utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENMP_UTILS_UTILS_H_
+#define MLIR_DIALECT_OPENMP_UTILS_UTILS_H_
+
+#include "mlir/IR/Operation.h"
+#include "mlir/IR/Value.h"
+
+namespace mlir {
+namespace omp {
+
+/// Check whether the value representing an allocation, assumed to have been
+/// defined in a shared device context, is used in a manner that would require
+/// device shared memory for correctness.
+///
+/// When a use takes place inside an omp.parallel region and it's not as a
+/// private clause argument, or when it is a reduction argument passed to
+/// omp.parallel or a function call argument, then the defining allocation is
+/// eligible for replacement with shared memory.
+///
+/// \see mlir::omp::opInSharedDeviceContext().
+bool allocaUsesRequireSharedMem(Value alloc);
+
+/// Check whether the given operation is located in a context where an
+/// allocation to be used by multiple threads in a parallel region would have to
+/// be placed in device shared memory to be accessible.
+///
+/// That means that it is inside of a target device module, it is a non-SPMD
+/// target region, is inside of one or it's located in a device function, and it
+/// is not not inside of a parallel region.
+///
+/// This represents a necessary but not sufficient set of conditions to use
+/// device shared memory in place of regular allocas. For some variables, the
+/// associated OpenMP construct or their uses might also need to be taken into
+/// account.
+///
+/// \see mlir::omp::allocaUsesRequireSharedMem().
+bool opInSharedDeviceContext(Operation &op);
+
+} // namespace omp
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENMP_UTILS_UTILS_H_
diff --git a/mlir/lib/Dialect/OpenMP/CMakeLists.txt b/mlir/lib/Dialect/OpenMP/CMakeLists.txt
index 9f57627c321fb..31167e6af908b 100644
--- a/mlir/lib/Dialect/OpenMP/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenMP/CMakeLists.txt
@@ -1,2 +1,3 @@
 add_subdirectory(IR)
 add_subdirectory(Transforms)
+add_subdirectory(Utils)
diff --git a/mlir/lib/Dialect/OpenMP/Transforms/CMakeLists.txt b/mlir/lib/Dialect/OpenMP/Transforms/CMakeLists.txt
index b00ca178dd9df..fa723239299a2 100644
--- a/mlir/lib/Dialect/OpenMP/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenMP/Transforms/CMakeLists.txt
@@ -18,6 +18,7 @@ add_mlir_dialect_library(MLIROpenMPTransforms
   MLIRLLVMDialect
   MLIROpenACCMPCommon
   MLIROpenMPDialect
+  MLIROpenMPUtils
   MLIRPass
   MLIRSupport
   MLIRTransforms
diff --git a/mlir/lib/Dialect/OpenMP/Transforms/StackToShared.cpp b/mlir/lib/Dialect/OpenMP/Transforms/StackToShared.cpp
index 0edccf53a2031..6b54f9c14013c 100644
--- a/mlir/lib/Dialect/OpenMP/Transforms/StackToShared.cpp
+++ b/mlir/lib/Dialect/OpenMP/Transforms/StackToShared.cpp
@@ -15,7 +15,9 @@
 
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+#include "mlir/Dialect/OpenMP/Utils/Utils.h"
 #include "mlir/Pass/Pass.h"
+#include "llvm/ADT/STLExtras.h"
 
 namespace mlir {
 namespace omp {
@@ -26,94 +28,20 @@ namespace omp {
 
 using namespace mlir;
 
-/// When a use takes place inside an omp.parallel region and it's not as a
-/// private clause argument, or when it is a reduction argument passed to
-/// omp.parallel or a function call argument, then the defining allocation is
-/// eligible for replacement with shared memory.
-static bool allocaUseRequiresDeviceSharedMem(const OpOperand &use) {
-  Operation *owner = use.getOwner();
-  if (auto parallelOp = dyn_cast<omp::ParallelOp>(owner)) {
-    if (llvm::is_contained(parallelOp.getReductionVars(), use.get()))
-      return true;
-  } else if (auto callOp = dyn_cast<CallOpInterface>(owner)) {
-    if (llvm::is_contained(callOp.getArgOperands(), use.get()))
-      return true;
-  }
-
-  // If it is used directly inside of a parallel region, it has to be replaced
-  // unless the use is a private clause.
-  if (owner->getParentOfType<omp::ParallelOp>()) {
-    if (auto argIface = dyn_cast<omp::BlockArgOpenMPOpInterface>(owner)) {
-      if (auto privateSyms =
-              cast_or_null<ArrayAttr>(owner->getAttr("private_syms"))) {
-        for (auto [var, sym] :
-             llvm::zip_equal(argIface.getPrivateVars(), privateSyms)) {
-          if (var != use.get())
-            continue;
-
-          auto moduleOp = owner->getParentOfType<ModuleOp>();
-          auto privateOp = cast<omp::PrivateClauseOp>(
-              moduleOp.lookupSymbol(cast<SymbolRefAttr>(sym)));
-          return privateOp.getDataSharingType() !=
-                 omp::DataSharingClauseType::Private;
-        }
-      }
-    }
-    return true;
-  }
-  return false;
-}
-
-static bool shouldReplaceAllocaWithUses(const Operation::use_range &uses) {
-  // Check direct uses and also follow hlfir.declare/fir.convert uses.
-  for (const OpOperand &use : uses) {
-    Operation *owner = use.getOwner();
-    if (llvm::isa<LLVM::AddrSpaceCastOp, LLVM::GEPOp>(owner)) {
-      if (shouldReplaceAllocaWithUses(owner->getUses()))
-        return true;
-    } else if (allocaUseRequiresDeviceSharedMem(use)) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-// TODO: Refactor the logic in `shouldReplaceAllocaWithDeviceSharedMem`,
-// `shouldReplaceAllocaWithUses` and `allocaUseRequiresDeviceSharedMem` to
-// be reusable by the MLIR to LLVM IR translation stage, as something very
-// similar is also implemented there to choose between allocas and device
-// shared memory allocations when processing OpenMP reductions, mapping and
-// privatization.
+/// Tell whether to replace an operation representing a stack allocation with a
+/// device shared memory allocation/deallocation pair based on the location of
+/// the allocation and its uses.
 static bool shouldReplaceAllocaWithDeviceSharedMem(Operation &op) {
-  auto offloadIface = op.getParentOfType<omp::OffloadModuleInterface>();
-  if (!offloadIface || !offloadIface.getIsTargetDevice())
-    return false;
-
-  auto targetOp = op.getParentOfType<omp::TargetOp>();
-
-  // It must be inside of a generic omp.target or in a target device function,
-  // and not inside of omp.parallel.
-  if (auto parallelOp = op.getParentOfType<omp::ParallelOp>()) {
-    if (!targetOp || targetOp->isProperAncestor(parallelOp))
-      return false;
-  }
-
-  if (targetOp) {
-    if (targetOp.getKernelExecFlags(targetOp.getInnermostCapturedOmpOp()) !=
-        omp::TargetExecMode::generic)
-      return false;
-  } else {
-    auto declTargetIface = op.getParentOfType<omp::DeclareTargetInterface>();
-    if (!declTargetIface || !declTargetIface.isDeclareTarget() ||
-        declTargetIface.getDeclareTargetDeviceType() ==
-            omp::DeclareTargetDeviceType::host)
-      return false;
-  }
-
-  return shouldReplaceAllocaWithUses(op.getUses());
+  return omp::opInSharedDeviceContext(op) &&
+         llvm::any_of(op.getResults(), [&](Value result) {
+           return omp::allocaUsesRequireSharedMem(result);
+         });
 }
 
+/// Based on the location of the definition of the given value representing the
+/// result of a device shared memory allocation, find the corresponding points
+/// where its deallocation should be placed and introduce `omp.free_shared_mem`
+/// ops at those points.
 static void insertDeviceSharedMemDeallocation(OpBuilder &builder,
                                               TypeAttr elemType,
                                               Value arraySize,
diff --git a/mlir/lib/Dialect/OpenMP/Utils/CMakeLists.txt b/mlir/lib/Dialect/OpenMP/Utils/CMakeLists.txt
new file mode 100644
index 0000000000000..8fd8ba2622c68
--- /dev/null
+++ b/mlir/lib/Dialect/OpenMP/Utils/CMakeLists.txt
@@ -0,0 +1,13 @@
+add_mlir_dialect_library(MLIROpenMPUtils
+  Utils.cpp
+
+  ADDITIONAL_HEADER_DIRS
+  ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/OpenMP
+
+  LINK_LIBS PUBLIC
+  MLIRIR
+  MLIRLLVMDialect
+  MLIROpenACCMPCommon
+  MLIROpenMPDialect
+  MLIRSupport
+  )
diff --git a/mlir/lib/Dialect/OpenMP/Utils/Utils.cpp b/mlir/lib/Dialect/OpenMP/Utils/Utils.cpp
new file mode 100644
index 0000000000000..f5b7aa7ca2e2c
--- /dev/null
+++ b/mlir/lib/Dialect/OpenMP/Utils/Utils.cpp
@@ -0,0 +1,104 @@
+//===- StackToShared.cpp -------------------------------------------===//
+//
+// 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 file implements various OpenMP dialect utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenMP/Utils/Utils.h"
+
+#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+
+using namespace mlir;
+
+static bool allocaUseRequiresSharedMem(const OpOperand &use) {
+  Operation *owner = use.getOwner();
+  if (auto parallelOp = dyn_cast<omp::ParallelOp>(owner)) {
+    if (llvm::is_contained(parallelOp.getReductionVars(), use.get()))
+      return true;
+  } else if (auto callOp = dyn_cast<CallOpInterface>(owner)) {
+    if (llvm::is_contained(callOp.getArgOperands(), use.get()))
+      return true;
+  }
+
+  // If it is used directly inside of a parallel region, it has to be replaced
+  // unless the use is a private clause.
+  if (owner->getParentOfType<omp::ParallelOp>()) {
+    if (auto argIface = dyn_cast<omp::BlockArgOpenMPOpInterface>(owner)) {
+      if (auto privateSyms =
+              cast_or_null<ArrayAttr>(owner->getAttr("private_syms"))) {
+        for (auto [var, sym] :
+             llvm::zip_equal(argIface.getPrivateVars(), privateSyms)) {
+          if (var != use.get())
+            continue;
+
+          auto moduleOp = owner->getParentOfType<ModuleOp>();
+          auto privateOp = cast<omp::PrivateClauseOp>(
+              moduleOp.lookupSymbol(cast<SymbolRefAttr>(sym)));
+          return privateOp.getDataSharingType() !=
+                 omp::DataSharingClauseType::Private;
+        }
+      }
+    }
+    return true;
+  }
+  return false;
+}
+
+bool mlir::omp::allocaUsesRequireSharedMem(Value alloc) {
+  for (const OpOperand &use : alloc.getUses()) {
+    Operation *owner = use.getOwner();
+    if (isa<LLVM::AddrSpaceCastOp, LLVM::GEPOp>(owner)) {
+      if (llvm::any_of(owner->getResults(), [&](Value result) {
+            return allocaUsesRequireSharedMem(result);
+          }))
+        return true;
+    } else if (allocaUseRequiresSharedMem(use)) {
+      return true;
+    }
+  }
+  return false;
+}
+
+bool mlir::omp::opInSharedDeviceContext(Operation &op) {
+  if (isa<omp::ParallelOp>(op))
+    return false;
+
+  auto offloadIface = op.getParentOfType<omp::OffloadModuleInterface>();
+  if (!offloadIface || !offloadIface.getIsTargetDevice())
+    return false;
+
+  auto targetOp = op.getParentOfType<omp::TargetOp>();
+
+  // It must be inside of a generic omp.target or in a target device function,
+  // and not inside of omp.parallel.
+  if (auto parallelOp = op.getParentOfType<omp::ParallelOp>()) {
+    if (!targetOp || targetOp->isProperAncestor(parallelOp))
+      return false;
+  }
+
+  // The omp.target operation itself is considered in a shared device context in
+  // order to properly process its own allocation-defining entry block
+  // arguments.
+  if (!targetOp)
+    targetOp = dyn_cast<omp::TargetOp>(op);
+
+  if (targetOp) {
+    if (targetOp.getKernelExecFlags(targetOp.getInnermostCapturedOmpOp()) !=
+        omp::TargetExecMode::generic)
+      return false;
+  } else {
+    auto declTargetIface = op.getParentOfType<omp::DeclareTargetInterface>();
+    if (!declTargetIface || !declTargetIface.isDeclareTarget() ||
+        declTargetIface.getDeclareTargetDeviceType() ==
+            omp::DeclareTargetDeviceType::host)
+      return false;
+  }
+  return true;
+}
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/CMakeLists.txt
index 0a5d7c6e22058..eb748d8b43630 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/CMakeLists.txt
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/CMakeLists.txt
@@ -8,6 +8,7 @@ add_mlir_translation_library(MLIROpenMPToLLVMIRTranslation
   MLIRIR
   MLIRLLVMDialect
   MLIROpenMPDialect
+  MLIROpenMPUtils
   MLIRSupport
   MLIRTargetLLVMIRExport
   MLIRTransformUtils
diff --git a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
index ef5d096ee9bb3..151a7ae32fd42 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp
@@ -16,6 +16,7 @@
 #include "mlir/Dialect/LLVMIR/LLVMTypes.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
 #include "mlir/Dialect/OpenMP/OpenMPInterfaces.h"
+#include "mlir/Dialect/OpenMP/Utils/Utils.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Support/LLVM.h"
 #include "mlir/Target/LLVMIR/Dialect/OpenMPCommon.h"
@@ -1143,81 +1144,6 @@ struct DeferredStore {
 };
 } // namespace
 
-/// Check whether allocations for the given operation might potentially have to
-/// be done in device shared memory. That means we're compiling for an
-/// offloading target, the operation is neither an `omp::TargetOp` nor nested
-/// inside of one, or it is and that target region represents a Generic
-/// (non-SPMD) kernel.
-///
-/// This represents a necessary but not sufficient set of conditions to use
-/// device shared memory in place of regular allocas. For some variables, the
-/// associated OpenMP construct or their uses might also need to be taken into
-/// account.
-static bool
-mightAllocInDeviceSharedMemory(Operation &op,
-                               const llvm::OpenMPIRBuilder &ompBuilder) {
-  if (!ompBuilder.Config.isTargetDevice())
-    return false;
-
-  auto targetOp = dyn_cast<omp::TargetOp>(op);
-  if (!targetOp)
-    targetOp = op.getParentOfType<omp::TargetOp>();
-
-  return !targetOp ||
-         targetOp.getKernelExecFlags(targetOp.getInnermostCapturedOmpOp()) ==
-             omp::TargetExecMode::generic;
-}
-
-/// Check whether the entry block argument representing the private copy of a
-/// variable in an OpenMP construct must be allocated in device shared memory,
-/// based on what the uses of that copy are.
-///
-/// This must only be called if a previous call to
-/// \c mightAllocInDeviceSharedMemory has already returned \c true for the
-/// operation that owns the specified block argument.
-static bool mustAllocPrivateVarInDeviceSharedMemory(BlockArgument value) {
-  Operation *parentOp = value.getOwner()->getParentOp();
-  auto moduleOp = parentOp->getParentOfType<ModuleOp>();
-  for (auto *user : value.getUsers()) {
-    if (auto parallelOp = dyn_cast<omp::ParallelOp>(user)) {
-      if (llvm::is_contained(parallelOp.getReductionVars(), value))
-        return true;
-    } else if (auto callOp = dyn_cast<CallOpInterface>(user)) {
-      if (llvm::is_contained(callOp.getArgOperands(), value))
-        return true;
-    }
-
-    if (auto parallelOp = user->getParentOfType<omp::ParallelOp>()) {
-      if (parentOp->isProperAncestor(parallelOp)) {
-        // If it is used directly inside of a parallel region, skip private
-        // clause uses.
-        bool isPrivateClauseUse = false;
-        if (auto argIface = dyn_cast<omp::BlockArgOpenMPOpInterface>(user)) {
-          if (auto privateSyms = llvm::cast_or_null<ArrayAttr>(
-                  user->getAttr("private_syms"))) {
-            for (auto [var, sym] :
-                 llvm::zip_equal(argIface.getPrivateVars(), privateSyms)) {
-              if (var != value)
-                continue;
-
-              auto privateOp = cast<omp::PrivateClauseOp>(
-                  moduleOp.lookupSymbol(cast<SymbolRefAttr>(sym)));
-              if (privateOp.getCopyRegion().empty()) {
-                isPrivateClauseUse = true;
-                break;
-              }
-            }
-          }
-        }
-        if (!isPrivateClauseUse)
-          return true;
-      }
-    }
-  }
-
-  return false;
-}
-
 /// Allocate space for privatized reduction variables.
 /// `deferredStores` contains information to create store operations which needs
 /// to be inserted after all allocas
@@ -1236,8 +1162,7 @@ allocReductionVars(T op, ArrayRef<BlockArgument> reductionArgs,
   builder.SetInsertPoint(allocaIP.getBlock()->getTerminator());
 
   llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
-  bool useDeviceSharedMem = isa<omp::TeamsOp>(*op) &&
-                            mightAllocInDeviceSharedMemory(*op, *ompBuilder);
+  bool useDeviceSharedMem = omp::opInSharedDeviceContext(*op);
 
   // delay creating stores until after all allocas
   deferredStores.reserve(op.getNumReductionVars());
@@ -1368,8 +1293,7 @@ initReductionVars(OP op, ArrayRef<BlockArgument> reductionArgs,
     return success();
 
   llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
-  bool useDeviceSharedMem = isa<omp::TeamsOp>(*op) &&
-                            mightAllocInDeviceSharedMemory(*op, *ompBuilder);
+  bool useDeviceSharedMem = omp::opInSharedDeviceContext(*op);
 
   llvm::BasicBlock *initBlock = splitBB(builder, true, "omp.reduction.init");
   auto allocaIP = llvm::IRBuilderBase::InsertPoint(
@@ -1612,8 +1536,7 @@ static LogicalResult createReductionsAndCleanup(
       reductionRegions, privateReductionVariables, moduleTranslation, builder,
       "omp.reduction.cleanup");
 
-  bool useDeviceSharedMem = isa<omp::TeamsOp>(*op) &&
-                            mightAllocInDeviceSharedMemory(*op, *ompBuilder);
+  bool useDeviceSharedMem = omp::opInSharedDeviceContext(*op);
   if (useDeviceSharedMem) {
     for (auto [var, reductionDecl] :
          llvm::zip_equal(privateReductionVariables, reductionDecls))
@@ -1804,9 +1727,7 @@ allocatePrivateVars(T op, llvm::IRBuilderBase &builder,
   llvm::BasicBlock *afterAllocas = allocaTerminator->getSuccessor(0);
 
   llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
-  bool mightUseDeviceSharedMem =
-      isa<omp::TargetOp, omp::TeamsOp, omp::DistributeOp>(*op) &&
-      mightAllocInDeviceSharedMemory(*op, *ompBuilder);
+  bool mightUseDeviceSharedMem = omp::opInSharedDeviceContext(*op);
   unsigned int allocaAS =
       moduleTranslation.getLLVMModule()->getDataLayout().getAllocaAddrSpace();
   unsigned int defaultAS = moduleTranslation.getLLVMModule()
@@ -1820,8 +1741,7 @@ allocatePrivateVars(T op, llvm::IRBuilderBase &builder,
         moduleTranslation.convertType(privDecl.getType());
     builder.SetInsertPoint(allocaIP.getBlock()->getTerminator());
     llvm::Value *llvmPrivateVar = nullptr;
-    if (mightUseDeviceSharedMem &&
-        mustAllocPrivateVarInDeviceSharedMemory(blockArg)) {
+    if (mightUseDeviceSharedMem && omp::allocaUsesRequireSharedMem(blockArg)) {
       llvmPrivateVar = ompBuilder->createOMPAllocShared(builder, llvmAllocType);
     } else {
       llvmPrivateVar = builder.CreateAlloca(
@@ -1958,14 +1878,11 @@ cleanupPrivateVars(T op, llvm::IRBuilderBase &builder,
                                 "`omp.private` op in");
 
   llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
-  bool mightUseDeviceSharedMem =
-      isa<omp::TargetOp, omp::TeamsOp, omp::DistributeOp>(*op) &&
-      mightAllocInDeviceSharedMemory(*op, *ompBuilder);
+  bool mightUseDeviceSharedMem = omp::opInSharedDeviceContext(*op);
   for (auto [privDecl, llvmPrivVar, blockArg] :
        llvm::zip_equal(privateVarsInfo.privatizers, privateVarsInfo.llvmVars,
                        privateVarsInfo.blockArgs)) {...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/182856


More information about the llvm-branch-commits mailing list