Unreachable inst causes `unhandled terminator in non-terminator context` error in `stackify` pass
greenhat opened this issue · comments
Denys Zadorozhnyi commented
Error:
thread 'rust_masm_tests::apps::fib' panicked at codegen/masm/src/stackify/pass.rs:1389:9:
unhandled terminator in non-terminator context: PrimOp(PrimOp { op: Unreachable, args: EntityList { index: 0, unused: PhantomData<miden_hir::value::Value> } })
When the Rust code 9999/n
compiles to the following Wasm:
(module
(type (;0;) (func (param i32) (result i32)))
(func $fib (;0;) (type 0) (param i32) (result i32)
block ;; label = @1
local.get 0
i32.eqz
br_if 0 (;@1;)
i32.const 99999
local.get 0
i32.div_u
return
end
unreachable
unreachable
)
(memory (;0;) 16)
(global $__stack_pointer (;0;) (mut i32) i32.const 1048576)
(global (;1;) i32 i32.const 1048576)
(global (;2;) i32 i32.const 1048576)
(export "memory" (memory 0))
(export "fib" (func $fib))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
)
Which in turn translates to the following IR:
module noname
const $0 = 0x00100000;
global external @__stack_pointer : i32 = $0 { id = 0 };
global external @gv1 : i32 = $0 { id = 1 };
global external @gv2 : i32 = $0 { id = 2 };
pub fn fib(i32) -> i32 {
block0(v0: i32):
v2 = eq v0, 0 : i1;
v3 = cast v2 : i32;
v4 = neq v3, 0 : i1;
condbr v4, block2, block3;
block1(v1: i32):
block2:
unreachable ;
block3:
v5 = const.i32 99999 : i32;
v6 = cast v5 : u32;
v7 = cast v0 : u32;
v8 = div.checked v6, v7 : u32;
v9 = cast v8 : i32;
ret v9;
}
The stackify
pass fails with the error above.
Paul Schoenfelder commented
This one is a simple bug, all terminators are handled together in the pass before emitting the rest of the ops for a block, and unreachable
isn't being handled there, but as a normal primop. I can open a patch for that here in a few.