[Mlir-commits] [mlir] 4f638ff - [mlir][acc] Drop redundant `acc.terminator` erase that broke atomic capture under `if` (#205731)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Jun 25 09:23:23 PDT 2026


Author: khaki3
Date: 2026-06-25T09:23:18-07:00
New Revision: 4f638ff7baf97dd16abff7fc961d76c22063dc1f

URL: https://github.com/llvm/llvm-project/commit/4f638ff7baf97dd16abff7fc961d76c22063dc1f
DIFF: https://github.com/llvm/llvm-project/commit/4f638ff7baf97dd16abff7fc961d76c22063dc1f.diff

LOG: [mlir][acc] Drop redundant `acc.terminator` erase that broke atomic capture under `if` (#205731)

Example:
```fortran
!$acc parallel if(cond)
!$acc atomic capture
  a = a + 1
  b = a
!$acc end atomic
!$acc end parallel
```

In this code, the `if` clause triggers host-fallback specialization. A
blanket `acc.terminator` erase pattern strips the implicit terminator of
the still-present `acc.atomic.capture`, so the later `getTerminator()`
trips `mightHaveTerminator()`.

Fix: remove that pattern — every ACC region op already erases its own
terminator when it unwraps/inlines, so it was redundant (and only raced
ahead to break this case). Adds a lit test.

Added: 
    

Modified: 
    mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
    mlir/test/Dialect/OpenACC/acc-if-clause-lowering.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
index ccfd3ef84b2e7..d3c8b683b76cb 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCSpecializeForHost.cpp
@@ -464,8 +464,8 @@ void mlir::acc::populateACCHostFallbackPatterns(RewritePatternSet &patterns,
   // Runtime operations - erase them
   patterns.insert<
       ACCOpEraseConversion<acc::InitOp>, ACCOpEraseConversion<acc::ShutdownOp>,
-      ACCOpEraseConversion<acc::SetOp>, ACCOpEraseConversion<acc::WaitOp>,
-      ACCOpEraseConversion<acc::TerminatorOp>>(context);
+      ACCOpEraseConversion<acc::SetOp>, ACCOpEraseConversion<acc::WaitOp>>(
+      context);
 
   // Compute constructs - unwrap their regions
   patterns.insert<ACCRegionUnwrapConversion<acc::ParallelOp>,

diff  --git a/mlir/test/Dialect/OpenACC/acc-if-clause-lowering.mlir b/mlir/test/Dialect/OpenACC/acc-if-clause-lowering.mlir
index 4c88df432b6c7..af4cc72a42645 100644
--- a/mlir/test/Dialect/OpenACC/acc-if-clause-lowering.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-if-clause-lowering.mlir
@@ -373,4 +373,36 @@ func.func @test_acc_private(%arg0: memref<i32>, %cond: i1) {
     acc.yield
   }
   return
-}
\ No newline at end of file
+}
+
+// -----
+
+// Test that an acc.parallel with an if clause whose body holds an
+// acc.atomic.capture lowers cleanly: the device path keeps the capture and the
+// host fallback inlines it.
+// CHECK-LABEL: func.func @test_parallel_if_atomic_capture
+func.func @test_parallel_if_atomic_capture(%x: memref<i32>, %v: memref<i32>, %cond: i1) {
+  %c1_i32 = arith.constant 1 : i32
+  // CHECK-NOT: acc.parallel if
+  // CHECK: scf.if %{{.*}} {
+  // CHECK:   acc.parallel {
+  // CHECK:     acc.atomic.capture {
+  // CHECK:   } else {
+  // CHECK-NOT: acc.atomic.capture
+  // CHECK:     memref.load
+  // CHECK:     arith.addi
+  // CHECK:     memref.store
+  // CHECK:   }
+  acc.parallel if(%cond) {
+    acc.atomic.capture {
+      acc.atomic.update %x : memref<i32> {
+      ^bb0(%arg: i32):
+        %r = arith.addi %arg, %c1_i32 : i32
+        acc.yield %r : i32
+      }
+      acc.atomic.read %v = %x : memref<i32>, memref<i32>, i32
+    }
+    acc.yield
+  }
+  return
+}


        


More information about the Mlir-commits mailing list