[Mlir-commits] [mlir] 2a577a4 - [mlir][acc] Add operation for private handle to memref (#201603)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Thu Jun 4 09:24:28 PDT 2026


Author: Razvan Lupusoru
Date: 2026-06-04T09:24:24-07:00
New Revision: 2a577a44a35975f1ac25096861ab87e4c5ad9ddd

URL: https://github.com/llvm/llvm-project/commit/2a577a44a35975f1ac25096861ab87e4c5ad9ddd
DIFF: https://github.com/llvm/llvm-project/commit/2a577a44a35975f1ac25096861ab87e4c5ad9ddd.diff

LOG: [mlir][acc] Add operation for private handle to memref (#201603)

This MR introduces a new operation `acc.unwrap_private` for creating a
pointer-like view of the `acc.private_type` handle. This operation will
be used when materializing `acc.private_local` into the memory view
needed to access the allocated private memory. This new operation is
just a simple cast and thus it gets ViewLikeOpInterface attached to it.

Additionally, `acc.private_type` is now treated as a pointer-like type
to ease conversions to other pointer-like types via
PointerLikeType::genCast.

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/OpenACC/OpenACC.h
    mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
    mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
    mlir/test/Dialect/OpenACC/ops-cg-privatization.mlir
    mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
index 682e8ff9784c8..d5cd04949c751 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACC.h
@@ -32,6 +32,7 @@
 #include "mlir/Interfaces/ControlFlowInterfaces.h"
 #include "mlir/Interfaces/LoopLikeInterface.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "mlir/Interfaces/ViewLikeInterface.h"
 #include <variant>
 
 #define GET_TYPEDEF_CLASSES

diff  --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
index 9bca3b36c9785..13969f9fc9c65 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCCGOps.td
@@ -17,6 +17,7 @@
 #define OPENACC_CG_OPS
 
 include "mlir/Interfaces/InferTypeOpInterface.td"
+include "mlir/Interfaces/ViewLikeInterface.td"
 
 // This file is intended to be included from OpenACCOps.td, which provides
 // the necessary includes and definitions. The operations defined here use
@@ -253,6 +254,28 @@ def OpenACC_PrivatizeOp : OpenACC_Op<"privatize", []> {
   ];
 }
 
+//===----------------------------------------------------------------------===//
+// acc.unwrap_private
+//===----------------------------------------------------------------------===//
+
+def OpenACC_UnwrapPrivateOp
+    : OpenACC_Op<"unwrap_private",
+                 [NoMemoryEffect, AlwaysSpeculatable, ViewLikeOpInterface]> {
+  let summary = "Unwrap acc.private_type handle to pointer-like storage";
+  let description = [{
+    Converts a privatization handle (`acc.private_type<T>`) to a pointer-like
+    view of the underlying private storage.
+  }];
+  let arguments = (ins OpenACC_PrivateType:$handle);
+  let results = (outs OpenACC_PointerLikeType:$result);
+  let assemblyFormat = [{
+    $handle attr-dict `:` qualified(type($handle)) `to` type($result)
+  }];
+  let extraClassDeclaration = [{
+    ::mlir::Value getViewSource() { return getHandle(); }
+  }];
+}
+
 //===----------------------------------------------------------------------===//
 // acc.private_local
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index f5ad1867086b6..ec8bac765ed33 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -346,6 +346,23 @@ struct LLVMPointerPointerLikeModel
   }
 };
 
