Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allows for infinite brillig loops #7296

Merged
merged 7 commits into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
}
}
}
Loading