From 2ffeb2daf7453e781f365000b290c8e2023b9f5c Mon Sep 17 00:00:00 2001 From: Jake Fecher Date: Thu, 3 Aug 2023 12:45:26 -0500 Subject: [PATCH] Fix simplification of overflowing integer operations --- .../tests/test_data/4_sub/src/main.nr | 4 ++++ .../noirc_evaluator/src/ssa/ir/instruction.rs | 24 +++++++++---------- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/crates/nargo_cli/tests/test_data/4_sub/src/main.nr b/crates/nargo_cli/tests/test_data/4_sub/src/main.nr index 80fc0177e41..43ea9d5b4f0 100644 --- a/crates/nargo_cli/tests/test_data/4_sub/src/main.nr +++ b/crates/nargo_cli/tests/test_data/4_sub/src/main.nr @@ -2,4 +2,8 @@ fn main(mut x: u32, y: u32, z: u32) { x -= y; assert(x == z); + + // Test constant underflow (regression for #2045) + let x = -1 as u4; + assert(x == 15); } diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index 680715fb0ec..8c2b180b401 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -637,7 +637,7 @@ impl Binary { let lhs = truncate(lhs.try_into_u128()?, *bit_size); let rhs = truncate(rhs.try_into_u128()?, *bit_size); - let result = function(lhs, rhs)?; + let result = function(lhs, rhs); truncate(result, *bit_size).into() } _ => return None, @@ -673,18 +673,18 @@ impl BinaryOp { } } - fn get_u128_function(self) -> fn(u128, u128) -> Option { + fn get_u128_function(self) -> fn(u128, u128) -> u128 { match self { - BinaryOp::Add => u128::checked_add, - BinaryOp::Sub => u128::checked_sub, - BinaryOp::Mul => u128::checked_mul, - BinaryOp::Div => u128::checked_div, - BinaryOp::Mod => u128::checked_rem, - BinaryOp::And => |x, y| Some(x & y), - BinaryOp::Or => |x, y| Some(x | y), - BinaryOp::Xor => |x, y| Some(x ^ y), - BinaryOp::Eq => |x, y| Some((x == y) as u128), - BinaryOp::Lt => |x, y| Some((x < y) as u128), + BinaryOp::Add => u128::wrapping_add, + BinaryOp::Sub => u128::wrapping_sub, + BinaryOp::Mul => u128::wrapping_mul, + BinaryOp::Div => u128::wrapping_div, + BinaryOp::Mod => u128::wrapping_rem, + BinaryOp::And => |x, y| x & y, + BinaryOp::Or => |x, y| x | y, + BinaryOp::Xor => |x, y| x ^ y, + BinaryOp::Eq => |x, y| (x == y) as u128, + BinaryOp::Lt => |x, y| (x < y) as u128, } } }