[flang-commits] [clang] [flang] [Flang][FIR] Introduce FIRToCoreMLIR pass. (PR #168703)

Ming Yan via flang-commits flang-commits at lists.llvm.org
Wed Dec 3 19:44:05 PST 2025


NexMing wrote:

> Can you provide an example of such mem2reg you would like to see happening? I agree something needs to be done around fir.declare to allow mem2reg. I think we should be able to implement the PromotableOpInterface for it so that at least scalar case mem2reg would be possible, so I am interested to see if that would cover the cases you are interested in.

Here is a simple example.
```
  func.func @_QPfoo(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}) {
    %c0_i32 = arith.constant 0 : i32
    %0 = fir.dummy_scope : !fir.dscope
    %1 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QFfooEa"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
    %2 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFfooEi"}
    %3 = fir.declare %2 {uniq_name = "_QFfooEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
    fir.store %c0_i32 to %3 : !fir.ref<i32>
    %4 = fir.load %3 : !fir.ref<i32>
    fir.store %4 to %1 : !fir.ref<i32>
    return
  }
```
When it is lowered to the MLIR standard dialects, it becomes the following:
```
  func.func @_QPfoo(%arg0: !fir.ref<i32> {fir.bindc_name = "a"}) {
    %c0_i32 = arith.constant 0 : i32
    %0 = fir.dummy_scope : !fir.dscope
    %1 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_inout>, uniq_name = "_QFfooEa"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
    %2 = builtin.unrealized_conversion_cast %1 : !fir.ref<i32> to memref<i32, strided<[], offset: ?>>
    %alloca = memref.alloca() {bindc_name = "i", in_type = i32, uniq_name = "_QFfooEi"} : memref<i32>
    %cast = memref.cast %alloca : memref<i32> to memref<i32, strided<[], offset: ?>>
    %3 = builtin.unrealized_conversion_cast %cast : memref<i32, strided<[], offset: ?>> to !fir.ref<i32>
    %4 = fir.declare %3 {uniq_name = "_QFfooEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
    %5 = builtin.unrealized_conversion_cast %4 : !fir.ref<i32> to memref<i32, strided<[], offset: ?>>
    memref.store %c0_i32, %5[] : memref<i32, strided<[], offset: ?>>
    %6 = memref.load %5[] : memref<i32, strided<[], offset: ?>>
    memref.store %6, %2[] : memref<i32, strided<[], offset: ?>>
    return
  }
```
I want the `memref.alloca` here to be eliminated, but the presence of `fir.declare` prevents the `mem2reg` optimization.
As you said, we can try implementing `PromotableOpInterface` to see whether it can resolve this issue.

Additionally, the `fir-memref-dataflow-opt` pass can also optimize it, but I’ve found that this pass is not robust enough (I encountered bugs in my tests), and I prefer extending or implementing this in the MLIR standard dialects—it’s more general.

https://github.com/llvm/llvm-project/pull/168703


More information about the flang-commits mailing list