[Mlir-commits] [mlir] 027977e - [OpenACC] add acc.reduction_combine operation (#181853)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Feb 17 15:57:45 PST 2026


Author: Scott Manley
Date: 2026-02-17T17:57:40-06:00
New Revision: 027977e0a8e34e47b9ef5792a6d516991be70fd9

URL: https://github.com/llvm/llvm-project/commit/027977e0a8e34e47b9ef5792a6d516991be70fd9
DIFF: https://github.com/llvm/llvm-project/commit/027977e0a8e34e47b9ef5792a6d516991be70fd9.diff

LOG: [OpenACC] add acc.reduction_combine operation (#181853)

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.reduction_combine %srcMemref into %destMemref <reductionOperator> : type
```

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
    mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
    mlir/test/Dialect/OpenACC/ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 8f7c8c2a89be9..b1e87851fbafd 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -20,6 +20,48 @@
 // the necessary includes and definitions. The operations defined here use
 // types and definitions from that file.
 
+//===----------------------------------------------------------------------===//
+// acc.reduction_combine
+//===----------------------------------------------------------------------===//
+
+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
+    variable. The intention of this operator is to facilitate codegen
+    decisions (such as generate an atomic update). E.g.
+
+    ```
+      acc.reduction_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 OpenACC_AnyPointerOrMappableType:$destMemref,
+                       OpenACC_AnyPointerOrMappableType:$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..03fe5d177e327 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();
 }
 
+//===----------------------------------------------------------------------===//
+// ReductionCombineOp
+//===----------------------------------------------------------------------===//
+void acc::ReductionCombineOp::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..15698ca457ca0 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_reduction_combine(%arg0 : memref<i32>, %arg1 : memref<i32>) {
+  acc.reduction_combine %arg0 into %arg1 <add> : memref<i32>
+  return
+}
+
+// CHECK-LABEL: func @test_acc_reduction_combine
+// CHECK:       acc.reduction_combine %arg0 into %arg1 <add> : memref<i32>


        


More information about the Mlir-commits mailing list