llvm-project/flang/test/Fir/convert-memref-codegen.mlir
Susan Tan (ス-ザン タン) 2698d15664
[flang] Lowering FIR memory ops to MemRef dialect (#173507)
This patch introduces FIRToMemRef, a lowering pass that converts FIR
memory operations to the MemRef dialect, including support for slices,
shifts, and descriptor-style access patterns. To support partial
lowering, where FIR and MemRef types can coexist, we extend the handling
of fir.convert to correctly marshal between FIR reference-like types and
MemRef descriptors. The patch also factors the type conversion logic
into a reusable FIRToMemRefTypeConverter, which centralizes the rules
for converting FIR types (e.g. !fir.ref, !fir.box, sequences, logicals)
to their corresponding memref types, and is used throughout the new
pass.

---------

Co-authored-by: Scott Manley <rscottmanley@gmail.com>
Co-authored-by: jeanPerier <jean.perier.polytechnique@gmail.com>
2026-01-14 10:46:50 -05:00

37 lines
2.0 KiB
MLIR

// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s -o - | FileCheck %s
// This test ensures that the FIR CodeGen ConvertOpConversion
// properly lowers fir.convert when either the source or the destination
// type is a memref.
module {
// CHECK-LABEL: llvm.func @memref_to_ref_convert(
// Reconstruct the memref descriptor from the expanded LLVM arguments.
// CHECK: %[[POISON0:.*]] = llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[DESC0:.*]] = llvm.insertvalue %arg0, %[[POISON0]][0] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[DESC1:.*]] = llvm.insertvalue %arg1, %[[DESC0]][1] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[DESC:.*]] = llvm.insertvalue %arg2, %[[DESC1]][2] : !llvm.struct<(ptr, ptr, i64)>
//
// Lower the fir.convert from memref<f32> to !fir.ref<f32> by extracting
// the buffer pointer from the descriptor.
// CHECK: %[[ALIGNED:.*]] = llvm.extractvalue %[[DESC]][1] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[OFF:.*]] = llvm.extractvalue %[[DESC]][2] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[BUF:.*]] = llvm.getelementptr %[[ALIGNED]][%[[OFF]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
//
// The second fir.convert (from !fir.ref<f32> back to memref<f32>) lowering
// CHECK: %[[POISON1:.*]] = llvm.mlir.poison : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[DESC2:.*]] = llvm.insertvalue %[[BUF]], %[[POISON1]][0] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[DESC3:.*]] = llvm.insertvalue %[[BUF]], %[[DESC2]][1] : !llvm.struct<(ptr, ptr, i64)>
// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : index) : i64
// CHECK: %[[DESC4:.*]] = llvm.insertvalue %[[ZERO]], %[[DESC3]][2] : !llvm.struct<(ptr, ptr, i64)>
//
// CHECK-NOT: fir.convert
func.func @memref_to_ref_convert(%arg0: memref<f32>) {
%0 = fir.convert %arg0 : (memref<f32>) -> !fir.ref<f32>
%1 = fir.convert %0 : (!fir.ref<f32>) -> memref<f32>
return
}
}