[Mlir-commits] [mlir] [mlir][acc] Add gpu module and data layout utilities (PR #180988)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Wed Feb 11 10:30:19 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir
Author: Razvan Lupusoru (razvanlupusoru)
<details>
<summary>Changes</summary>
Add utility functions to support OpenACC code generation:
- getOrCreateGPUModule for GPU module management with configurable naming
- getDataLayout for querying data layout from operations with explicit spec or module fallback
---
Patch is 20.13 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/180988.diff
11 Files Affected:
- (modified) mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h (+36)
- (added) mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsCG.h (+39)
- (added) mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsGPU.h (+44)
- (modified) mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt (+1)
- (modified) mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp (+9)
- (modified) mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt (+4)
- (added) mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp (+55)
- (added) mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsGPU.cpp (+47)
- (modified) mlir/unittests/Dialect/OpenACC/CMakeLists.txt (+3)
- (added) mlir/unittests/Dialect/OpenACC/OpenACCUtilsCGTest.cpp (+76)
- (added) mlir/unittests/Dialect/OpenACC/OpenACCUtilsGPUTest.cpp (+89)
``````````diff
diff --git a/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h b/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
index 31ef05c2f1743..6b68ffd4620e2 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
+++ b/mlir/include/mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h
@@ -50,7 +50,9 @@
#ifndef MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
#define MLIR_DIALECT_OPENACC_ANALYSIS_OPENACCSUPPORT_H
+#include "mlir/Dialect/GPU/IR/GPUDialect.h"
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtilsGPU.h"
#include "mlir/IR/Remarks.h"
#include "mlir/IR/Value.h"
#include "mlir/Pass/AnalysisManager.h"
@@ -95,6 +97,10 @@ struct OpenACCSupportTraits {
/// Check if a value use is legal in an OpenACC region.
virtual bool isValidValueUse(Value v, mlir::Region ®ion) = 0;
+
+ /// Get or optionally create a GPU module in the given module.
+ virtual std::optional<gpu::GPUModuleOp>
+ getOrCreateGPUModule(ModuleOp mod, bool create, llvm::StringRef name) = 0;
};
/// SFINAE helpers to detect if implementation has optional methods
@@ -125,6 +131,16 @@ struct OpenACCSupportTraits {
llvm::is_detected<emitRemark_t, ImplT, Operation *,
std::function<std::string()>, llvm::StringRef>;
+ template <typename ImplT, typename... Args>
+ using getOrCreateGPUModule_t =
+ decltype(std::declval<ImplT>().getOrCreateGPUModule(
+ std::declval<Args>()...));
+
+ template <typename ImplT>
+ using has_getOrCreateGPUModule =
+ llvm::is_detected<getOrCreateGPUModule_t, ImplT, ModuleOp, bool,
+ llvm::StringRef>;
+
/// This class wraps a concrete OpenACCSupport implementation and forwards
/// interface calls to it. This provides type erasure, allowing different
/// implementation types to be used interchangeably without inheritance.
@@ -172,6 +188,15 @@ struct OpenACCSupportTraits {
return acc::isValidValueUse(v, region);
}
+ std::optional<gpu::GPUModuleOp>
+ getOrCreateGPUModule(ModuleOp mod, bool create,
+ llvm::StringRef name) final {
+ if constexpr (has_getOrCreateGPUModule<ImplT>::value)
+ return impl.getOrCreateGPUModule(mod, create, name);
+ else
+ return acc::getOrCreateGPUModule(mod, create, name);
+ }
+
private:
ImplT impl;
};
@@ -270,6 +295,17 @@ class OpenACCSupport {
/// \param region The MLIR region in which the legality is checked.
bool isValidValueUse(Value v, Region ®ion);
+ /// Get or optionally create a GPU module in the given module.
+ ///
+ /// \param mod The module to search or create the GPU module in.
+ /// \param create If true (default), create the GPU module if it doesn't exist.
+ /// \param name The name for the GPU module. If empty, implementation uses its
+ /// default name.
+ /// \return The GPU module if found or created, std::nullopt otherwise.
+ std::optional<gpu::GPUModuleOp>
+ getOrCreateGPUModule(ModuleOp mod, bool create = true,
+ llvm::StringRef name = "");
+
/// Signal that this analysis should always be preserved so that
/// underlying implementation registration is not lost.
bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) {
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsCG.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsCG.h
new file mode 100644
index 0000000000000..862fdd5b3e8f3
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsCG.h
@@ -0,0 +1,39 @@
+//===- OpenACCUtilsCG.h - OpenACC Code Generation 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 file defines utility functions for OpenACC code generation, including
+// data layout and type-related utilities.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
+#define MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
+
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include <optional>
+
+namespace mlir {
+class Operation;
+
+namespace acc {
+
+/// Get the data layout for an operation.
+///
+/// Attempts to get the data layout from the operation or its parent module.
+/// If `allowDefault` is true (default), a default data layout may be
+/// constructed when no explicit data layout spec is found.
+///
+/// \param op The operation to get the data layout for.
+/// \param allowDefault If true, allow returning a default data layout.
+/// \return The data layout if available, std::nullopt otherwise.
+std::optional<DataLayout> getDataLayout(Operation *op, bool allowDefault = true);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_OPENACCUTILSCG_H_
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsGPU.h b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsGPU.h
new file mode 100644
index 0000000000000..7a5fc46a21640
--- /dev/null
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCUtilsGPU.h
@@ -0,0 +1,44 @@
+//===- OpenACCUtilsGPU.h - OpenACC GPU 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 file defines utility functions for OpenACC that depend on the GPU
+// dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MLIR_DIALECT_OPENACC_OPENACCUTILSGPU_H_
+#define MLIR_DIALECT_OPENACC_OPENACCUTILSGPU_H_
+
+#include "mlir/Dialect/GPU/IR/GPUDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include <optional>
+
+namespace mlir {
+namespace acc {
+
+/// Default GPU module name used by OpenACC.
+constexpr llvm::StringLiteral kDefaultGPUModuleName = "acc_gpu_module";
+
+/// Get or create a GPU module in the given module.
+///
+/// If a GPU module with the specified name already exists, it is returned.
+/// If `create` is true and no GPU module exists, one is created.
+/// If `create` is false and no GPU module exists, std::nullopt is returned.
+///
+/// \param mod The module to search or create the GPU module in.
+/// \param create If true (default), create the GPU module if it doesn't exist.
+/// \param name The name for the GPU module. If empty, uses kDefaultGPUModuleName.
+/// \return The GPU module if found or created, std::nullopt otherwise.
+std::optional<gpu::GPUModuleOp>
+getOrCreateGPUModule(ModuleOp mod, bool create = true,
+ llvm::StringRef name = kDefaultGPUModuleName);
+
+} // namespace acc
+} // namespace mlir
+
+#endif // MLIR_DIALECT_OPENACC_OPENACCUTILSGPU_H_
diff --git a/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
index f305068e1b3bc..f2c13608855b9 100644
--- a/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/Analysis/CMakeLists.txt
@@ -5,6 +5,7 @@ add_mlir_dialect_library(MLIROpenACCAnalysis
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/OpenACC
LINK_LIBS PUBLIC
+ MLIRGPUDialect
MLIRIR
MLIROpenACCDialect
MLIROpenACCUtils
diff --git a/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp b/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
index f204ace4609ab..3875122152194 100644
--- a/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
+++ b/mlir/lib/Dialect/OpenACC/Analysis/OpenACCSupport.cpp
@@ -12,6 +12,7 @@
#include "mlir/Dialect/OpenACC/Analysis/OpenACCSupport.h"
#include "mlir/Dialect/OpenACC/OpenACCUtils.h"
+#include "mlir/Dialect/OpenACC/OpenACCUtilsGPU.h"
namespace mlir {
namespace acc {
@@ -63,5 +64,13 @@ bool OpenACCSupport::isValidValueUse(Value v, Region ®ion) {
return acc::isValidValueUse(v, region);
}
+std::optional<gpu::GPUModuleOp>
+OpenACCSupport::getOrCreateGPUModule(ModuleOp mod, bool create,
+ llvm::StringRef name) {
+ if (impl)
+ return impl->getOrCreateGPUModule(mod, create, name);
+ return acc::getOrCreateGPUModule(mod, create, name);
+}
+
} // namespace acc
} // namespace mlir
diff --git a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
index 532ba90355b44..baf248fd9b2ae 100644
--- a/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
+++ b/mlir/lib/Dialect/OpenACC/Utils/CMakeLists.txt
@@ -1,5 +1,7 @@
add_mlir_dialect_library(MLIROpenACCUtils
OpenACCUtils.cpp
+ OpenACCUtilsCG.cpp
+ OpenACCUtilsGPU.cpp
OpenACCUtilsLoop.cpp
OpenACCUtilsTiling.cpp
@@ -18,6 +20,8 @@ add_mlir_dialect_library(MLIROpenACCUtils
LINK_LIBS PUBLIC
MLIRArithDialect
MLIRArithUtils
+ MLIRDataLayoutInterfaces
+ MLIRGPUDialect
MLIROpenACCDialect
MLIRIR
MLIRSCFDialect
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp
new file mode 100644
index 0000000000000..5c5c453f2cae0
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsCG.cpp
@@ -0,0 +1,55 @@
+//===- OpenACCUtilsCG.cpp - OpenACC Code Generation Utilities -------------===//
+//
+// 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 utility functions for OpenACC code generation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsCG.h"
+#include "mlir/IR/BuiltinOps.h"
+
+namespace mlir {
+namespace acc {
+
+std::optional<DataLayout> getDataLayout(Operation *op, bool allowDefault) {
+ if (!op)
+ return std::nullopt;
+
+ // Walk up the parent chain to find the nearest operation with an explicit
+ // data layout spec. Check ModuleOp explicitly since it does not actually
+ // implement DataLayoutOpInterface as a trait (it just has the same methods).
+ Operation *current = op;
+ while (current) {
+ // Check for ModuleOp with explicit data layout spec
+ if (auto mod = llvm::dyn_cast<ModuleOp>(current)) {
+ if (mod.getDataLayoutSpec())
+ return DataLayout(mod);
+ } else if (auto dataLayoutOp =
+ llvm::dyn_cast<DataLayoutOpInterface>(current)) {
+ // Check other DataLayoutOpInterface implementations
+ if (dataLayoutOp.getDataLayoutSpec())
+ return DataLayout(dataLayoutOp);
+ }
+ current = current->getParentOp();
+ }
+
+ // No explicit data layout found; return default if allowed
+ if (allowDefault) {
+ // Check if op itself is a ModuleOp
+ if (auto mod = llvm::dyn_cast<ModuleOp>(op))
+ return DataLayout(mod);
+ // Otherwise check parents
+ if (auto mod = op->getParentOfType<ModuleOp>())
+ return DataLayout(mod);
+ }
+
+ return std::nullopt;
+}
+
+} // namespace acc
+} // namespace mlir
diff --git a/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsGPU.cpp b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsGPU.cpp
new file mode 100644
index 0000000000000..fb1e34f514da9
--- /dev/null
+++ b/mlir/lib/Dialect/OpenACC/Utils/OpenACCUtilsGPU.cpp
@@ -0,0 +1,47 @@
+//===- OpenACCUtilsGPU.cpp - OpenACC GPU Utilities ------------------------===//
+//
+// 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 utility functions for OpenACC that depend on the GPU
+// dialect.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsGPU.h"
+#include "mlir/IR/SymbolTable.h"
+
+namespace mlir {
+namespace acc {
+
+std::optional<gpu::GPUModuleOp> getOrCreateGPUModule(ModuleOp mod, bool create,
+ llvm::StringRef name) {
+ // Use default name if provided name is empty
+ llvm::StringRef moduleName =
+ name.empty() ? llvm::StringRef(kDefaultGPUModuleName) : name;
+
+ // Look for existing GPU module with the specified name
+ SymbolTable symTab(mod);
+ if (auto gpuMod = symTab.lookup<gpu::GPUModuleOp>(moduleName))
+ return gpuMod;
+
+ if (!create)
+ return std::nullopt;
+
+ // Create a new GPU module
+ auto *ctx = mod.getContext();
+ mod->setAttr(gpu::GPUDialect::getContainerModuleAttrName(),
+ UnitAttr::get(ctx));
+
+ OpBuilder builder(ctx);
+ auto gpuMod = gpu::GPUModuleOp::create(builder, mod.getLoc(), moduleName);
+ Block::iterator insertPt(mod.getBodyRegion().front().end());
+ symTab.insert(gpuMod, insertPt);
+ return gpuMod;
+}
+
+} // namespace acc
+} // namespace mlir
diff --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
index 4359bae00ca21..7303ff581abc4 100644
--- a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -2,6 +2,8 @@ add_mlir_unittest(MLIROpenACCTests
OpenACCOpsTest.cpp
OpenACCOpsInterfacesTest.cpp
OpenACCTypeInterfacesTest.cpp
+ OpenACCUtilsCGTest.cpp
+ OpenACCUtilsGPUTest.cpp
OpenACCUtilsTest.cpp
OpenACCUtilsTilingTest.cpp
OpenACCUtilsLoopTest.cpp
@@ -10,6 +12,7 @@ mlir_target_link_libraries(MLIROpenACCTests
PRIVATE
MLIRIR
MLIRAffineDialect
+ MLIRDLTIDialect
MLIRFuncDialect
MLIRGPUDialect
MLIRMemRefDialect
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsCGTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsCGTest.cpp
new file mode 100644
index 0000000000000..23827923e9e0f
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsCGTest.cpp
@@ -0,0 +1,76 @@
+//===- OpenACCUtilsCGTest.cpp - Unit tests for OpenACC CG utilities -------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsCG.h"
+#include "mlir/Dialect/DLTI/DLTI.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCUtilsCGTest : public ::testing::Test {
+protected:
+ OpenACCUtilsCGTest() : b(&context), loc(UnknownLoc::get(&context)) {
+ context.loadDialect<acc::OpenACCDialect, DLTIDialect>();
+ }
+
+ MLIRContext context;
+ OpBuilder b;
+ Location loc;
+};
+
+//===----------------------------------------------------------------------===//
+// getDataLayout Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCUtilsCGTest, getDataLayoutNoSpecAllowDefault) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // With allowDefault=true, should return a default DataLayout
+ auto dl = getDataLayout(module->getOperation(), /*allowDefault=*/true);
+ EXPECT_TRUE(dl.has_value());
+}
+
+TEST_F(OpenACCUtilsCGTest, getDataLayoutNoSpecDisallowDefault) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // With allowDefault=false and no spec, should return nullopt
+ auto dl = getDataLayout(module->getOperation(), /*allowDefault=*/false);
+ EXPECT_FALSE(dl.has_value());
+}
+
+TEST_F(OpenACCUtilsCGTest, getDataLayoutNullOp) {
+ // Null operation should return nullopt
+ auto dl = getDataLayout(nullptr, /*allowDefault=*/true);
+ EXPECT_FALSE(dl.has_value());
+}
+
+TEST_F(OpenACCUtilsCGTest, getDataLayoutWithSpec) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // Add a data layout spec to the module
+ auto indexEntry = DataLayoutEntryAttr::get(
+ IndexType::get(&context), b.getI32IntegerAttr(32));
+ auto spec = DataLayoutSpecAttr::get(&context, {indexEntry});
+ (*module)->setAttr(DLTIDialect::kDataLayoutAttrName, spec);
+
+ // With explicit spec, should return DataLayout regardless of allowDefault
+ auto dl1 = getDataLayout(module->getOperation(), /*allowDefault=*/false);
+ EXPECT_TRUE(dl1.has_value());
+
+ auto dl2 = getDataLayout(module->getOperation(), /*allowDefault=*/true);
+ EXPECT_TRUE(dl2.has_value());
+}
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCUtilsGPUTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsGPUTest.cpp
new file mode 100644
index 0000000000000..e9d94edde3a92
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCUtilsGPUTest.cpp
@@ -0,0 +1,89 @@
+//===- OpenACCUtilsGPUTest.cpp - Unit tests for OpenACC GPU utilities ----===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/OpenACC/OpenACCUtilsGPU.h"
+#include "mlir/Dialect/GPU/IR/GPUDialect.h"
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/IR/MLIRContext.h"
+#include "mlir/IR/OwningOpRef.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCUtilsGPUTest : public ::testing::Test {
+protected:
+ OpenACCUtilsGPUTest() : b(&context), loc(UnknownLoc::get(&context)) {
+ context.loadDialect<gpu::GPUDialect>();
+ }
+
+ MLIRContext context;
+ OpBuilder b;
+ Location loc;
+};
+
+//===----------------------------------------------------------------------===//
+// getOrCreateGPUModule Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCUtilsGPUTest, getOrCreateGPUModuleCreatesWhenMissing) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // First call should create the GPU module
+ auto gpuMod = getOrCreateGPUModule(*module, /*create=*/true);
+ ASSERT_TRUE(gpuMod.has_value());
+ EXPECT_EQ(gpuMod->getName(), kDefaultGPUModuleName);
+
+ // Module should now have the container module attribute
+ EXPECT_TRUE(
+ (*module)->hasAttr(gpu::GPUDialect::getContainerModuleAttrName()));
+}
+
+TEST_F(OpenACCUtilsGPUTest, getOrCreateGPUModuleReturnsExisting) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // Create a GPU module first
+ auto gpuMod1 = getOrCreateGPUModule(*module, /*create=*/true);
+ ASSERT_TRUE(gpuMod1.has_value());
+
+ // Second call should return the same module
+ auto gpuMod2 = getOrCreateGPUModule(*module, /*create=*/true);
+ ASSERT_TRUE(gpuMod2.has_value());
+ EXPECT_EQ(gpuMod1->getOperation(), gpuMod2->getOperation());
+}
+
+TEST_F(OpenACCUtilsGPUTest, getOrCreateGPUModuleNoCreateReturnsNullopt) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // With create=false and no existing GPU module, should return nullopt
+ auto gpuMod = getOrCreateGPUModule(*module, /*create=*/false);
+ EXPECT_FALSE(gpuMod.has_value());
+}
+
+TEST_F(OpenACCUtilsGPUTest, getOrCreateGPUModuleCustomName) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // Create with custom name
+ auto gpuMod =
+ getOrCreateGPUModule(*module, /*create=*/true, "custom_gpu_module");
+ ASSERT_TRUE(gpuMod.has_value());
+ EXPECT_EQ(gpuMod->getName(), "custom_gpu_module");
+}
+
+TEST_F(OpenACCUtilsGPUTest, getOrCreateGPUModuleEmptyNameUsesDefault) {
+ OwningOpRef<ModuleOp> module = ModuleOp::create(b, loc);
+
+ // Empty name should use default
+ auto gpuMod = getOrCreateGP...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/180988
More information about the Mlir-commits
mailing list