Skip to content

Commit b00facb

Browse files
vezenovmTomAFrench
andauthored
fix(ssa): Use post order when mapping instructions in loop invariant pass (#7140)
Co-authored-by: Tom French <tom@tomfren.ch>
1 parent f73dc9a commit b00facb

File tree

7 files changed

+71
-2
lines changed

7 files changed

+71
-2
lines changed

compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use crate::ssa::{
1616
function::Function,
1717
function_inserter::FunctionInserter,
1818
instruction::{binary::eval_constant_binary_op, BinaryOp, Instruction, InstructionId},
19+
post_order::PostOrder,
1920
types::Type,
2021
value::ValueId,
2122
},
@@ -272,8 +273,10 @@ impl<'f> LoopInvariantContext<'f> {
272273
/// correct new value IDs based upon the `FunctionInserter` internal map.
273274
/// Leaving out this mapping could lead to instructions with values that do not exist.
274275
fn map_dependent_instructions(&mut self) {
275-
let blocks = self.inserter.function.reachable_blocks();
276-
for block in blocks {
276+
let mut block_order = PostOrder::with_function(self.inserter.function).into_vec();
277+
block_order.reverse();
278+
279+
for block in block_order {
277280
for instruction_id in self.inserter.function.dfg[block].take_instructions() {
278281
self.inserter.push_instruction(instruction_id, block);
279282
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "regression_7128"
3+
type = "bin"
4+
authors = [""]
5+
6+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
in0 = "1"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
fn main(in0: Field) -> pub Field {
2+
let mut out0: Field = 0;
3+
let tmp1: Field = in0;
4+
5+
if (out0 == out0) // <== changing out0 to in0 or removing
6+
{
7+
// the comparison changes the result
8+
let in0_as_bytes: [u8; 32] = in0.to_be_bytes();
9+
let mut result: [u8; 32] = [0; 32];
10+
for i in 0..32 {
11+
result[i] = in0_as_bytes[i];
12+
}
13+
}
14+
15+
let mut tmp2: Field = 0; // <== moving this to the top of main,
16+
if (0.lt(in0)) // changes the result
17+
{
18+
tmp2 = 1;
19+
}
20+
21+
out0 = (tmp2 - tmp1);
22+
23+
assert(out0 != 0, "soundness violation");
24+
25+
out0
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "regression_7128"
3+
type = "bin"
4+
authors = [""]
5+
6+
[dependencies]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
in0 = "1"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
fn main(in0: Field) -> pub Field {
2+
let mut out0: Field = 0;
3+
let tmp1: Field = in0;
4+
5+
if (out0 == out0) // <== changing out0 to in0 or removing
6+
{
7+
// the comparison changes the result
8+
let in0_as_bytes: [u8; 32] = in0.to_be_bytes();
9+
let mut result: [u8; 32] = [0; 32];
10+
for i in 0..32 {
11+
result[i] = in0_as_bytes[i];
12+
}
13+
}
14+
15+
let mut tmp2: Field = 0; // <== moving this to the top of main,
16+
if (0.lt(in0)) // changes the result
17+
{
18+
tmp2 = 1;
19+
}
20+
21+
out0 = (tmp2 - tmp1);
22+
23+
assert(out0 == 0, "completeness violation");
24+
25+
out0
26+
}

0 commit comments

Comments
 (0)