[flang-commits] [flang] f6674ac - [flang] Register memref-to-llvm patterns in FIRToLLVMLowering (#234305)

via flang-commits flang-commits at lists.llvm.org
Fri Oct 23 07:51:32 PDT 2026


Author: jon-gibney
Date: 2026-10-23T09:51:26-05:00
New Revision: f6674ac264fecb4a77962312033350fbead84203

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

LOG: [flang] Register memref-to-llvm patterns in FIRToLLVMLowering (#234305)

With
  fir-opt --fir-to-scf --fir-to-memref
  mlir-opt --raise-scf-to-affine --affine-raise-from-memref
we can get from FIR to affine and do restructuring in that form.
However, doing
  fir-opt --lower-affine
leaves memref ops that
  fir-opt --fir-to-llvm-ir
couldn't legalize, as mentioned in

https://discourse.llvm.org/t/flang-affine-linearized-array-access-in-promote-to-affine-causes-false-dependence-and-blocks-loop-tiling/89927/7

This adds the memref-to-llvm patterns to FIRToLLVMLowering to fix that.

Assisted-by: Claude

Added: 
    flang/test/Fir/memref-ops-codegen.mlir

Modified: 
    flang/include/flang/Optimizer/CodeGen/CGPasses.td
    flang/lib/Optimizer/CodeGen/CMakeLists.txt
    flang/lib/Optimizer/CodeGen/CodeGen.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/CodeGen/CGPasses.td b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
index 6f0ae6588c2de..ac16f4111630e 100644
--- a/flang/include/flang/Optimizer/CodeGen/CGPasses.td
+++ b/flang/include/flang/Optimizer/CodeGen/CGPasses.td
@@ -51,7 +51,9 @@ def FIRToLLVMLowering : Pass<"fir-to-llvm-ir", "mlir::ModuleOp"> {
            "allocations marked with the unified heap allocation mode.">,
     Option<"managedHeapAllocSuffix", "managed-heap-alloc-suffix", "std::string",
            /*default=*/"", "Suffix of the allocator entry points used for "
-           "allocations marked with the managed heap allocation mode.">
+           "allocations marked with the managed heap allocation mode.">,
+    Option<"lowerMemRef", "lower-memref", "bool", /*default=*/"false",
+           "Also convert memref dialect operations.">
   ];
 }
 

diff  --git a/flang/lib/Optimizer/CodeGen/CMakeLists.txt b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
index c3cb3ca4b3ebf..0ed85c1cc7988 100644
--- a/flang/lib/Optimizer/CodeGen/CMakeLists.txt
+++ b/flang/lib/Optimizer/CodeGen/CMakeLists.txt
@@ -44,6 +44,7 @@ add_flang_library(FIRCodeGen
   MLIRMathToLibm
   MLIRMathToNVVM
   MLIRMathToROCDL
+  MLIRMemRefToLLVM
   MLIROpenMPToLLVMConversion
   MLIROpenACCDialect
   MLIRBuiltinToLLVMIRTranslation

diff  --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index d5097aa6f7603..c96ef88f89702 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -48,6 +48,7 @@
 #include "mlir/Conversion/MathToLibm/MathToLibm.h"
 #include "mlir/Conversion/MathToNVVM/MathToNVVM.h"
 #include "mlir/Conversion/MathToROCDL/MathToROCDL.h"
+#include "mlir/Conversion/MemRefToLLVM/MemRefToLLVM.h"
 #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
 #include "mlir/Conversion/UBToLLVM/UBToLLVM.h"
 #include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
@@ -5193,6 +5194,9 @@ class FIRToLLVMLowering
     mlir::index::populateIndexToLLVMConversionPatterns(typeConverter, pattern);
     mlir::populateVectorToLLVMConversionPatterns(typeConverter, pattern);
     mlir::ub::populateUBToLLVMConversionPatterns(typeConverter, pattern);
+    if (lowerMemRef)
+      mlir::populateFinalizeMemRefToLLVMConversionPatterns(
+          typeConverter, pattern, &symbolTables);
 
     // Flang specific overloads for OpenMP operations, to allow for special
     // handling of things like Box types.

diff  --git a/flang/test/Fir/memref-ops-codegen.mlir b/flang/test/Fir/memref-ops-codegen.mlir
new file mode 100644
index 0000000000000..e4d803a8df3b0
--- /dev/null
+++ b/flang/test/Fir/memref-ops-codegen.mlir
@@ -0,0 +1,53 @@
+// RUN: fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu lower-memref=true" --split-input-file %s | FileCheck %s
+// RUN: not fir-opt --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" --split-input-file %s 2>&1 | FileCheck %s --check-prefix=DISABLED
+
+// Test that memref dialect operations, as produced by fir-to-memref and
+// lower-affine, are lowered together with the fir.convert ops that bridge
+// !fir.ref and memref values when lower-memref is enabled.
+
+// DISABLED: failed to legalize operation 'memref.load'
+
+// CHECK-LABEL: llvm.func @load_scalar(
+// CHECK-SAME:    %[[ARG0:.*]]: !llvm.ptr) -> i32 {
+// CHECK:         %[[ALIGNED:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64)>
+// CHECK:         %[[VAL:.*]] = llvm.load %[[ALIGNED]] : !llvm.ptr -> i32
+// CHECK:         llvm.return %[[VAL]] : i32
+// CHECK-NOT:     memref.
+func.func @load_scalar(%arg0: !fir.ref<i32>) -> i32 {
+  %0 = fir.convert %arg0 : (!fir.ref<i32>) -> memref<i32>
+  %1 = memref.load %0[] : memref<i32>
+  return %1 : i32
+}
+
+// -----
+
+// CHECK-LABEL: llvm.func @store_scalar(
+// CHECK-SAME:    %[[ARG0:.*]]: !llvm.ptr, %[[VAL:.*]]: f32) {
+// CHECK:         %[[ALIGNED:.*]] = llvm.extractvalue %{{.*}}[1] : !llvm.struct<(ptr, ptr, i64)>
+// CHECK:         llvm.store %[[VAL]], %[[ALIGNED]] : f32, !llvm.ptr
+// CHECK-NOT:     memref.
+func.func @store_scalar(%arg0: !fir.ref<f32>, %arg1: f32) {
+  %0 = fir.convert %arg0 : (!fir.ref<f32>) -> memref<f32>
+  memref.store %arg1, %0[] : memref<f32>
+  return
+}
+
+// -----
+
+// CHECK-LABEL: llvm.func @load_store_static_2d(
+// CHECK-SAME:    %[[ARG0:.*]]: !llvm.ptr, %[[I:.*]]: i64, %[[J:.*]]: i64) {
+// CHECK:         %[[MUL0:.*]] = llvm.mul %[[I]], %{{.*}}
+// CHECK:         %[[ADD0:.*]] = llvm.add %[[MUL0]], %[[J]]
+// CHECK:         %[[SRC:.*]] = llvm.getelementptr {{.*}}[%[[ADD0]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
+// CHECK:         %[[VAL:.*]] = llvm.load %[[SRC]] : !llvm.ptr -> f32
+// CHECK:         %[[MUL1:.*]] = llvm.mul %[[J]], %{{.*}}
+// CHECK:         %[[ADD1:.*]] = llvm.add %[[MUL1]], %[[I]]
+// CHECK:         %[[DST:.*]] = llvm.getelementptr {{.*}}[%[[ADD1]]] : (!llvm.ptr, i64) -> !llvm.ptr, f32
+// CHECK:         llvm.store %[[VAL]], %[[DST]] : f32, !llvm.ptr
+// CHECK-NOT:     memref.
+func.func @load_store_static_2d(%arg0: !fir.ref<!fir.array<4x8xf32>>, %i: index, %j: index) {
+  %0 = fir.convert %arg0 : (!fir.ref<!fir.array<4x8xf32>>) -> memref<4x8xf32>
+  %1 = memref.load %0[%i, %j] : memref<4x8xf32>
+  memref.store %1, %0[%j, %i] : memref<4x8xf32>
+  return
+}


        


More information about the flang-commits mailing list