Skip to content

Commit

Permalink
fix: allows for infinite brillig loops (#7296)
Browse files Browse the repository at this point in the history
  • Loading branch information
guipublic authored Feb 7, 2025
1 parent 819a53a commit 87196e9
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ impl VariableLiveness {

fn compute_loop_body(&self, edge: BackEdge) -> HashSet<BasicBlockId> {
let mut loop_blocks = HashSet::default();
if edge.header == edge.start {
loop_blocks.insert(edge.header);
return loop_blocks;
}
loop_blocks.insert(edge.header);
loop_blocks.insert(edge.start);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -663,10 +663,11 @@ impl Context {
&mut self,
function: &Function,
) -> BTreeSet<usize> {
let returns = function.returns();
let variable_parameters_and_return_values = function
.parameters()
.iter()
.chain(function.returns())
.chain(returns)
.filter(|id| function.dfg.get_numeric_constant(**id).is_none())
.map(|value_id| function.dfg.resolve(*value_id));

Expand Down
10 changes: 3 additions & 7 deletions compiler/noirc_evaluator/src/ssa/ir/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,17 +165,13 @@ impl Function {

/// Returns the return types of this function.
pub(crate) fn returns(&self) -> &[ValueId] {
let blocks = self.reachable_blocks();
let mut function_return_values = None;
for block in blocks {
for block in self.reachable_blocks() {
let terminator = self.dfg[block].terminator();
if let Some(TerminatorInstruction::Return { return_values, .. }) = terminator {
function_return_values = Some(return_values);
break;
return return_values;
}
}
function_return_values
.expect("Expected a return instruction, as function construction is finished")
&[]
}

/// Collects all the reachable blocks of this function.
Expand Down
7 changes: 3 additions & 4 deletions compiler/noirc_evaluator/src/ssa/opt/inlining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,14 +470,14 @@ impl<'function> PerFunctionContext<'function> {
&mut self,
mut returns: Vec<(BasicBlockId, Vec<ValueId>)>,
) -> Vec<ValueId> {
// Clippy complains if this were written as an if statement
match returns.len() {
0 => Vec::new(),
1 => {
let (return_block, return_values) = returns.remove(0);
self.context.builder.switch_to_block(return_block);
return_values
}
n if n > 1 => {
_ => {
// If there is more than 1 return instruction we'll need to create a single block we
// can return to and continue inserting in afterwards.
let return_block = self.context.builder.insert_block();
Expand All @@ -490,7 +490,6 @@ impl<'function> PerFunctionContext<'function> {
self.context.builder.switch_to_block(return_block);
self.context.builder.block_parameters(return_block).to_vec()
}
_ => unreachable!("Inlined function had no return values"),
}
}

Expand Down Expand Up @@ -682,7 +681,7 @@ impl<'function> PerFunctionContext<'function> {
block_id: BasicBlockId,
block_queue: &mut VecDeque<BasicBlockId>,
) -> Option<(BasicBlockId, Vec<ValueId>)> {
match self.source_function.dfg[block_id].unwrap_terminator() {
match &self.source_function.dfg[block_id].unwrap_terminator() {
TerminatorInstruction::Jmp { destination, arguments, call_stack } => {
let destination = self.translate_block(*destination, block_queue);
let arguments = vecmap(arguments, |arg| self.translate_value(*arg));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "regression_7103"
type = "bin"
authors = [""]
compiler_version = ">=0.31.0"

[dependencies]
16 changes: 16 additions & 0 deletions test_programs/compile_success_with_bug/regression_7103/src/main.nr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
fn main() {
/// Safety: n/a
unsafe { loophole() };
}


unconstrained fn loophole() {
let mut i = 0;
loop {
println(i);
i += 1;
if false {
break;
}
}
}

0 comments on commit 87196e9

Please sign in to comment.