Skip to content

Commit

Permalink
chore: bitwise not for brillig (#1775)
Browse files Browse the repository at this point in the history
* bitwise not for brillig

* Code review
  • Loading branch information
guipublic authored Jun 21, 2023
1 parent 24b7738 commit 3ec0480
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 18 deletions.
19 changes: 12 additions & 7 deletions crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ impl<'block> BrilligBlock<'block> {
self.convert_ssa_terminator(terminator_instruction, dfg);
}

fn get_bit_size_from_ssa_type(typ: Type) -> u32 {
match typ {
Type::Numeric(num_type) => match num_type {
NumericType::Signed { bit_size } | NumericType::Unsigned { bit_size } => bit_size,
NumericType::NativeField => FieldElement::max_num_bits(),
},
_ => unreachable!("ICE bitwise not on a non numeric type"),
}
}

/// Creates a unique global label for a block.
///
/// This uses the current functions's function ID and the block ID
Expand Down Expand Up @@ -175,18 +185,13 @@ impl<'block> BrilligBlock<'block> {
self.brillig_context.mov_instruction(target_register, source_register);
}
Instruction::Not(value) => {
assert_eq!(
dfg.type_of_value(*value),
Type::bool(),
"not operator can only be applied to boolean values"
);
let condition = self.convert_ssa_value(*value, dfg);
let result_ids = dfg.instruction_results(instruction_id);
let result_register = self
.function_context
.get_or_create_register(self.brillig_context, result_ids[0]);

self.brillig_context.not_instruction(condition, result_register);
let bit_size = Self::get_bit_size_from_ssa_type(dfg.type_of_value(*value));
self.brillig_context.not_instruction(condition, bit_size, result_register);
}
Instruction::Call { func, arguments } => match &dfg[*func] {
Value::ForeignFunction(func_name) => {
Expand Down
25 changes: 16 additions & 9 deletions crates/noirc_evaluator/src/brillig/brillig_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl BrilligContext {

let exit_loop_label = self.next_section_label();

self.not_instruction(index_less_than_array_len, index_less_than_array_len);
self.not_instruction(index_less_than_array_len, 1, index_less_than_array_len);
self.jump_if_instruction(index_less_than_array_len, exit_loop_label);

// Copy the element from source to destination
Expand Down Expand Up @@ -419,19 +419,26 @@ impl BrilligContext {
///
/// Not is computed using a subtraction operation as there is no native not instruction
/// in Brillig.
pub(crate) fn not_instruction(&mut self, condition: RegisterIndex, result: RegisterIndex) {
debug_show::not_instruction(condition, result);
let one = self.make_constant(Value::from(FieldElement::one()));

// Compile !x as (1 - x)
pub(crate) fn not_instruction(
&mut self,
input: RegisterIndex,
bit_size: u32,
result: RegisterIndex,
) {
debug_show::not_instruction(input, bit_size, result);
// Compile !x as ((-1) - x)
let u_max = FieldElement::from(2_i128).pow(&FieldElement::from(bit_size as i128))
- FieldElement::one();
let max = self.make_constant(Value::from(u_max));
let opcode = BrilligOpcode::BinaryIntOp {
destination: result,
op: BinaryIntOp::Sub,
bit_size: 1,
lhs: one,
rhs: condition,
bit_size,
lhs: max,
rhs: input,
};
self.push_opcode(opcode);
self.deallocate_register(max);
}

/// Processes a foreign call instruction.
Expand Down
4 changes: 2 additions & 2 deletions crates/noirc_evaluator/src/brillig/brillig_ir/debug_show.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,8 @@ pub(crate) fn const_instruction(result: RegisterIndex, constant: Value) {
}

/// Processes a not instruction. Append with "_" as this is a high-level instruction.
pub(crate) fn not_instruction(condition: RegisterIndex, result: RegisterIndex) {
debug_println!(" _NOT {} = !{}", result, condition);
pub(crate) fn not_instruction(condition: RegisterIndex, bit_size: u32, result: RegisterIndex) {
debug_println!(" i{}_NOT {} = !{}", bit_size, result, condition);
}

/// Processes a foreign call instruction.
Expand Down

0 comments on commit 3ec0480

Please sign in to comment.