diff --git a/compiler/noirc_evaluator/src/ssa/ir/printer.rs b/compiler/noirc_evaluator/src/ssa/ir/printer.rs index 3965a867c2f..76393d2b7b4 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/printer.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/printer.rs @@ -303,7 +303,7 @@ fn display_instruction_inner( writeln!(f, "] : {typ}") } - Instruction::Noop => writeln!(f, "no-op"), + Instruction::Noop => writeln!(f, "nop"), } } diff --git a/compiler/noirc_evaluator/src/ssa/parser/ast.rs b/compiler/noirc_evaluator/src/ssa/parser/ast.rs index 504ab0ff107..19eff00b24f 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/ast.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/ast.rs @@ -141,6 +141,7 @@ pub(crate) enum ParsedInstruction { elements: Vec, typ: Type, }, + Nop, Not { target: Identifier, value: ParsedValue, diff --git a/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs b/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs index d794aa235d1..56181acabbd 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/into_ssa.rs @@ -330,6 +330,9 @@ impl Translator { let value_id = self.builder.insert_load(value, typ); self.define_variable(target, value_id)?; } + ParsedInstruction::Nop => { + self.builder.insert_instruction(Instruction::Noop, None); + } ParsedInstruction::Not { target, value } => { let value = self.translate_value(value)?; let value_id = self.builder.insert_not(value); diff --git a/compiler/noirc_evaluator/src/ssa/parser/mod.rs b/compiler/noirc_evaluator/src/ssa/parser/mod.rs index 6faa356a8a8..bad08e74552 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/mod.rs @@ -335,6 +335,10 @@ impl<'a> Parser<'a> { return Ok(Some(instruction)); } + if let Some(instruction) = self.parse_nop()? { + return Ok(Some(instruction)); + } + if let Some(target) = self.eat_identifier()? { return Ok(Some(self.parse_assignment(target)?)); } @@ -458,6 +462,14 @@ impl<'a> Parser<'a> { Ok(Some(ParsedInstruction::Store { address, value })) } + fn parse_nop(&mut self) -> ParseResult> { + if !self.eat_keyword(Keyword::Nop)? { + return Ok(None); + } + + Ok(Some(ParsedInstruction::Nop)) + } + fn parse_assignment(&mut self, target: Identifier) -> ParseResult { let mut targets = vec![target]; diff --git a/compiler/noirc_evaluator/src/ssa/parser/tests.rs b/compiler/noirc_evaluator/src/ssa/parser/tests.rs index 9f401aab10a..7428691eb76 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/tests.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/tests.rs @@ -649,3 +649,15 @@ fn regression_modulo_fields_brillig() { let ssa = Ssa::from_str(src).unwrap(); ssa.to_brillig(&BrilligOptions::default()); } + +#[test] +fn test_parses_nop() { + let src = " + acir(inline) fn add f0 { + b0(): + nop + return + } + "; + assert_ssa_roundtrip(src); +} diff --git a/compiler/noirc_evaluator/src/ssa/parser/token.rs b/compiler/noirc_evaluator/src/ssa/parser/token.rs index 0c4b60cc3ea..54fcd888d53 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/token.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/token.rs @@ -152,6 +152,7 @@ pub(crate) enum Keyword { Mod, Mul, Mut, + Nop, NoPredicates, Not, Of, @@ -216,6 +217,7 @@ impl Keyword { "mod" => Keyword::Mod, "mul" => Keyword::Mul, "mut" => Keyword::Mut, + "nop" => Keyword::Nop, "no_predicates" => Keyword::NoPredicates, "not" => Keyword::Not, "of" => Keyword::Of, @@ -284,6 +286,7 @@ impl Display for Keyword { Keyword::Mod => write!(f, "mod"), Keyword::Mul => write!(f, "mul"), Keyword::Mut => write!(f, "mut"), + Keyword::Nop => write!(f, "nop"), Keyword::NoPredicates => write!(f, "no_predicates"), Keyword::Not => write!(f, "not"), Keyword::Of => write!(f, "of"),