llvm-project
llvm-project copied to clipboard
[mlir][func] Duplicate function elimination pass can create invalid IR
In the duplicate function elimination logic here, there are a couple bugs:
- It is not checked whether a function has a body or not, so in the below
some_external_func2will be replaced withsome_external_func:
func.func private @some_external_func(i32, i32) -> i32
func.func private @some_external_func2(i32, i32) -> i32
func.func @some_caller(%arg0: i32, %arg1: i32) -> (i32, i32) {
%0 = func.call @some_external_func(%arg0, %arg1) : (i32, i32) -> i32
%1 = func.call @some_external_func2(%arg0, %arg1) : (i32, i32) -> i32
return %0, %1 : i32, i32
}
- The logic assumes that the only users of the
func.funcsymbol arefunc::CallOpops, but it doesn't check this. There could be other users (e.g.func.constant, ops not in upstream, or even just a discardableSymbolRefAttrin any op). These symbols will still refer to the removed function symbol at the end of the pass.