[Mlir-commits] [flang] [mlir] [flang][acc] Use ReducibleType interface on LogicalType (PR #178253)
Razvan Lupusoru
llvmlistbot at llvm.org
Tue Jan 27 08:52:31 PST 2026
https://github.com/razvanlupusoru updated https://github.com/llvm/llvm-project/pull/178253
>From 0ab19b4729f0e54a126edf874fc38a07fd12f358 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Tue, 27 Jan 2026 08:49:00 -0800
Subject: [PATCH 1/2] [flang][acc] Use ReducibleType interface on LogicalType
Introduce a new ReducibleType type interface in the OpenACC dialect
that provides a type-aware mechanism for translating OpenACC reduction
operators to arith::AtomicRMWKind values. This interface should be
attached to value types that can participate in OpenACC reductions.
For FIR, implement this interface on fir::LogicalType to handle the
AccLand and AccLor reduction operators, which map to
arith::AtomicRMWKind::andi and ori respectively.
---
.../Support/FIROpenACCTypeInterfaces.h | 7 ++
.../Support/FIROpenACCTypeInterfaces.cpp | 19 ++++
.../Support/RegisterOpenACCExtensions.cpp | 2 +
mlir/include/mlir/Dialect/OpenACC/OpenACC.h | 1 +
.../Dialect/OpenACC/OpenACCTypeInterfaces.td | 29 ++++++
mlir/unittests/Dialect/OpenACC/CMakeLists.txt | 1 +
.../OpenACC/OpenACCTypeInterfacesTest.cpp | 93 +++++++++++++++++++
7 files changed, 152 insertions(+)
create mode 100644 mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
index 1ce69df2d7154..9d952a6130f0e 100644
--- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
+++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
@@ -108,6 +108,13 @@ struct OpenACCMappableModel
bool isDeviceData(mlir::Type type, mlir::Value var) const;
};
+struct OpenACCReducibleLogicalModel
+ : public mlir::acc::ReducibleType::ExternalModel<
+ OpenACCReducibleLogicalModel, fir::LogicalType> {
+ std::optional<mlir::arith::AtomicRMWKind>
+ getAtomicRMWKind(mlir::Type type, mlir::acc::ReductionOperator redOp) const;
+};
+
} // namespace fir::acc
#endif // FLANG_OPTIMIZER_OPENACC_FIROPENACCTYPEINTERFACES_H_
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index dde6d678cf255..7619a21fc0477 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -1586,4 +1586,23 @@ template bool
OpenACCMappableModel<fir::PointerType>::isDeviceData(mlir::Type,
mlir::Value) const;
+std::optional<mlir::arith::AtomicRMWKind>
+OpenACCReducibleLogicalModel::getAtomicRMWKind(
+ mlir::Type type, mlir::acc::ReductionOperator redOp) const {
+ switch (redOp) {
+ case mlir::acc::ReductionOperator::AccLand:
+ return mlir::arith::AtomicRMWKind::andi;
+ case mlir::acc::ReductionOperator::AccLor:
+ return mlir::arith::AtomicRMWKind::ori;
+ case mlir::acc::ReductionOperator::AccEqv:
+ case mlir::acc::ReductionOperator::AccNeqv:
+ // Eqv and Neqv are valid for logical types but don't have a direct
+ // AtomicRMWKind mapping yet.
+ return std::nullopt;
+ default:
+ // Other reduction operators are not valid for logical types.
+ return std::nullopt;
+ }
+}
+
} // namespace fir::acc
diff --git a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
index d0f323684b759..c0be247a47729 100644
--- a/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp
@@ -45,6 +45,8 @@ void registerOpenACCExtensions(mlir::DialectRegistry ®istry) {
fir::LLVMPointerType::attachInterface<
OpenACCPointerLikeModel<fir::LLVMPointerType>>(*ctx);
+ fir::LogicalType::attachInterface<OpenACCReducibleLogicalModel>(*ctx);
+
fir::ArrayCoorOp::attachInterface<
PartialEntityAccessModel<fir::ArrayCoorOp>>(*ctx);
fir::CoordinateOp::attachInterface<
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
index 84fbf2c3d936c..6a873afb1fcdc 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
@@ -23,6 +23,7 @@
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.h.inc"
+#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc"
#include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h"
#include "mlir/IR/Value.h"
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
index ca60f9bca5cf1..97def012990c0 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
@@ -469,4 +469,33 @@ def OpenACC_MappableTypeInterface : TypeInterface<"MappableType"> {
];
}
+def OpenACC_ReducibleTypeInterface : TypeInterface<"ReducibleType"> {
+ let cppNamespace = "::mlir::acc";
+
+ let description = [{
+ This interface should be attached to value types that can participate in
+ OpenACC reductions. For PointerLikeType types, attach this interface to the
+ pointee type rather than the pointer type itself.
+ }];
+
+ let methods = [
+ InterfaceMethod<
+ /*description=*/[{
+ Returns the `arith::AtomicRMWKind` corresponding to the given OpenACC
+ reduction operator for this type. Returns `std::nullopt` if the
+ reduction operator is not valid for this type.
+
+ For example:
+ - Integer types typically map `AccAdd` to `arith::AtomicRMWKind::addi`
+ - Float types typically map `AccAdd` to `arith::AtomicRMWKind::addf`
+ - Boolean/logical types map `AccLand` to `arith::AtomicRMWKind::andi`
+ - A float type would return `std::nullopt` for `AccLand`
+ }],
+ /*retTy=*/"::std::optional<::mlir::arith::AtomicRMWKind>",
+ /*methodName=*/"getAtomicRMWKind",
+ /*args=*/(ins "::mlir::acc::ReductionOperator":$redOp)
+ >,
+ ];
+}
+
#endif // OPENACC_TYPE_INTERFACES
diff --git a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
index ef0c8fb11d0c9..4359bae00ca21 100644
--- a/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
+++ b/mlir/unittests/Dialect/OpenACC/CMakeLists.txt
@@ -1,6 +1,7 @@
add_mlir_unittest(MLIROpenACCTests
OpenACCOpsTest.cpp
OpenACCOpsInterfacesTest.cpp
+ OpenACCTypeInterfacesTest.cpp
OpenACCUtilsTest.cpp
OpenACCUtilsTilingTest.cpp
OpenACCUtilsLoopTest.cpp
diff --git a/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
new file mode 100644
index 0000000000000..c773c031e3b6e
--- /dev/null
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
@@ -0,0 +1,93 @@
+//===- OpenACCTypeInterfacesTest.cpp - Tests for OpenACC type interfaces -===//
+//
+// 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/Arith/IR/Arith.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
+#include "mlir/IR/BuiltinDialect.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/DialectRegistry.h"
+#include "mlir/IR/MLIRContext.h"
+#include "gtest/gtest.h"
+
+using namespace mlir;
+using namespace mlir::acc;
+
+namespace {
+
+/// Test model that attaches ReducibleType to IntegerType for testing purposes.
+/// This only implements a small subset of reduction operators to exercise the
+/// interface - a real implementation would handle all valid operators.
+struct TestReducibleIntegerModel
+ : public ReducibleType::ExternalModel<TestReducibleIntegerModel,
+ IntegerType> {
+ std::optional<arith::AtomicRMWKind>
+ getAtomicRMWKind(Type type, ReductionOperator redOp) const {
+ switch (redOp) {
+ case ReductionOperator::AccAdd:
+ return arith::AtomicRMWKind::addi;
+ default:
+ return std::nullopt;
+ }
+ }
+};
+
+} // namespace
+
+//===----------------------------------------------------------------------===//
+// Test Fixture
+//===----------------------------------------------------------------------===//
+
+class OpenACCTypeInterfacesTest : public ::testing::Test {
+protected:
+ OpenACCTypeInterfacesTest() : context() {
+ // Register the test external model before loading dialects.
+ DialectRegistry registry;
+ registry.addExtension(+[](MLIRContext *ctx, BuiltinDialect *dialect) {
+ IntegerType::attachInterface<TestReducibleIntegerModel>(*ctx);
+ });
+ context.appendDialectRegistry(registry);
+ context.loadDialect<acc::OpenACCDialect, arith::ArithDialect>();
+ }
+
+ MLIRContext context;
+};
+
+//===----------------------------------------------------------------------===//
+// ReducibleType Interface Tests
+//===----------------------------------------------------------------------===//
+
+TEST_F(OpenACCTypeInterfacesTest, ReducibleTypeGetAtomicRMWKindAdd) {
+ Type i32Type = IntegerType::get(&context, 32);
+ auto reducible = dyn_cast<ReducibleType>(i32Type);
+ ASSERT_TRUE(reducible != nullptr);
+
+ auto kind = reducible.getAtomicRMWKind(ReductionOperator::AccAdd);
+ ASSERT_TRUE(kind.has_value());
+ EXPECT_EQ(*kind, arith::AtomicRMWKind::addi);
+}
+
+TEST_F(OpenACCTypeInterfacesTest, ReducibleTypeGetAtomicRMWKindUnsupported) {
+ // Test that unsupported reduction operators return nullopt.
+ Type i32Type = IntegerType::get(&context, 32);
+ auto reducible = dyn_cast<ReducibleType>(i32Type);
+ ASSERT_TRUE(reducible != nullptr);
+
+ // The test model only implements AccAdd, so other operators return nullopt.
+ auto mulKind = reducible.getAtomicRMWKind(ReductionOperator::AccMul);
+ EXPECT_FALSE(mulKind.has_value());
+
+ auto noneKind = reducible.getAtomicRMWKind(ReductionOperator::AccNone);
+ EXPECT_FALSE(noneKind.has_value());
+}
+
+TEST_F(OpenACCTypeInterfacesTest, NonReducibleTypeReturnsNull) {
+ // Test that a type without the interface attached returns nullptr.
+ Type f32Type = Float32Type::get(&context);
+ auto reducible = dyn_cast<ReducibleType>(f32Type);
+ EXPECT_TRUE(reducible == nullptr);
+}
>From d0761f8cd37c026733950c04d5566b3c5653b4a0 Mon Sep 17 00:00:00 2001
From: Razvan Lupusoru <rlupusoru at nvidia.com>
Date: Tue, 27 Jan 2026 08:52:19 -0800
Subject: [PATCH 2/2] fix format
---
mlir/include/mlir/Dialect/OpenACC/OpenACC.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
index 6a873afb1fcdc..2f6d1ee5bdd3e 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
@@ -20,10 +20,10 @@
#include "mlir/IR/SymbolTable.h"
#include "mlir/Bytecode/BytecodeOpInterface.h"
+#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/OpenACC/OpenACCOpsDialect.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCOpsEnums.h.inc"
#include "mlir/Dialect/OpenACC/OpenACCOpsInterfaces.h.inc"
-#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/OpenACC/OpenACCTypeInterfaces.h.inc"
#include "mlir/Dialect/OpenACCMPCommon/Interfaces/AtomicInterfaces.h"
#include "mlir/IR/Value.h"
More information about the Mlir-commits
mailing list