From a395c5cf7ad2df9628f0ad670cfb7858e02afab4 Mon Sep 17 00:00:00 2001 From: jewelofchaos9 Date: Tue, 17 Jun 2025 11:01:08 +0000 Subject: [PATCH 1/2] fix --- compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs index cc8aebac06b..6f1f356892e 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify/binary.rs @@ -234,10 +234,11 @@ pub(super) fn simplify_binary(binary: &Binary, dfg: &mut DataFlowGraph) -> Simpl (Some(bitmask), None) | (None, Some(bitmask)) => { // This substitution requires the bitmask to retain all of the lower bits. // The bitmask must then be one less than a power of 2. - let bitmask_plus_one = bitmask.to_u128() + 1; - if bitmask_plus_one.is_power_of_two() { + let bitmask = bitmask.to_u128(); + if bitmask == u128::MAX || (bitmask + 1).is_power_of_two() { let value = if lhs_value.is_some() { rhs } else { lhs }; - let bit_size = bitmask_plus_one.ilog2(); + let bit_size = + if bitmask == u128::MAX { 128 } else { (bitmask + 1).ilog2() }; let max_bit_size = lhs_type.bit_size(); if bit_size == max_bit_size { From 66c91e01d171659a404a79150ea884e4349ebba6 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Tue, 17 Jun 2025 11:18:25 +0000 Subject: [PATCH 2/2] chore: add regression test --- .../src/ssa/ir/dfg/simplify.rs | 55 +++++++++++++++---- 1 file changed, 43 insertions(+), 12 deletions(-) diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs index b0461c3b092..93cd6695a61 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg/simplify.rs @@ -463,29 +463,60 @@ mod tests { #[test] fn simplifies_or_when_one_side_is_all_1s() { let test_cases = vec![ - ("u128", "340282366920938463463374607431768211455"), - ("u64", "18446744073709551615"), - ("u32", "4294967295"), - ("u16", "65535"), - ("u8", "255"), + ("u128", u128::MAX.to_string()), + ("u64", u64::MAX.to_string()), + ("u32", u32::MAX.to_string()), + ("u16", u16::MAX.to_string()), + ("u8", u8::MAX.to_string()), ]; const SRC_TEMPLATE: &str = " acir(inline) pure fn main f0 { - b0(v1: {typ}): - v2 = or {typ} {max}, v1 - return v2 + b0(v1: {typ}): + v2 = or {typ} {max}, v1 + return v2 } "; const EXPECTED_TEMPLATE: &str = " acir(inline) pure fn main f0 { - b0(v1: {typ}): - return {typ} {max} + b0(v1: {typ}): + return {typ} {max} + } + "; + for (typ, max) in test_cases { + let src = SRC_TEMPLATE.replace("{typ}", typ).replace("{max}", &max); + let expected = EXPECTED_TEMPLATE.replace("{typ}", typ).replace("{max}", &max); + let ssa: Ssa = Ssa::from_str_simplifying(&src).unwrap(); + assert_normalized_ssa_equals(ssa, &expected); + } + } + + #[test] + fn simplifies_noop_bitwise_and_truncation() { + let test_cases = vec![ + ("u128", u128::MAX.to_string()), + ("u64", u64::MAX.to_string()), + ("u32", u32::MAX.to_string()), + ("u16", u16::MAX.to_string()), + ("u8", u8::MAX.to_string()), + ]; + const SRC_TEMPLATE: &str = " + acir(inline) pure fn main f0 { + b0(v1: {typ}): + v2 = and {typ} {max}, v1 + return v2 + } + "; + + const EXPECTED_TEMPLATE: &str = " + acir(inline) pure fn main f0 { + b0(v1: {typ}): + return v1 } "; for (typ, max) in test_cases { - let src = SRC_TEMPLATE.replace("{typ}", typ).replace("{max}", max); - let expected = EXPECTED_TEMPLATE.replace("{typ}", typ).replace("{max}", max); + let src = SRC_TEMPLATE.replace("{typ}", typ).replace("{max}", &max); + let expected = EXPECTED_TEMPLATE.replace("{typ}", typ); let ssa: Ssa = Ssa::from_str_simplifying(&src).unwrap(); assert_normalized_ssa_equals(ssa, &expected); }