noir
noir copied to clipboard
Compiler hangs: infinite loop in `Inlining Brillig Calls`
Aim
Discovered testing https://github.com/noir-lang/noir/pull/8979
The following code causes the compiler to hang:
fn main() {
unsafe { func_2() };
}
unconstrained fn func_2() {
loop {
if false {
break
}
}
}
or like this:
fn main() {
unsafe { func_2(false) };
}
unconstrained fn func_2(cond: bool) {
loop {
if cond {
break
}
}
}
Expected Behavior
Expected it to compile, despite the infinite loop.
Bug
$ cargo run -q -p nargo_cli -- compile --show-ssa
After Verifying no dynamic array indices to reference value elements (1) (step 41):
acir(inline) predicate_pure fn main f0 {
b0():
call f1(u1 0)
return
}
brillig(inline) predicate_pure fn func_2 f1 {
b0(v0: u1):
jmp b1()
b1():
jmpif v0 then: b2, else: b3
b2():
return
b3():
jmp b1()
}
^C⏎
That is the last step of the primary pipeline. If we change the program to remove the infinite loop, we can see that the next step would be After Inlining Brillig Calls (1) (step 42):, which involves running the Brillig VM with constant inputs. In this case it means the compiler never returns, because it gets stuck in the infinite loop.
Maybe there could be some limit to how far we try to evaluate such calls at compile time.
To Reproduce
See above.
Workaround
None
Workaround Description
Not having any constant arguments that cause infinite loops in Brillig functions.
Additional Context
No response
Project Impact
None
Blocker Context
No response
Nargo Version
nargo version = 1.0.0-beta.7 noirc version = 1.0.0-beta.7+45246337701fe88d7f97416ee0715d23acf50ab2 (git version hash: d7030e8c4e05dcba0eb30adac7f0f18458b306f0, is dirty: true)
NoirJS Version
No response
Proving Backend Tooling & Version
No response
Would you like to submit a PR for this Issue?
None
Support Needs
No response
related: https://github.com/noir-lang/noir/issues/5026
Yeah, I'd say that we should add an execute N opcodes method to the brillig vm and then during compilation we can execute some (large) number of opcodes and otherwise just leave the call in place.