diff --git a/crates/codegen/src/yul/isel/function.rs b/crates/codegen/src/yul/isel/function.rs index 46f60c5c9e..249754310a 100644 --- a/crates/codegen/src/yul/isel/function.rs +++ b/crates/codegen/src/yul/isel/function.rs @@ -494,12 +494,13 @@ impl<'db, 'a> FuncLowerHelper<'db, 'a> { } fn lower_unary(&mut self, op: UnOp, value: ValueId) -> yul::Expression { + let value_ty = self.body.store.value_ty(value); let value = self.value_expr(value); match op { UnOp::Not => expression! { iszero([value])}, UnOp::Neg => { let zero = literal_expression! {0}; - expression! { sub([zero], [value])} + self.ctx.runtime.safe_sub(self.db, zero, value, value_ty) } UnOp::Inv => expression! { not([value])}, } @@ -535,6 +536,7 @@ impl<'db, 'a> FuncLowerHelper<'db, 'a> { BinOp::Mod => self.ctx.runtime.safe_mod(self.db, lhs, rhs, inst_result_ty), BinOp::Pow => self.ctx.runtime.safe_pow(self.db, lhs, rhs, inst_result_ty), BinOp::Shl => expression! {shl([rhs], [lhs])}, + BinOp::Shr if is_signed => expression! {sar([rhs], [lhs])}, BinOp::Shr => expression! {shr([rhs], [lhs])}, BinOp::BitOr | BinOp::LogicalOr => expression! {or([lhs], [rhs])}, BinOp::BitXor => expression! {xor([lhs], [rhs])}, diff --git a/newsfragments/723.bugfix.md b/newsfragments/723.bugfix.md new file mode 100644 index 0000000000..6d3f06f066 --- /dev/null +++ b/newsfragments/723.bugfix.md @@ -0,0 +1,2 @@ +* Properly lower right shift operation to yul's `sar` if operand is signed type +* Properly lower negate operation to call `safe_sub`