[Mlir-commits] [mlir] [mlir][acc] Lower sequential acc.loop to scf.for in ACCComputeLowering (PR #206165)

Delaram Talaashrafi llvmlistbot at llvm.org
Fri Jun 26 13:07:11 PDT 2026


https://github.com/delaram-talaashrafi created https://github.com/llvm/llvm-project/pull/206165

Sequential loops already have fixed parallelism, so represent them with `scf.for` rather than `scf.parallel`. To prevent further analysis and parallelization, `parDimAttr` is set to seq.

>From 3f9673ed144d2458fd5e186d7925c8a45f31421d Mon Sep 17 00:00:00 2001
From: Delaram Talaashrafi <dtalaashrafi at rome5.pgi.net>
Date: Fri, 26 Jun 2026 13:01:59 -0700
Subject: [PATCH] [mlir][acc] Lower sequential acc.loop to scf.for in
 ACCComputeLowering

Sequential loops already have fixed parallelism, so represent them with
scf.for rather than scf.parallel. To prevent further analysis and parallelization,
parDimAttr is set to seq.
---
 .../OpenACC/Transforms/ACCComputeLowering.cpp     | 15 +++++++--------
 .../OpenACC/acc-compute-lowering-compute.mlir     |  8 ++++----
 .../OpenACC/acc-compute-lowering-loop.mlir        |  6 +++---
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
index cf9e80bd1a4d5..1c5f302f23192 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCComputeLowering.cpp
@@ -313,15 +313,14 @@ class ACCLoopConversion : public OpRewritePattern<LoopOp> {
     LoopParMode parMode = loopOp.getDefaultOrDeviceTypeParallelism(deviceType);
 
     if (parMode == LoopParMode::loop_seq || isOpInSerialRegion(loopOp)) {
-      // Although it might seem unintuitive, scf.parallel is used here because
-      // the parallelism of the loop is already predetermined (as sequential).
-      // scf.for will become a candidate for auto-parallelization analysis.
-      auto parallelOp = convertACCLoopToSCFParallel(loopOp, rewriter);
-      if (!parallelOp)
+      // Use scf.for with sequential loops, because the loop's parallelism is
+      // already determined.
+      auto forOp =
+          convertACCLoopToSCFFor(loopOp, rewriter, /*enableCollapse=*/true);
+      if (!forOp)
         return failure();
-      setParDimsAttr(parallelOp,
-                     GPUParallelDimsAttr::seq(loopOp->getContext()));
-      rewriter.replaceOp(loopOp, parallelOp);
+      setParDimsAttr(forOp, GPUParallelDimsAttr::seq(loopOp->getContext()));
+      rewriter.replaceOp(loopOp, forOp);
     } else if (parMode == LoopParMode::loop_auto) {
       // All loops in serial regions should have already been handled.
       assert(!isOpInSerialRegion(loopOp) &&
diff --git a/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir b/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
index c2049dab676e3..c511d3e4270d1 100644
--- a/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-compute-lowering-compute.mlir
@@ -39,7 +39,7 @@ func.func @parallel_seq_loop(%buf: memref<4xi32>) {
   // CHECK: acc.kernel_environment
   // CHECK: acc.par_width {{.*}} {par_dim = #acc.par_dim<block_x>}
   // CHECK: acc.compute_region launch(
-  // CHECK: scf.parallel
+  // CHECK: scf.for
   // CHECK: acc.par_dims = #acc<par_dims[sequential]>
   acc.parallel num_gangs({%c10_i32 : i32}) dataOperands(%dev : memref<4xi32>) {
     acc.loop control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
@@ -66,7 +66,7 @@ func.func @serial_loop(%buf: memref<4xi32>) {
   // CHECK: acc.kernel_environment
   // CHECK: acc.par_width {par_dim = #acc.par_dim<sequential>}
   // CHECK: acc.compute_region launch(
-  // CHECK: scf.parallel
+  // CHECK: scf.for
   // CHECK: acc.par_dims = #acc<par_dims[sequential]>
   acc.serial dataOperands(%dev : memref<4xi32>) {
     acc.loop control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
@@ -150,7 +150,7 @@ func.func @parallel_unit_launch_serial_loops(%buf: memref<4xi32>) {
   // CHECK: acc.kernel_environment
   // CHECK: acc.par_width {par_dim = #acc.par_dim<sequential>}
   // CHECK: acc.compute_region launch(
-  // CHECK: scf.parallel
+  // CHECK: scf.for
   // CHECK: acc.par_dims = #acc<par_dims[sequential]>
   acc.parallel num_gangs({%c1_i32 : i32}) num_workers(%c1_i32 : i32) vector_length(%c1_i32 : i32) dataOperands(%dev : memref<4xi32>) {
     acc.loop control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
@@ -182,7 +182,7 @@ func.func @kernels_unit_launch_serial_loops(%buf: memref<4xi32>) {
   // CHECK: acc.kernel_environment
   // CHECK: acc.par_width {par_dim = #acc.par_dim<sequential>}
   // CHECK: acc.compute_region launch(
-  // CHECK: scf.parallel
+  // CHECK: scf.for
   // CHECK: acc.par_dims = #acc<par_dims[sequential]>
   acc.kernels num_gangs({%c1_i32 : i32}) num_workers(%c1_i32 : i32) vector_length(%c1_i32 : i32) dataOperands(%dev : memref<4xi32>) {
     acc.loop control(%i : index) = (%c0 : index) to (%c4 : index) step (%c1 : index) {
diff --git a/mlir/test/Dialect/OpenACC/acc-compute-lowering-loop.mlir b/mlir/test/Dialect/OpenACC/acc-compute-lowering-loop.mlir
index 2f9276e8525bb..0207157383c49 100644
--- a/mlir/test/Dialect/OpenACC/acc-compute-lowering-loop.mlir
+++ b/mlir/test/Dialect/OpenACC/acc-compute-lowering-loop.mlir
@@ -95,7 +95,7 @@ func.func @serial_loop_normalized(%buf: memref<1xi32>) {
   // CHECK: acc.kernel_environment
   // CHECK: acc.par_width {par_dim = #acc.par_dim<sequential>}
   // CHECK: acc.compute_region launch(
-  // CHECK: scf.parallel
+  // CHECK: scf.for
   // CHECK-DAG: arith.muli
   // CHECK-DAG: arith.addi
   // CHECK: acc.par_dims = #acc<par_dims[sequential]>
@@ -137,9 +137,9 @@ acc.routine @routine_with_loop func(@device_routine_with_loop) seq
 // CHECK-LABEL: func.func @device_routine_with_loop
 // CHECK: attributes {acc.specialized_routine = #acc.specialized_routine<@routine_with_loop, <seq>, "host_routine_with_loop">}
 // CHECK-NOT: acc.loop
-// CHECK: scf.parallel
+// CHECK: scf.for
 // CHECK: acc.par_dims = #acc<par_dims[sequential]>
-// CHECK-NOT: scf.for
+// CHECK-NOT: scf.parallel
 func.func @device_routine_with_loop(%buf: memref<8xi32>) attributes {acc.specialized_routine = #acc.specialized_routine<@routine_with_loop, <seq>, "host_routine_with_loop">} {
   %c0 = arith.constant 0 : index
   %c1 = arith.constant 1 : index



More information about the Mlir-commits mailing list