[Mlir-commits] [flang] [mlir] [flang][acc] Use ReducibleType interface on LogicalType (PR #178253)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jan 27 08:50:39 PST 2026


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-openacc

Author: Razvan Lupusoru (razvanlupusoru)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/178253.diff


7 Files Affected:

- (modified) flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h (+7) 
- (modified) flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp (+19) 
- (modified) flang/lib/Optimizer/OpenACC/Support/RegisterOpenACCExtensions.cpp (+2) 
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACC.h (+1) 
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td (+29) 
- (modified) mlir/unittests/Dialect/OpenACC/CMakeLists.txt (+1) 
- (added) mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp (+93) 


``````````diff
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 &registry) {
     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);
+}

``````````

</details>


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


More information about the Mlir-commits mailing list