[Mlir-commits] [mlir] [mlir][OpenACC] Fold constant-false host_data with an empty region (PR #236052)

Akshay Khadse llvmlistbot at llvm.org
Wed Oct 28 03:38:39 PDT 2026


https://github.com/akshaykhadse updated https://github.com/llvm/llvm-project/pull/236052

>From c14b899e58fc5010eaf97035b1a47b10bbceed37 Mon Sep 17 00:00:00 2001
From: akshaykhadse <akshayskhadse at gmail.com>
Date: Fri, 23 Oct 2026 20:22:15 -0400
Subject: [PATCH] [mlir][OpenACC] Fold constant-false host_data with an empty
 region

RemoveConstantIfConditionWithRegion replaces a construct whose `if`
condition is constant false with the contents of its region. The helper
it uses asserts that the region has exactly one block, but acc.host_data
accepts an empty region, so canonicalizing such an op crashed.

An empty region has no body to inline, so erase the op in that case,
matching the result for a non-empty region. Bail out on multi-block
regions instead of asserting.

Fixes #231828
---
 mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp     | 20 +++++++++++++++++---
 mlir/test/Dialect/OpenACC/canonicalize.mlir | 17 +++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 69c0baef8918b..8462e6e3bc98f 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -1367,11 +1367,25 @@ struct RemoveConstantIfConditionWithRegion : public OpRewritePattern<OpTy> {
     IntegerAttr constAttr;
     if (!matchPattern(ifCond, m_Constant(&constAttr)))
       return failure();
-    if (constAttr.getInt())
+    if (constAttr.getInt()) {
       rewriter.modifyOpInPlace(op, [&]() { op.getIfCondMutable().erase(0); });
-    else
-      replaceOpWithRegion(rewriter, op, op.getRegion());
+      return success();
+    }
+
+    // With a constant false condition the construct has no effect, so it is
+    // replaced by its body. An empty region has no body, so the op is simply
+    // erased.
+    Region &region = op.getRegion();
+    if (region.empty()) {
+      if (op->getNumResults() != 0)
+        return rewriter.notifyMatchFailure(op, "empty region with results");
+      rewriter.eraseOp(op);
+      return success();
+    }
+    if (!region.hasOneBlock())
+      return rewriter.notifyMatchFailure(op, "expected single-block region");
 
+    replaceOpWithRegion(rewriter, op, region);
     return success();
   }
 };
diff --git a/mlir/test/Dialect/OpenACC/canonicalize.mlir b/mlir/test/Dialect/OpenACC/canonicalize.mlir
index c7b03b3e6a044..bf53595d62c25 100644
--- a/mlir/test/Dialect/OpenACC/canonicalize.mlir
+++ b/mlir/test/Dialect/OpenACC/canonicalize.mlir
@@ -147,6 +147,23 @@ func.func @testhostdataop(%a: memref<f32>, %ifCond: i1) -> () {
 
 // -----
 
+// A constant false condition removes the construct even when its region is
+// empty.
+
+func.func @testhostdataop_empty_region(%a: memref<f32>) -> () {
+  %0 = acc.use_device varPtr(%a : memref<f32>) -> memref<f32>
+  %false = arith.constant false
+  acc.host_data dataOperands(%0 : memref<f32>) if(%false) {
+  }
+  return
+}
+
+// CHECK-LABEL: func.func @testhostdataop_empty_region
+// CHECK-NOT: acc.host_data
+// CHECK: return
+
+// -----
+
 func.func @update_no_op(%x : memref<i32>) {
   acc.atomic.update %x : memref<i32> {
   ^bb0(%xval : i32):



More information about the Mlir-commits mailing list