+struct PrivateTypePointerLikeModel
+    : public PointerLikeType::ExternalModel<PrivateTypePointerLikeModel,
+                                            PrivateType> {
+  Type getElementType(Type type) const {
+    return cast<PrivateType>(type).getBaseTy();
+  }
+
+  Value genCast(Type, OpBuilder &builder, Location loc, Value value,
+                Type resultType) const {
+    if (value.getType() == resultType)
+      return value;
+    if (!isa<PointerLikeType>(resultType))
+      return {};
+    return UnwrapPrivateOp::create(builder, loc, resultType, value).getResult();
+  }
+};
+
 struct MemrefAddressOfGlobalModel
     : public AddressOfGlobalOpInterface::ExternalModel<
           MemrefAddressOfGlobalModel, memref::GetGlobalOp> {
@@ -474,6 +491,7 @@ void OpenACCDialect::initialize() {
       MemRefPointerLikeModel<UnrankedMemRefType>>(*getContext());
   LLVM::LLVMPointerType::attachInterface<LLVMPointerPointerLikeModel>(
       *getContext());
+  PrivateType::attachInterface<PrivateTypePointerLikeModel>(*getContext());
 
   // Attach operation interfaces
   memref::GetGlobalOp::attachInterface<MemrefAddressOfGlobalModel>(

diff  --git a/mlir/test/Dialect/OpenACC/ops-cg-privatization.mlir b/mlir/test/Dialect/OpenACC/ops-cg-privatization.mlir
index 206466e94abd7..2b0af1527a984 100644
--- a/mlir/test/Dialect/OpenACC/ops-cg-privatization.mlir
+++ b/mlir/test/Dialect/OpenACC/ops-cg-privatization.mlir
@@ -1,5 +1,7 @@
 // RUN: mlir-opt -split-input-file %s | FileCheck %s --check-prefixes=CHECK
+// Verify the printed output can be parsed.
 // RUN: mlir-opt -split-input-file %s | mlir-opt -split-input-file | FileCheck %s --check-prefixes=CHECK
+// Verify the generic form can be parsed.
 // RUN: mlir-opt -split-input-file -mlir-print-op-generic %s | mlir-opt -split-input-file | FileCheck %s --check-prefixes=CHECK
 
 // -----
@@ -114,3 +116,28 @@ func.func @privatize_inside_compute_region(%data : memref<64xf32>) {
 // CHECK: acc.private_local
 // CHECK: memref.load %{{.*}}[%{{.*}}] : memref<64xf32>
 // CHECK: } {origin = "acc.parallel"}
+
+// -----
+
+// CHECK-LABEL: func @unwrap_private_to_memref
+func.func @unwrap_private_to_memref() {
+  %h = acc.privatize : () -> !acc.private_type<memref<i32>>
+  %m = acc.unwrap_private %h : !acc.private_type<memref<i32>> to memref<i32>
+  %z = arith.constant 0 : i32
+  memref.store %z, %m[] : memref<i32>
+  return
+}
+// CHECK-DAG: %[[H:.*]] = acc.privatize
+// CHECK-SAME: () -> !acc.private_type<memref<i32>>
+// CHECK: %{{.*}} = acc.unwrap_private %[[H]]
+// CHECK-SAME: !acc.private_type<memref<i32>> to memref<i32>
+
+// -----
+
+// CHECK-LABEL: func @unwrap_private_to_byte_memref
+func.func @unwrap_private_to_byte_memref() {
+  %h = acc.privatize : () -> !acc.private_type<memref<f64>>
+  %storage = acc.unwrap_private %h : !acc.private_type<memref<f64>> to memref<?xi8>
+  return
+}
+// CHECK: acc.unwrap_private %{{.*}} : !acc.private_type<memref<f64>> to memref<?xi8>

diff  --git a/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp b/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
index 0d5419203dbbe..9e9b05e969211 100644
--- a/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
+++ b/mlir/unittests/Dialect/OpenACC/OpenACCTypeInterfacesTest.cpp
@@ -256,3 +256,24 @@ TEST_F(OpenACCTypeInterfacesTest, PointerLikeGenCastLLVMIntToPtrFromIndex) {
   ASSERT_TRUE(intToPtr);
   EXPECT_TRUE(isa<arith::IndexCastUIOp>(intToPtr.getArg().getDefiningOp()));
 }
+
+TEST_F(OpenACCTypeInterfacesTest, PointerLikeGenCastPrivateTypeToMemref) {
+  Location loc = UnknownLoc::get(&context);
+  OwningOpRef<ModuleOp> module = ModuleOp::create(loc);
+  OpBuilder builder(module->getBodyRegion());
+  func::FuncOp fn = func::FuncOp::create(builder, loc, "cast_private_to_memref",
+                                         builder.getFunctionType({}, {}));
+  Block *block = fn.addEntryBlock();
+  builder.setInsertionPointToStart(block);
+
+  Type privateTy = PrivateType::get(&context, builder.getI8Type());
+  Type memrefTy = MemRefType::get({ShapedType::kDynamic}, builder.getI8Type());
+  Value handle = UndefOp::create(builder, loc, privateTy);
+  auto ptrLike = cast<PointerLikeType>(privateTy);
+  Value out = ptrLike.genCast(builder, loc, handle, memrefTy);
+  ASSERT_TRUE(out);
+  EXPECT_EQ(out.getType(), memrefTy);
+  auto unwrap = dyn_cast<UnwrapPrivateOp>(out.getDefiningOp());
+  ASSERT_TRUE(unwrap);
+  EXPECT_EQ(unwrap.getHandle(), handle);
+}


        


More information about the Mlir-commits mailing list