[flang-commits] [flang] [mlir] [acc][flang] Add genLoad and genStore to PointerLikeType (PR #170348)
via flang-commits
flang-commits at lists.llvm.org
Tue Dec 2 10:41:18 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-fir-hlfir
Author: Razvan Lupusoru (razvanlupusoru)
<details>
<summary>Changes</summary>
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.
---
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:
- (modified) flang/include/flang/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.h (+9)
- (modified) flang/lib/Optimizer/OpenACC/Support/FIROpenACCTypeInterfaces.cpp (+112)
- (added) flang/test/Fir/OpenACC/pointer-like-interface-load.mlir (+85)
- (added) flang/test/Fir/OpenACC/pointer-like-interface-store.mlir (+75)
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCTypeInterfaces.td (+44)
- (modified) mlir/lib/Dialect/OpenACC/IR/OpenACC.cpp (+56)
- (added) mlir/test/Dialect/OpenACC/pointer-like-interface-load.mlir (+29)
- (added) mlir/test/Dialect/OpenACC/pointer-like-interface-store.mlir (+39)
- (modified) mlir/test/lib/Dialect/OpenACC/TestPointerLikeTypeInterface.cpp (+107-2)
``````````diff
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]
``````````
</details>
https://github.com/llvm/llvm-project/pull/170348
More information about the flang-commits
mailing list