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
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,7 @@ impl AcirContext {
let max_power_of_two = self.add_constant(
FieldElement::from(2_i128).pow(&FieldElement::from(bit_size as i128 - 1)),
);
let zero = self.add_constant(FieldElement::zero());
let one = self.add_constant(FieldElement::one());

// Get the sign bit of rhs by computing rhs / max_power_of_two
Expand All @@ -998,10 +999,19 @@ impl AcirContext {
// Unsigned to signed: derive q and r from q1,r1 and the signs of lhs and rhs
// Quotient sign is lhs sign * rhs sign, whose resulting sign bit is the XOR of the sign bits
let q_sign = self.xor_var(lhs_leading, rhs_leading, AcirType::unsigned(1))?;

let quotient = self.two_complement(q1, q_sign, bit_size)?;
let remainder = self.two_complement(r1, lhs_leading, bit_size)?;

// Issue #5129 - When q1 is zero and quotient sign is -1, we compute -0=2^{bit_size},
// which is not valid because we do not wrap integer operations
// Similar case can happen with the remainder.
let q_is_0 = self.eq_var(q1, zero)?;
let q_is_not_0 = self.not_var(q_is_0, AcirType::unsigned(1))?;
let quotient = self.mul_var(quotient, q_is_not_0)?;
let r_is_0 = self.eq_var(r1, zero)?;
let r_is_not_0 = self.not_var(r_is_0, AcirType::unsigned(1))?;
let remainder = self.mul_var(remainder, r_is_not_0)?;

Ok((quotient, remainder))
}

Expand Down
2 changes: 1 addition & 1 deletion test_programs/execution_success/signed_div/src/main.nr
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ struct SignedDivOp {
result: i8,
}

unconstrained fn main(ops: [SignedDivOp; 15]) {
fn main(ops: [SignedDivOp; 15]) {
for i in 0..15 {
assert_eq(ops[i].lhs / ops[i].rhs, ops[i].result);
}
Expand Down