[MLIR] mem2reg fails to promote local `memref.alloca` in a reachable block
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Hi, I found a missed optimization bug in MLIR mem2reg. In the following example, `%alloca` is local to ^bb1 and does not escape. The `memref.load` is dominated by the preceding `memref.store` to the same address, so `%0` can be replaced by `%arg0`. However, mem2reg keeps the memory operations unchanged.
### Input Program
**input.mlir**
```llvm
module {
func.func @switch_only_default(%arg0: i32, %arg1: f32) {
"foo.pred"()[^bb1, ^bb2] : () -> ()
^bb1: // pred: ^bb0
%alloca = memref.alloca() : memref<1xi32>
%c0 = arith.constant 0 : index
memref.store %arg0, %alloca[%c0] : memref<1xi32>
%0 = memref.load %alloca[%c0] : memref<1xi32>
"foo.use"(%0) : (i32) -> ()
%alloca_0 = memref.alloca() : memref<1xi32>
memref.store %0, %alloca_0[%c0] : memref<1xi32>
cf.switch %arg0 : i32, [
default: ^bb2(%arg1 : f32)]
^bb2(%1: f32): // 2 preds: ^bb0, ^bb1
"foo.bb2Terminator"(%1) : (f32) -> ()
}
}
```
### Command
```bash
mlir-opt --allow-unregistered-dialect --mem2reg input.mlir
```
Version: 9d3a3fa57c47fd06efea20f100ec747f5e5fbfdd
Contributor guide
Research direction
Start with the input.mlir reproducer and run it with mlir-opt --allow-unregistered-dialect --mem2reg. Trace the mem2reg handling of the local memref.alloca in the reachable ^bb1 block. Done means the shown load/store sequence is promoted so the value passed to foo.use reflects the preceding argument store.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100