Skip to content
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
43 changes: 29 additions & 14 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,36 @@

let lhs = try_convert_field_element_to_signed_integer(lhs, bit_size)?;
let rhs = try_convert_field_element_to_signed_integer(rhs, bit_size)?;
// The divisor is being truncated into the type of the operand, which can potentially
// lead to the rhs being zero.
// If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic.
// Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic,
// and the operation should be handled by ACIR generation.
if matches!(operator, BinaryOp::Div | BinaryOp::Mod) && rhs == 0 {
return None;
}

let result = function(lhs, rhs)?;
// Check for overflow
let two_pow_bit_size_minus_one = 1i128 << (bit_size - 1);
if result >= two_pow_bit_size_minus_one || result < -two_pow_bit_size_minus_one {
return None;
}
let result = function(lhs, rhs);
let result = match operator {
BinaryOp::Div | BinaryOp::Mod if rhs == 0 => {
// The divisor is being truncated into the type of the operand, which can potentially
// lead to the rhs being zero.
// If the rhs of a division is zero, attempting to evaluate the division will cause a compiler panic.
// Thus, we do not evaluate the division in this method, as we want to avoid triggering a panic,
// and the operation should be handled by ACIR generation.
return None;
}
BinaryOp::Shr => {
if rhs >= bit_size as i128 {
0
} else {
result?
}
}

_ => {
// Check for overflow
let two_pow_bit_size_minus_one = 1i128 << (bit_size - 1);
let result = result?;
if result >= two_pow_bit_size_minus_one || result < -two_pow_bit_size_minus_one
{
return None;
}
result
}
};
convert_signed_integer_to_field_element(result, bit_size)
}
};
Expand Down Expand Up @@ -322,7 +337,7 @@

let integer_modulus = BigUint::from(2_u128).pow(bit_size);
let truncated_as_bigint = BigUint::from(input)
.modpow(&BigUint::one(), &integer_modulus);

Check warning on line 340 in compiler/noirc_evaluator/src/ssa/ir/instruction/binary.rs

View workflow job for this annotation

GitHub Actions / Code

Unknown word (modpow)
let truncated_as_bigint = FieldElement::from_be_bytes_reduce(&truncated_as_bigint.to_bytes_be());
prop_assert_eq!(truncated_as_field, truncated_as_bigint);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ fn main(x: u64) {
//regression for 6201
let a: i16 = -769;
assert_eq(a >> 3, -97);

regression_8310();
}

fn regression_2250() {
Expand All @@ -28,3 +30,9 @@ fn regression_2250() {
let b: u32 = 1 >> 32;
assert(b == 0);
}

fn regression_8310() {
let x: i64 = -356710612598522715;
let b = x >> 64;
assert(b == 0);
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading