[Mlir-commits] [mlir] [MLIR][OpenACC] Fix host fallback for acc.atomic.update (PR #207597)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Sun Jul 5 09:24:14 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-openacc

@llvm/pr-subscribers-mlir-openacc

Author: ES3Q

<details>
<summary>Changes</summary>

The host fallback for `acc.atomic.update` only processed the first operation in the region and used its result for the store, ignoring the remaining operations and the `acc.yield` terminator. This generated invalid IR when the region contained multiple operations.

1.Fix this by cloning all operations in the region and using the operand of `acc.yield` as the final result to store.
2.Add tests for atomic read, write, update, and capture operations to cover the host fallback path.

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


2 Files Affected:

- (modified) mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp (+6-2) 
- (modified) mlir/test/Dialect/OpenACC/acc-specialize-for-host-fallback.mlir (+63) 


``````````diff
diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
index d3c8b683b76cb..5f41a1175f21f 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
@@ -142,9 +142,13 @@ class ACCOrphanAtomicUpdateOpConversion
       }
       IRMapping mapping;
       mapping.map(atomicUpdateOp.getRegion().front().getArgument(0), loadOp);
-      Operation *expr = rewriter.clone(*atomicUpdateOp.getFirstOp(), mapping);
+      Block &block = atomicUpdateOp.getRegion().front();
+      for (Operation &op : block.without_terminator())
+        rewriter.clone(op, mapping);
+      auto yieldOp = cast<acc::YieldOp>(block.getTerminator());
+      Value result = mapping.lookup(yieldOp.getOperand(0));
       if (!ptrLikeType.genStore(rewriter, atomicUpdateOp.getLoc(),
-                                expr->getResult(0), xTyped)) {
+                                result, xTyped)) {
         accSupport.emitNYI(atomicUpdateOp.getLoc(),
                            "failed to generate store for atomic update");
         return failure();
diff --git a/mlir/test/Dialect/OpenACC/acc-specialize-for-host-fallback.mlir b/mlir/test/Dialect/OpenACC/acc-specialize-for-host-fallback.mlir
index 59269b71bf61c..1a02f9fd710db 100644
--- a/mlir/test/Dialect/OpenACC/acc-specialize-for-host-fallback.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-specialize-for-host-fallback.mlir
@@ -155,3 +155,66 @@ func.func @declare_enter_exit(%arg0 : memref<i32>) attributes {acc.routine_info
   acc.declare_exit token(%token) dataOperands(%0 : memref<i32>)
   return
 }
+
+//===----------------------------------------------------------------------===//
+// Atomic operations (host fallback)
+//===----------------------------------------------------------------------===//
+
+acc.routine @acc_routine_atomic_read func(@atomic_read) seq
+// CHECK-LABEL: func.func @atomic_read
+// CHECK-NOT:   acc.atomic
+// CHECK:       memref.load
+func.func @atomic_read(%src : memref<f64>, %dst : memref<f64>) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_atomic_read]>} {
+  acc.atomic.read %dst = %src : memref<f64>, memref<f64>, f64
+  return
+}
+
+acc.routine @acc_routine_atomic_write func(@atomic_write) seq
+// CHECK-LABEL: func.func @atomic_write
+// CHECK-NOT:   acc.atomic
+// CHECK:       memref.store
+func.func @atomic_write(%addr : memref<f64>) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_atomic_write]>} {
+  %val = arith.constant 5.0e-01 : f64
+  acc.atomic.write %addr = %val : memref<f64>, f64
+  return
+}
+
+acc.routine @acc_routine_atomic_update func(@atomic_update) seq
+// CHECK-LABEL: func.func @atomic_update
+// CHECK-NOT:   acc.atomic
+// CHECK:       arith.select
+func.func @atomic_update(%x : memref<f64>) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_atomic_update]>} {
+  %a = arith.constant 5.0e-01 : f64
+  acc.parallel {
+    acc.atomic.update %x : memref<f64> {
+    ^bb0(%arg0: f64):
+      %c = arith.cmpf ogt, %a, %arg0 fastmath<contract> : f64
+      %r = arith.select %c, %a, %arg0 : f64
+      acc.yield %r : f64
+    }
+    acc.terminator
+  }
+  return
+}
+
+acc.routine @acc_routine_atomic_capture func(@atomic_capture) seq
+// CHECK-LABEL: func.func @atomic_capture
+// CHECK-NOT:   acc.atomic
+// CHECK:       arith.select
+func.func @atomic_capture(%x : memref<f64>, %dst : memref<f64>) attributes {acc.routine_info = #acc.routine_info<[@acc_routine_atomic_capture]>} {
+  %a = arith.constant 5.0e-01 : f64
+  acc.parallel {
+    acc.atomic.capture {
+      acc.atomic.update %x : memref<f64> {
+      ^bb0(%arg0: f64):
+        %c = arith.cmpf ogt, %a, %arg0 fastmath<contract> : f64
+        %r = arith.select %c, %a, %arg0 : f64
+        acc.yield %r : f64
+      }
+      acc.atomic.read %dst = %x : memref<f64>, memref<f64>, f64
+      acc.terminator
+    }
+    acc.terminator
+  }
+  return
+}

``````````

</details>


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


More information about the Mlir-commits mailing list