Skip to content

Instantly share code, notes, and snippets.

@navyxliu
Last active September 22, 2025 01:32
Show Gist options
  • Save navyxliu/2949bfd5b57defdabbd81abb3ed11409 to your computer and use it in GitHub Desktop.
Save navyxliu/2949bfd5b57defdabbd81abb3ed11409 to your computer and use it in GitHub Desktop.
The remove-dead-value bug.
input.mlir
```
module @return_void_with_unused_argument {
// the function is immutable because it is public.
func.func public @immutable_fn_return_void_with_unused_argument(%arg0: i32, %unused: i32) -> () {
%sum = arith.addi %arg0, %arg0 : i32
%c0 = arith.constant 0 : index
%buf = memref.alloc() : memref<1xi32>
memref.store %sum, %buf[%c0] : memref<1xi32>
return
}
func.func @main2(%arg0: i32) -> () {
%zero = arith.constant 0 : i32
call @immutable_fn_return_void_with_unused_argument(%arg0, %zero) : (i32, i32) -> ()
return
}
}
```
./bin/mlir-opt --remove-dead-value ./input.mlir
expect the error:
```
./input.mlir:13:5: error: null operand found
call @immutable_fn_return_void_with_unused_argument(%arg0, %zero) : (i32, i32) -> ()
^
./input.mlir:13:5: note: see current operation: "func.call"(%arg0, <<NULL VALUE>>) <{callee = @immutable_fn_return_void_with_unused_argument}> : (i32, <<NULL TYPE>>) -> ()
```
# Analysis
it's very simple. @immutable_fn_return_void_with_unused_argument is immutable because it's public.
remove-dead-values can't change it.
on the other side, liveness analysis is inter-procedural. %unused is nonLive according to it.
the bug of remove-dead-values is that
1) it overlooks the public quanlifier of the callop.
2) in a basic block, it iterates forward, not backward.
It discovers %zero = arith.constant 0 : i32 first, and mark it NonLive because its only use is NonLive.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment