-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[acc][flang] Add genLoad and genStore to PointerLikeType #170348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This patch extends the OpenACC PointerLikeType interface with two new methods for generating load and store operations, enabling dialect-agnostic memory access patterns. New Interface Methods: - genLoad(builder, loc, srcPtr, valueType): Generates a load operation from a pointer-like value. Returns the loaded value. - genStore(builder, loc, valueToStore, destPtr): Generates a store operation to a pointer-like value. Implementations provided for FIR pointer-like types, memref type (rank-0 only), and LLVM pointer types. Extended TestPointerLikeTypeInterface.cpp with 'load' and 'store' test modes.
|
@llvm/pr-subscribers-mlir @llvm/pr-subscribers-flang-fir-hlfir Author: Razvan Lupusoru (razvanlupusoru) ChangesThis patch extends the OpenACC PointerLikeType interface with two new methods for generating load and store operations, enabling dialect-agnostic memory access patterns. New Interface Methods:
Implementations provided for FIR pointer-like types, memref type (rank-0 only), and LLVM pointer types. Extended TestPointerLikeTypeInterface.cpp with 'load' and 'store' test modes. Patch is 25.26 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/170348.diff 9 Files Affected:
diff --git a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
index 3167c554abbdd..38150b294f4e1 100644
--- a/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
+++ b/flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h
@@ -43,6 +43,15 @@ struct OpenACCPointerLikeModel
mlir::TypedValue<mlir::acc::PointerLikeType> destination,
mlir::TypedValue<mlir::acc::PointerLikeType> source,
mlir::Type varType) const;
+
+ mlir::Value genLoad(mlir::Type pointer, mlir::OpBuilder &builder,
+ mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const;
+
+ bool genStore(mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const;
};
template <typename T>
diff --git a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
index ae0f5fb8197fa..a6109c3a04010 100644
--- a/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
+++ b/flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
@@ -1014,4 +1014,116 @@ template bool OpenACCPointerLikeModel<fir::LLVMPointerType>::genCopy(
mlir::TypedValue<mlir::acc::PointerLikeType> source,
mlir::Type varType) const;
+template <typename Ty>
+mlir::Value OpenACCPointerLikeModel<Ty>::genLoad(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const {
+
+ // Unwrap to get the pointee type.
+ mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy(pointer);
+ assert(pointeeTy && "expected pointee type to be extractable");
+
+ // Box types contain both a descriptor and referenced data. The genLoad API
+ // handles simple loads and cannot properly manage both parts.
+ if (fir::isa_box_type(pointeeTy))
+ return {};
+
+ // Unlimited polymorphic (class(*)) cannot be handled because type is unknown.
+ if (fir::isUnlimitedPolymorphicType(pointeeTy))
+ return {};
+
+ // Return empty for dynamic size types because the load logic
+ // cannot be determined simply from the type.
+ if (fir::hasDynamicSize(pointeeTy))
+ return {};
+
+ mlir::Value loadedValue = fir::LoadOp::create(builder, loc, srcPtr);
+
+ // If valueType is provided and differs from the loaded type, insert a convert
+ if (valueType && loadedValue.getType() != valueType) {
+ return fir::ConvertOp::create(builder, loc, valueType, loadedValue);
+ }
+
+ return loadedValue;
+}
+
+template mlir::Value OpenACCPointerLikeModel<fir::ReferenceType>::genLoad(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const;
+
+template mlir::Value OpenACCPointerLikeModel<fir::PointerType>::genLoad(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const;
+
+template mlir::Value OpenACCPointerLikeModel<fir::HeapType>::genLoad(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const;
+
+template mlir::Value OpenACCPointerLikeModel<fir::LLVMPointerType>::genLoad(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::TypedValue<mlir::acc::PointerLikeType> srcPtr,
+ mlir::Type valueType) const;
+
+template <typename Ty>
+bool OpenACCPointerLikeModel<Ty>::genStore(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const {
+
+ // Unwrap to get the pointee type.
+ mlir::Type pointeeTy = fir::dyn_cast_ptrEleTy(pointer);
+ assert(pointeeTy && "expected pointee type to be extractable");
+
+ // Box types contain both a descriptor and referenced data. The genStore API
+ // handles simple stores and cannot properly manage both parts.
+ if (fir::isa_box_type(pointeeTy))
+ return false;
+
+ // Unlimited polymorphic (class(*)) cannot be handled because type is unknown.
+ if (fir::isUnlimitedPolymorphicType(pointeeTy))
+ return false;
+
+ // Return false for dynamic size types because the store logic
+ // cannot be determined simply from the type.
+ if (fir::hasDynamicSize(pointeeTy))
+ return false;
+
+ // Get the type from the value being stored
+ mlir::Type valueType = valueToStore.getType();
+ mlir::Value convertedValue = valueToStore;
+
+ // If the value type differs from the pointee type, insert a convert
+ if (valueType != pointeeTy) {
+ convertedValue =
+ fir::ConvertOp::create(builder, loc, pointeeTy, valueToStore);
+ }
+
+ fir::StoreOp::create(builder, loc, convertedValue, destPtr);
+ return true;
+}
+
+template bool OpenACCPointerLikeModel<fir::ReferenceType>::genStore(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const;
+
+template bool OpenACCPointerLikeModel<fir::PointerType>::genStore(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const;
+
+template bool OpenACCPointerLikeModel<fir::HeapType>::genStore(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const;
+
+template bool OpenACCPointerLikeModel<fir::LLVMPointerType>::genStore(
+ mlir::Type pointer, mlir::OpBuilder &builder, mlir::Location loc,
+ mlir::Value valueToStore,
+ mlir::TypedValue<mlir::acc::PointerLikeType> destPtr) const;
+
} // namespace fir::acc
diff --git a/flang/test/Fir/OpenACC/pointer-like-interface-load.mlir b/flang/test/Fir/OpenACC/pointer-like-interface-load.mlir
new file mode 100644
index 0000000000000..79a944280445f
--- /dev/null
+++ b/flang/test/Fir/OpenACC/pointer-like-interface-load.mlir
@@ -0,0 +1,85 @@
+// RUN: fir-opt %s --split-input-file --pass-pipeline="builtin.module(func.func(test-acc-pointer-like-interface{test-mode=load}))" 2>&1 | FileCheck %s
+
+func.func @test_load_scalar_f32() {
+ %ptr = fir.alloca f32 {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.alloca f32 {test.ptr}
+ // CHECK: Loaded value type: f32
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.ref<f32>
+ return
+}
+
+// -----
+
+func.func @test_load_scalar_i32() {
+ %ptr = fir.alloca i32 {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.alloca i32 {test.ptr}
+ // CHECK: Loaded value type: i32
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.ref<i32>
+ return
+}
+
+// -----
+
+func.func @test_load_scalar_i64() {
+ %ptr = fir.alloca i64 {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.alloca i64 {test.ptr}
+ // CHECK: Loaded value type: i64
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.ref<i64>
+ return
+}
+
+// -----
+
+func.func @test_load_heap_scalar() {
+ %ptr = fir.allocmem f64 {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.allocmem f64 {test.ptr}
+ // CHECK: Loaded value type: f64
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.heap<f64>
+ return
+}
+
+// -----
+
+func.func @test_load_logical() {
+ %ptr = fir.alloca !fir.logical<4> {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.alloca !fir.logical<4> {test.ptr}
+ // CHECK: Loaded value type: !fir.logical<4>
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.ref<!fir.logical<4>>
+ return
+}
+
+// -----
+
+func.func @test_load_derived_type() {
+ %ptr = fir.alloca !fir.type<_QTt{i:i32}> {test.ptr}
+ // CHECK: Successfully generated load for operation: %{{.*}} = fir.alloca !fir.type<_QTt{i:i32}> {test.ptr}
+ // CHECK: Loaded value type: !fir.type<_QTt{i:i32}>
+ // CHECK: Generated: %{{.*}} = fir.load %{{.*}} : !fir.ref<!fir.type<_QTt{i:i32}>>
+ return
+}
+
+// -----
+
+func.func @test_load_dynamic_array_fails() {
+ %c10 = arith.constant 10 : index
+ %ptr = fir.alloca !fir.array<?xf32>, %c10 {test.ptr}
+ // CHECK: Failed to generate load for operation: %{{.*}} = fir.alloca !fir.array<?xf32>
+ return
+}
+
+// -----
+
+func.func @test_load_box_fails() {
+ %ptr = fir.alloca !fir.box<!fir.ptr<f32>> {test.ptr}
+ // CHECK: Failed to generate load for operation: %{{.*}} = fir.alloca !fir.box<!fir.ptr<f32>>
+ return
+}
+
+// -----
+
+func.func @test_load_unlimited_polymorphic_fails() {
+ %ptr = fir.alloca !fir.class<none> {test.ptr}
+ // CHECK: Failed to generate load for operation: %{{.*}} = fir.alloca !fir.class<none>
+ return
+}
+
diff --git a/flang/test/Fir/OpenACC/pointer-like-interface-store.mlir b/flang/test/Fir/OpenACC/pointer-like-interface-store.mlir
new file mode 100644
index 0000000000000..6306bf1cf6cee
--- /dev/null
+++ b/flang/test/Fir/OpenACC/pointer-like-interface-store.mlir
@@ -0,0 +1,75 @@
+// RUN: fir-opt %s --split-input-file --pass-pipeline="builtin.module(func.func(test-acc-pointer-like-interface{test-mode=store}))" 2>&1 | FileCheck %s
+
+func.func @test_store_scalar_f32() {
+ %ptr = fir.alloca f32 {test.ptr}
+ // CHECK: Successfully generated store for operation: %{{.*}} = fir.alloca f32 {test.ptr}
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 4.200000e+01 : f32
+ // CHECK: Generated: fir.store %[[VAL]] to %{{.*}} : !fir.ref<f32>
+ return
+}
+
+// -----
+
+func.func @test_store_scalar_i32() {
+ %ptr = fir.alloca i32 {test.ptr}
+ // CHECK: Successfully generated store for operation: %{{.*}} = fir.alloca i32 {test.ptr}
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 42 : i32
+ // CHECK: Generated: fir.store %[[VAL]] to %{{.*}} : !fir.ref<i32>
+ return
+}
+
+// -----
+
+func.func @test_store_scalar_i64() {
+ %ptr = fir.alloca i64 {test.ptr}
+ // CHECK: Successfully generated store for operation: %{{.*}} = fir.alloca i64 {test.ptr}
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 42 : i64
+ // CHECK: Generated: fir.store %[[VAL]] to %{{.*}} : !fir.ref<i64>
+ return
+}
+
+// -----
+
+func.func @test_store_heap_scalar() {
+ %ptr = fir.allocmem f64 {test.ptr}
+ // CHECK: Successfully generated store for operation: %{{.*}} = fir.allocmem f64 {test.ptr}
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 4.200000e+01 : f64
+ // CHECK: Generated: fir.store %[[VAL]] to %{{.*}} : !fir.heap<f64>
+ return
+}
+
+// -----
+
+func.func @test_store_with_type_conversion() {
+ %ptr = fir.alloca i32 {test.ptr}
+ // CHECK: Successfully generated store for operation: %{{.*}} = fir.alloca i32 {test.ptr}
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 42 : i32
+ // CHECK: Generated: fir.store %[[VAL]] to %{{.*}} : !fir.ref<i32>
+ return
+}
+
+// -----
+
+func.func @test_store_dynamic_array_fails() {
+ %c10 = arith.constant 10 : index
+ %ptr = fir.alloca !fir.array<?xf32>, %c10 {test.ptr}
+ // CHECK: Failed to generate store for operation: %{{.*}} = fir.alloca !fir.array<?xf32>
+ return
+}
+
+// -----
+
+func.func @test_store_box_fails() {
+ %ptr = fir.alloca !fir.box<!fir.ptr<f32>> {test.ptr}
+ // CHECK: Failed to generate store for operation: %{{.*}} = fir.alloca !fir.box<!fir.ptr<f32>>
+ return
+}
+
+// -----
+
+func.func @test_store_unlimited_polymorphic_fails() {
+ %ptr = fir.alloca !fir.class<none> {test.ptr}
+ // CHECK: Failed to generate store for operation: %{{.*}} = fir.alloca !fir.class<none>
+ return
+}
+
diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
index d1bbc7f206ce6..3f11bf6fbfce3 100644
--- a/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
+++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td
@@ -176,6 +176,50 @@ def OpenACC_PointerLikeTypeInterface : TypeInterface<"PointerLikeType"> {
return false;
}]
>,
+ InterfaceMethod<
+ /*description=*/[{
+ Generates a load operation from the pointer-like type. This dereferences
+ the pointer and returns the loaded value.
+
+ The `srcPtr` parameter is the pointer to load from. If the current type is
+ represented in a way that it does not capture the pointee type, `valueType`
+ must be passed in to provide the necessary type information.
+
+ Returns the loaded value, or an empty Value if load generation failed.
+ }],
+ /*retTy=*/"::mlir::Value",
+ /*methodName=*/"genLoad",
+ /*args=*/(ins "::mlir::OpBuilder &":$builder,
+ "::mlir::Location":$loc,
+ "::mlir::TypedValue<::mlir::acc::PointerLikeType>":$srcPtr,
+ "::mlir::Type":$valueType),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return {};
+ }]
+ >,
+ InterfaceMethod<
+ /*description=*/[{
+ Generates a store operation to the pointer-like type. This stores a value
+ to the memory location pointed to by the pointer.
+
+ The `destPtr` parameter is the pointer to store to. The `valueToStore`
+ parameter is the value to be stored. The type information is derived from
+ the valueToStore parameter itself.
+
+ Returns true if store was successfully generated, false otherwise.
+ }],
+ /*retTy=*/"bool",
+ /*methodName=*/"genStore",
+ /*args=*/(ins "::mlir::OpBuilder &":$builder,
+ "::mlir::Location":$loc,
+ "::mlir::Value":$valueToStore,
+ "::mlir::TypedValue<::mlir::acc::PointerLikeType>":$destPtr),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/[{
+ return false;
+ }]
+ >,
];
}
diff --git a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
index 841d1d781f1a1..3369cc7a3535b 100644
--- a/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
+++ b/mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp
@@ -203,12 +203,68 @@ struct MemRefPointerLikeModel
return false;
}
+
+ mlir::Value genLoad(Type pointer, OpBuilder &builder, Location loc,
+ TypedValue<PointerLikeType> srcPtr,
+ Type valueType) const {
+ // Load from a memref - only valid for scalar memrefs (rank 0).
+ // This is because the address computation for memrefs is part of the load
+ // (and not computed separately), but the API does not have arguments for
+ // indexing.
+ auto memrefValue = dyn_cast_if_present<TypedValue<MemRefType>>(srcPtr);
+ if (!memrefValue)
+ return {};
+
+ auto memrefTy = memrefValue.getType();
+
+ // Only load from scalar memrefs (rank 0)
+ if (memrefTy.getRank() != 0)
+ return {};
+
+ return memref::LoadOp::create(builder, loc, memrefValue);
+ }
+
+ bool genStore(Type pointer, OpBuilder &builder, Location loc,
+ Value valueToStore, TypedValue<PointerLikeType> destPtr) const {
+ // Store to a memref - only valid for scalar memrefs (rank 0)
+ // This is because the address computation for memrefs is part of the store
+ // (and not computed separately), but the API does not have arguments for
+ // indexing.
+ auto memrefValue = dyn_cast_if_present<TypedValue<MemRefType>>(destPtr);
+ if (!memrefValue)
+ return false;
+
+ auto memrefTy = memrefValue.getType();
+
+ // Only store to scalar memrefs (rank 0)
+ if (memrefTy.getRank() != 0)
+ return false;
+
+ memref::StoreOp::create(builder, loc, valueToStore, memrefValue);
+ return true;
+ }
};
struct LLVMPointerPointerLikeModel
: public PointerLikeType::ExternalModel<LLVMPointerPointerLikeModel,
LLVM::LLVMPointerType> {
Type getElementType(Type pointer) const { return Type(); }
+
+ mlir::Value genLoad(Type pointer, OpBuilder &builder, Location loc,
+ TypedValue<PointerLikeType> srcPtr,
+ Type valueType) const {
+ // For LLVM pointers, we need the valueType to determine what to load
+ if (!valueType)
+ return {};
+
+ return LLVM::LoadOp::create(builder, loc, valueType, srcPtr);
+ }
+
+ bool genStore(Type pointer, OpBuilder &builder, Location loc,
+ Value valueToStore, TypedValue<PointerLikeType> destPtr) const {
+ LLVM::StoreOp::create(builder, loc, valueToStore, destPtr);
+ return true;
+ }
};
struct MemrefAddressOfGlobalModel
diff --git a/mlir/test/Dialect/OpenACC/pointer-like-interface-load.mlir b/mlir/test/Dialect/OpenACC/pointer-like-interface-load.mlir
new file mode 100644
index 0000000000000..36df6a1d1bbe3
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/pointer-like-interface-load.mlir
@@ -0,0 +1,29 @@
+// RUN: mlir-opt %s --split-input-file --pass-pipeline="builtin.module(func.func(test-acc-pointer-like-interface{test-mode=load}))" 2>&1 | FileCheck %s
+
+func.func @test_memref_load_scalar() {
+ %ptr = memref.alloca() {test.ptr} : memref<f32>
+ // CHECK: Successfully generated load for operation: %[[PTR:.*]] = memref.alloca() {test.ptr} : memref<f32>
+ // CHECK: Loaded value type: f32
+ // CHECK: Generated: %{{.*}} = memref.load %[[PTR]][] : memref<f32>
+ return
+}
+
+// -----
+
+func.func @test_memref_load_int() {
+ %ptr = memref.alloca() {test.ptr} : memref<i64>
+ // CHECK: Successfully generated load for operation: %[[PTR:.*]] = memref.alloca() {test.ptr} : memref<i64>
+ // CHECK: Loaded value type: i64
+ // CHECK: Generated: %{{.*}} = memref.load %[[PTR]][] : memref<i64>
+ return
+}
+
+// -----
+
+func.func @test_memref_load_dynamic() {
+ %c10 = arith.constant 10 : index
+ %ptr = memref.alloc(%c10) {test.ptr} : memref<?xf32>
+ // CHECK: Failed to generate load for operation: %[[PTR:.*]] = memref.alloc(%{{.*}}) {test.ptr} : memref<?xf32>
+ return
+}
+
diff --git a/mlir/test/Dialect/OpenACC/pointer-like-interface-store.mlir b/mlir/test/Dialect/OpenACC/pointer-like-interface-store.mlir
new file mode 100644
index 0000000000000..0fee43102d6d9
--- /dev/null
+++ b/mlir/test/Dialect/OpenACC/pointer-like-interface-store.mlir
@@ -0,0 +1,39 @@
+// RUN: mlir-opt %s --split-input-file --pass-pipeline="builtin.module(func.func(test-acc-pointer-like-interface{test-mode=store}))" 2>&1 | FileCheck %s
+
+func.func @test_memref_store_scalar() {
+ %ptr = memref.alloca() {test.ptr} : memref<f32>
+ // CHECK: Successfully generated store for operation: %[[PTR:.*]] = memref.alloca() {test.ptr} : memref<f32>
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 4.200000e+01 : f32
+ // CHECK: Generated: memref.store %[[VAL]], %[[PTR]][] : memref<f32>
+ return
+}
+
+// -----
+
+func.func @test_memref_store_int() {
+ %ptr = memref.alloca() {test.ptr} : memref<i32>
+ // CHECK: Successfully generated store for operation: %[[PTR:.*]] = memref.alloca() {test.ptr} : memref<i32>
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 42 : i32
+ // CHECK: Generated: memref.store %[[VAL]], %[[PTR]][] : memref<i32>
+ return
+}
+
+// -----
+
+func.func @test_memref_store_i64() {
+ %ptr = memref.alloca() {test.ptr} : memref<i64>
+ // CHECK: Successfully generated store for operation: %[[PTR:.*]] = memref.alloca() {test.ptr} : memref<i64>
+ // CHECK: Generated: %[[VAL:.*]] = arith.constant 42 : i64
+ // CHECK: Generated: memref.store %[[VAL]], %[[PTR]][] : memref<i64>
+ return
+}
+
+// -----
+
+func.func @test_memref_store_dynamic() {
+ %c10 = arith.constant 10 : index
+ %ptr = memref.alloc(%c10) {test.ptr} : memref<?xf32>
+ // CHECK: Failed to generate store for operation: %[[PTR:.*]] = memref.alloc(%{{.*}}) {test.ptr} : memref<?xf32>
+ return
+}
+
diff --git a/mlir/test/lib/Dialect/OpenACC/TestPointerLikeTypeInterface.cpp b/mlir/test/lib/Dialect/OpenACC/TestPointerLikeTypeInterface.cpp
index 027b0a1a8b80b..9e2db6ac64f60 100644
--- a/mlir/test/lib/Dialect/OpenACC/TestPointerLikeTypeInterface.cpp
+++ b/mlir/test/lib/Dialect/OpenACC/TestPointerLikeTypeInterface.cpp
@@ -46,7 +46,7 @@ struct TestPointerLikeTypeInterfacePass
...
[truncated]
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
Outdated
Show resolved
Hide resolved
flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp
Outdated
Show resolved
Hide resolved
This patch extends the OpenACC PointerLikeType interface with two new methods for generating load and store operations, enabling dialect-agnostic memory access patterns. New Interface Methods: - genLoad(builder, loc, srcPtr, valueType): Generates a load operation from a pointer-like value. Returns the loaded value. - genStore(builder, loc, valueToStore, destPtr): Generates a store operation to a pointer-like value. Implementations provided for FIR pointer-like types, memref type (rank-0 only), and LLVM pointer types. Extended TestPointerLikeTypeInterface.cpp with 'load' and 'store' test modes.
This patch extends the OpenACC PointerLikeType interface with two new methods for generating load and store operations, enabling dialect-agnostic memory access patterns. New Interface Methods: - genLoad(builder, loc, srcPtr, valueType): Generates a load operation from a pointer-like value. Returns the loaded value. - genStore(builder, loc, valueToStore, destPtr): Generates a store operation to a pointer-like value. Implementations provided for FIR pointer-like types, memref type (rank-0 only), and LLVM pointer types. Extended TestPointerLikeTypeInterface.cpp with 'load' and 'store' test modes.
This patch extends the OpenACC PointerLikeType interface with two new methods for generating load and store operations, enabling dialect-agnostic memory access patterns.
New Interface Methods:
genLoad(builder, loc, srcPtr, valueType): Generates a load operation from a pointer-like value. Returns the loaded value.
genStore(builder, loc, valueToStore, destPtr): Generates a store operation to a pointer-like value.
Implementations provided for FIR pointer-like types, memref type (rank-0 only), and LLVM pointer types.
Extended TestPointerLikeTypeInterface.cpp with 'load' and 'store' test modes.