From fab4a6e6ff025c83ec43313e36b8a236d030313a Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 5 Feb 2024 12:51:27 +0000 Subject: [PATCH] feat: simplify all unsigned constant NOT instructions (#4230) # Description ## Problem\* Resolves ## Summary\* This PR expands the existing simplification of constant NOT instructions to cover all unsigned integers. ## Additional Context ## Documentation\* Check one: - [x] No documentation needed. - [ ] Documentation included in this PR. - [ ] **[Exceptional Case]** Documentation to be submitted in a separate PR. # PR Checklist\* - [x] I have tested the changes locally. - [x] I have formatted the changes with [Prettier](https://prettier.io/) and/or `cargo fmt` on default settings. --- compiler/noirc_evaluator/src/ssa/ir/instruction.rs | 7 ++++--- .../literal_not_simplification/Nargo.toml | 7 +++++++ .../literal_not_simplification/src/main.nr | 8 ++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 test_programs/compile_success_empty/literal_not_simplification/Nargo.toml create mode 100644 test_programs/compile_success_empty/literal_not_simplification/src/main.nr diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index fa5bc0f6697..7e9a64e8fbc 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -440,9 +440,10 @@ impl Instruction { // Limit optimizing ! on constants to only booleans. If we tried it on fields, // there is no Not on FieldElement, so we'd need to convert between u128. This // would be incorrect however since the extra bits on the field would not be flipped. - Value::NumericConstant { constant, typ } if *typ == Type::bool() => { - let value = constant.is_zero() as u128; - SimplifiedTo(dfg.make_constant(value.into(), Type::bool())) + Value::NumericConstant { constant, typ } if typ.is_unsigned() => { + // As we're casting to a `u128`, we need to clear out any upper bits that the NOT fills. + let value = !constant.to_u128() % (1 << typ.bit_size()); + SimplifiedTo(dfg.make_constant(value.into(), typ.clone())) } Value::Instruction { instruction, .. } => { // !!v => v diff --git a/test_programs/compile_success_empty/literal_not_simplification/Nargo.toml b/test_programs/compile_success_empty/literal_not_simplification/Nargo.toml new file mode 100644 index 00000000000..63d73ed3c0a --- /dev/null +++ b/test_programs/compile_success_empty/literal_not_simplification/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "literal_not_simplification" +type = "bin" +authors = [""] +compiler_version = ">=0.23.0" + +[dependencies] diff --git a/test_programs/compile_success_empty/literal_not_simplification/src/main.nr b/test_programs/compile_success_empty/literal_not_simplification/src/main.nr new file mode 100644 index 00000000000..33198a326c9 --- /dev/null +++ b/test_programs/compile_success_empty/literal_not_simplification/src/main.nr @@ -0,0 +1,8 @@ +fn main() { + let four: u8 = 4; + let not_four: u8 = !four; + + let five: u8 = 5; + let not_five: u8 = !five; + assert(not_four != not_five); +}