From d0e40e6a50b5f183fb87a1b64489d19301d85c86 Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 1 Feb 2024 16:43:08 +0000 Subject: [PATCH 1/2] feat: simplify all unsigned constant NOT instructions --- 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..cd9d9f951a7 --- /dev/null +++ b/test_programs/compile_success_empty/literal_not_simplification/src/main.nr @@ -0,0 +1,8 @@ +fn main(x: u8) { + let four: u8 = 4; + let not_four: u8 = !four; + + let five: u8 = 5; + let not_five: u8 = !five; + assert(not_four != not_five); +} From fdf4e825a67e38d6fd3fe9883e1c54316ab7e70d Mon Sep 17 00:00:00 2001 From: Tom French Date: Thu, 1 Feb 2024 21:39:04 +0000 Subject: [PATCH 2/2] chore: remove unused program argument --- .../literal_not_simplification/src/main.nr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index cd9d9f951a7..33198a326c9 100644 --- a/test_programs/compile_success_empty/literal_not_simplification/src/main.nr +++ b/test_programs/compile_success_empty/literal_not_simplification/src/main.nr @@ -1,4 +1,4 @@ -fn main(x: u8) { +fn main() { let four: u8 = 4; let not_four: u8 = !four;