[Mlir-commits] [mlir] [OpenACC] add acc.combine operation (PR #181853)

Scott Manley llvmlistbot at llvm.org
Tue Feb 17 15:46:18 PST 2026


https://github.com/rscottmanley updated https://github.com/llvm/llvm-project/pull/181853

>From 105bcc95892d900a373ec97ce06ef7a68916aa84 Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Tue, 17 Feb 2026 08:12:34 -0800
Subject: [PATCH 1/3] [OpenACC] add acc.combine operation

To facilitate codegen decisions, we need to create an operation that can
abstract the final update of the original and partial sum from a
reduction. This is represented within the combiner recipes. Having an
operator allows future lowering to clearly identify how to handle the
final accumulation. This is currently an NFC.

The format of this operation is:

```
  acc.combine %srcMemref into %destMemref <reductionOperator> : type
```
---
 .../mlir/Dialect/OpenACC/OpenACCCGOps.td      | 41 +++++++++++++++++++
 mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp       | 17 ++++++++
 mlir/test/Dialect/OpenACC/ops.mlir            | 10 +++++
 3 files changed, 68 insertions(+)

diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 8f7c8c2a89be9..99f51db6544c9 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -20,6 +20,47 @@
 // the necessary includes and definitions. The operations defined here use
 // types and definitions from that file.
 
+//===----------------------------------------------------------------------===//
+// acc.combine
+//===----------------------------------------------------------------------===//
+
+def OpenACC_CombineOp: OpenACC_Op<"combine", [SameTypeOperands, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+  let summary = "Combine a reduction partial sum with its original value";
+  let description = [{
+    This operation is a composite to do a typical update of a reduction
+    variable. The intention of this operator is to facilitate codegen
+    decisions (such as generate an atomic update). E.g.
+
+    ```
+      lro.combine %src into %dest <addi> : memref<i32>
+    ```
+
+    Might lower to something similar to
+
+    ```
+      %loadSrc = memref.load %src[] : memref<i32>
+      %loadDest = memref.load %dest[] : memref<i32>
+      %combine = arith.addi %loadSrc, %loadDest : i32
+      memref.store %combine, %dest[] : memref<i32>
+    ```
+    
+    The $destMemref operand is a "pointer" to the original reduction 
+    variable (typically shared). The $srcMemref operand is a "pointer"
+    to the partial sum of the reduction (typically private).
+
+    The $kind is the OpenACC reduction operator that determines how to 
+    accumulate the two values.
+  }];
+
+  let arguments = (ins AnyType:$destMemref,
+                       AnyType:$srcMemref,
+                       OpenACC_ReductionOperatorAttr:$reductionOperator);
+  
+  let assemblyFormat = [{
+    $srcMemref `into` $destMemref $reductionOperator `:` type($destMemref) attr-dict
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // acc.kernel_environment
 //===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 460314f8f678f..33c285d4bfb27 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -5129,6 +5129,23 @@ LogicalResult acc::WaitOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// CombineOp
+//===----------------------------------------------------------------------===//
+void acc::CombineOp::getEffects(
+    llvm::SmallVectorImpl<
+        mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
+        &effects) {
+  effects.emplace_back(mlir::MemoryEffects::Read::get(), &getSrcMemrefMutable(),
+                       mlir::SideEffects::DefaultResource::get());
+  effects.emplace_back(mlir::MemoryEffects::Read::get(),
+                       &getDestMemrefMutable(),
+                       mlir::SideEffects::DefaultResource::get());
+  effects.emplace_back(mlir::MemoryEffects::Write::get(),
+                       &getDestMemrefMutable(),
+                       mlir::SideEffects::DefaultResource::get());
+}
+
 #define GET_OP_CLASSES
 #include "mlir/Dialect/OpenACC/OpenACCOps.cpp.inc"
 
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index d31397c15769b..cc9cae98aa277 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -2494,3 +2494,13 @@ func.func @test_kernel_environment_with_async(%arg0: memref<1024xf32>) {
 // CHECK:           gpu.launch
 // CHECK:             memref.store %{{.*}}, %[[CREATE]]
 // CHECK:         acc.copyout accPtr(%[[CREATE]] : memref<1024xf32>) async(%[[ASYNC]] : i32) to varPtr(%{{.*}} : memref<1024xf32>)
+
+// -----
+
+func.func @test_acc_combine(%arg0 : memref<i32>, %arg1 : memref<i32>) {
+  acc.combine %arg0 into %arg1 <add> : memref<i32>
+  return
+}
+
+// CHECK-LABEL: func @test_acc_combine
+// CHECK:       acc.combine %arg0 into %arg1 <add> : memref<i32>
\ No newline at end of file

>From fe6dc120f59748e0077d9ec863bd4071f705c67d Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Tue, 17 Feb 2026 15:43:13 -0800
Subject: [PATCH 2/3] address Review comments:

use OpenACC_AnyPointerOrMappableType for operands

rename to acc.reduction_combine
---
 mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td | 8 ++++----
 mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp           | 4 ++--
 mlir/test/Dialect/OpenACC/ops.mlir                | 8 ++++----
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 99f51db6544c9..2d617331e43a3 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -24,7 +24,7 @@
 // acc.combine
 //===----------------------------------------------------------------------===//
 
-def OpenACC_CombineOp: OpenACC_Op<"combine", [SameTypeOperands, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+def OpenACC_ReductionCombineOp: OpenACC_Op<"reduction_combine", [SameTypeOperands, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
   let summary = "Combine a reduction partial sum with its original value";
   let description = [{
     This operation is a composite to do a typical update of a reduction
@@ -32,7 +32,7 @@ def OpenACC_CombineOp: OpenACC_Op<"combine", [SameTypeOperands, DeclareOpInterfa
     decisions (such as generate an atomic update). E.g.
 
     ```
-      lro.combine %src into %dest <addi> : memref<i32>
+      acc.reduction_combine %src into %dest <addi> : memref<i32>
     ```
 
     Might lower to something similar to
@@ -52,8 +52,8 @@ def OpenACC_CombineOp: OpenACC_Op<"combine", [SameTypeOperands, DeclareOpInterfa
     accumulate the two values.
   }];
 
-  let arguments = (ins AnyType:$destMemref,
-                       AnyType:$srcMemref,
+  let arguments = (ins OpenACC_AnyPointerOrMappableType:$destMemref,
+                       OpenACC_AnyPointerOrMappableType:$srcMemref,
                        OpenACC_ReductionOperatorAttr:$reductionOperator);
   
   let assemblyFormat = [{
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 33c285d4bfb27..03fe5d177e327 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -5130,9 +5130,9 @@ LogicalResult acc::WaitOp::verify() {
 }
 
 //===----------------------------------------------------------------------===//
-// CombineOp
+// ReductionCombineOp
 //===----------------------------------------------------------------------===//
-void acc::CombineOp::getEffects(
+void acc::ReductionCombineOp::getEffects(
     llvm::SmallVectorImpl<
         mlir::SideEffects::EffectInstance<mlir::MemoryEffects::Effect>>
         &effects) {
diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir
index cc9cae98aa277..15698ca457ca0 100644
--- a/mlir/test/Dialect/OpenACC/ops.mlir
+++ b/mlir/test/Dialect/OpenACC/ops.mlir
@@ -2497,10 +2497,10 @@ func.func @test_kernel_environment_with_async(%arg0: memref<1024xf32>) {
 
 // -----
 
-func.func @test_acc_combine(%arg0 : memref<i32>, %arg1 : memref<i32>) {
-  acc.combine %arg0 into %arg1 <add> : memref<i32>
+func.func @test_acc_reduction_combine(%arg0 : memref<i32>, %arg1 : memref<i32>) {
+  acc.reduction_combine %arg0 into %arg1 <add> : memref<i32>
   return
 }
 
-// CHECK-LABEL: func @test_acc_combine
-// CHECK:       acc.combine %arg0 into %arg1 <add> : memref<i32>
\ No newline at end of file
+// CHECK-LABEL: func @test_acc_reduction_combine
+// CHECK:       acc.reduction_combine %arg0 into %arg1 <add> : memref<i32>

>From 0315b592fa1477e67bb723007a2e6f3179da9d5a Mon Sep 17 00:00:00 2001
From: Scott Manley <scmanley at nvidia.com>
Date: Tue, 17 Feb 2026 15:46:01 -0800
Subject: [PATCH 3/3] format .td

---
 mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 2d617331e43a3..9283fe69753f6 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -24,7 +24,8 @@
 // acc.combine
 //===----------------------------------------------------------------------===//
 
-def OpenACC_ReductionCombineOp: OpenACC_Op<"reduction_combine", [SameTypeOperands, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
+def OpenACC_ReductionCombineOp: OpenACC_Op<"reduction_combine", 
+    [SameTypeOperands, DeclareOpInterfaceMethods<MemoryEffectsOpInterface>]> {
   let summary = "Combine a reduction partial sum with its original value";
   let description = [{
     This operation is a composite to do a typical update of a reduction



More information about the Mlir-commits mailing list