0xPolygonMiden / compiler

Compiler from MidenIR to Miden Assembly

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unreachable inst causes `unhandled terminator in non-terminator context` error in `stackify` pass

greenhat opened this issue · comments

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.

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.