From 4bac28c962a89e7263804b35ecb80077b52b6e66 Mon Sep 17 00:00:00 2001 From: Christoph Burgdorf Date: Tue, 20 Jan 2026 15:49:49 +0000 Subject: [PATCH 01/11] checked arithmetic --- crates/codegen/src/sonatina/lower.rs | 671 +++++++++- crates/codegen/src/sonatina/tests.rs | 1 + .../codegen/src/yul/emitter/control_flow.rs | 10 +- crates/codegen/src/yul/emitter/expr.rs | 329 +++++ crates/codegen/src/yul/emitter/module.rs | 171 ++- .../codegen/tests/fixtures/arg_bindings.snap | 40 +- crates/codegen/tests/fixtures/aug_assign.snap | 103 +- .../tests/fixtures/aug_assign_bit_ops.snap | 199 ++- crates/codegen/tests/fixtures/bit_ops.snap | 159 ++- crates/codegen/tests/fixtures/block_expr.snap | 39 +- .../fixtures/borrow_storage_field_handle.snap | 44 +- .../by_ref_trait_provider_storage_bug.snap | 135 +- .../tests/fixtures/cast_u8_usize_cmp.snap | 37 +- .../codegen/tests/fixtures/code_region.snap | 50 +- .../tests/fixtures/comparison_ops.snap | 58 +- .../codegen/tests/fixtures/const_array.snap | 65 +- .../tests/fixtures/const_array_add.snap | 39 +- .../tests/fixtures/create_contract.snap | 422 ++++-- .../tests/fixtures/effect_ptr_domains.snap | 58 +- .../tests/fixtures/enum_variant_contract.snap | 114 +- crates/codegen/tests/fixtures/erc20.snap | 533 +++++--- .../tests/fixtures/erc20_low_level.snap | 156 ++- .../codegen/tests/fixtures/event_logging.snap | 116 +- .../tests/fixtures/event_logging_via_log.snap | 116 +- crates/codegen/tests/fixtures/for_array.snap | 39 +- .../tests/fixtures/for_array_large.snap | 39 +- crates/codegen/tests/fixtures/for_range.snap | 94 +- .../codegen/tests/fixtures/full_contract.snap | 153 ++- .../codegen/tests/fixtures/function_call.snap | 40 +- .../tests/fixtures/high_level_contract.snap | 218 +++- crates/codegen/tests/fixtures/if_else.snap | 40 +- .../fixtures/init_args_with_child_dep.snap | 364 +++++- .../codegen/tests/fixtures/literal_add.snap | 39 +- .../codegen/tests/fixtures/literal_sub.snap | 39 +- .../tests/fixtures/local_bindings.snap | 43 +- .../tests/fixtures/match_mixed_return.snap | 40 +- .../codegen/tests/fixtures/match_struct.snap | 40 +- .../tests/fixtures/match_tuple_binding.snap | 82 +- crates/codegen/tests/fixtures/math_ops.snap | 18 +- crates/codegen/tests/fixtures/momo.snap | 40 +- .../tests/fixtures/name_collisions.snap | 174 ++- .../codegen/tests/fixtures/nested_struct.snap | 1 - .../newtype_field_mut_method_call.snap | 42 +- .../newtype_storage_byplace_effect_arg.snap | 137 +- ...newtype_storage_field_mut_method_call.snap | 130 +- .../newtype_word_mut_method_call.snap | 39 +- .../codegen/tests/fixtures/range_bounds.snap | 140 +- crates/codegen/tests/fixtures/ret.snap | 99 +- .../fixtures/sonatina_ir/arg_bindings.snap | 20 +- .../fixtures/sonatina_ir/aug_assign.snap | 68 +- .../sonatina_ir/aug_assign_bit_ops.snap | 148 ++- .../tests/fixtures/sonatina_ir/bit_ops.snap | 108 +- .../fixtures/sonatina_ir/block_expr.snap | 20 +- .../borrow_storage_field_handle.snap | 15 +- .../by_ref_trait_provider_storage_bug.snap | 139 +- .../sonatina_ir/cast_u8_usize_cmp.snap | 42 +- .../fixtures/sonatina_ir/code_region.snap | 35 +- .../fixtures/sonatina_ir/comparison_ops.snap | 130 +- .../fixtures/sonatina_ir/const_array.snap | 55 +- .../fixtures/sonatina_ir/const_array_add.snap | 15 +- .../fixtures/sonatina_ir/create_contract.snap | 326 ++--- .../sonatina_ir/effect_ptr_domains.snap | 35 +- .../sonatina_ir/enum_variant_contract.snap | 111 +- .../tests/fixtures/sonatina_ir/erc20.snap | 457 ++++--- .../fixtures/sonatina_ir/erc20_low_level.snap | 143 ++- .../fixtures/sonatina_ir/event_logging.snap | 93 +- .../sonatina_ir/event_logging_via_log.snap | 93 +- .../tests/fixtures/sonatina_ir/for_array.snap | 20 +- .../fixtures/sonatina_ir/for_array_large.snap | 20 +- .../tests/fixtures/sonatina_ir/for_range.snap | 61 +- .../fixtures/sonatina_ir/full_contract.snap | 115 +- .../fixtures/sonatina_ir/function_call.snap | 20 +- .../sonatina_ir/high_level_contract.snap | 236 ++-- .../tests/fixtures/sonatina_ir/if_else.snap | 20 +- .../sonatina_ir/init_args_with_child_dep.snap | 174 ++- .../fixtures/sonatina_ir/literal_add.snap | 20 +- .../fixtures/sonatina_ir/literal_sub.snap | 20 +- .../fixtures/sonatina_ir/local_bindings.snap | 20 +- .../sonatina_ir/match_mixed_return.snap | 15 +- .../fixtures/sonatina_ir/match_struct.snap | 20 +- .../sonatina_ir/match_tuple_binding.snap | 24 +- .../tests/fixtures/sonatina_ir/math_ops.snap | 25 +- .../tests/fixtures/sonatina_ir/momo.snap | 20 +- .../fixtures/sonatina_ir/name_collisions.snap | 78 +- .../newtype_field_mut_method_call.snap | 18 +- .../newtype_storage_byplace_effect_arg.snap | 126 +- ...newtype_storage_field_mut_method_call.snap | 126 +- .../newtype_word_mut_method_call.snap | 15 +- .../fixtures/sonatina_ir/range_bounds.snap | 116 +- .../tests/fixtures/sonatina_ir/ret.snap | 74 +- .../tests/fixtures/sonatina_ir/storage.snap | 128 +- .../sonatina_ir/storage_map_contract.snap | 59 +- .../sonatina_ir/tstor_ptr_contract.snap | 124 +- .../fixtures/sonatina_ir/tuple_expr.snap | 32 +- .../fixtures/sonatina_ir/while_cond_call.snap | 34 +- .../sonatina_ir/wrapping_saturating.snap | 366 ++++++ crates/codegen/tests/fixtures/storage.snap | 180 ++- .../tests/fixtures/storage_map_contract.snap | 92 +- .../fixtures/test_output/effect_test.snap | 39 +- .../tests/fixtures/tstor_ptr_contract.snap | 138 +- crates/codegen/tests/fixtures/tuple_expr.snap | 50 +- .../tests/fixtures/while_cond_call.snap | 48 +- .../tests/fixtures/wrapping_saturating.fe | 18 + .../tests/fixtures/wrapping_saturating.snap | 261 ++++ .../fe/tests/fixtures/build_foundry/erc20.fe | 2 +- .../fe_test/checked_arithmetic_matrix.fe | 715 +++++++++++ .../fe_test/checked_arithmetic_methods.fe | 56 + .../fe_test/checked_arithmetic_regressions.fe | 113 ++ .../fixtures/fe_test/signed_arithmetic.fe | 100 ++ .../checked_arithmetic_reverts.fe | 47 + .../checked_arithmetic_reverts.snap | 37 + crates/hir/src/analysis/ty/const_ty.rs | 378 +++++- crates/hir/src/analysis/ty/ty_check/expr.rs | 78 +- crates/hir/test_files/ty_check/ops.snap | 1 - crates/mir/src/analysis/escape.rs | 8 + crates/mir/src/ir.rs | 36 + crates/mir/src/lower/contracts.rs | 10 +- crates/mir/src/lower/expr.rs | 325 ++++- crates/mir/src/lower/intrinsics.rs | 83 ++ crates/mir/src/lower/prepass.rs | 10 +- crates/mir/src/monomorphize.rs | 38 +- crates/mir/tests/fixtures/abi_decode.mir.snap | 47 +- .../tests/fixtures/borrow_handles.mir.snap | 18 +- .../fixtures/borrow_handles_readback.mir.snap | 25 +- .../by_ref_trait_effect_provider.mir.snap | 8 +- .../tests/fixtures/cast_u8_usize_cmp.mir.snap | 24 +- ...ole_storage_map_contract_defaults.mir.snap | 104 +- ...act_field_layout_slots_const_hole.mir.snap | 104 +- crates/mir/tests/fixtures/echo.mir.snap | 112 +- .../mir/tests/fixtures/for_continue.mir.snap | 36 +- .../tests/fixtures/if_let_while_let.mir.snap | 8 +- .../mir/tests/fixtures/kitchen_sink.mir.snap | 44 +- .../mixed_trait_type_effects.mir.snap | 24 +- .../fixtures/mut_param_augassign.mir.snap | 19 +- .../mut_self_transparent_newtype.mir.snap | 8 +- .../fixtures/transient_field_effects.mir.snap | 39 +- .../tests/fixtures/while_cond_call.mir.snap | 16 +- .../fixtures/zst_load_index_eval.mir.snap | 22 +- ...et_pattern_owned_local_use_after_move.snap | 2 +- ...ch_pattern_owned_local_use_after_move.snap | 2 +- .../uitest/fixtures/ty_check/aug_assign.snap | 6 +- .../const_checked_arithmetic_overflow.fe | 25 + .../const_checked_arithmetic_overflow.snap | 64 + .../trait_assoc_const_mismatch_span.snap | 10 +- ingots/core/src/num.fe | 1129 +++++++++++++++-- ingots/core/src/num_yul.fe | 150 +++ ingots/core/src/ops.fe | 31 + 147 files changed, 12431 insertions(+), 2443 deletions(-) create mode 100644 crates/codegen/tests/fixtures/sonatina_ir/wrapping_saturating.snap create mode 100644 crates/codegen/tests/fixtures/wrapping_saturating.fe create mode 100644 crates/codegen/tests/fixtures/wrapping_saturating.snap create mode 100644 crates/fe/tests/fixtures/fe_test/checked_arithmetic_matrix.fe create mode 100644 crates/fe/tests/fixtures/fe_test/checked_arithmetic_methods.fe create mode 100644 crates/fe/tests/fixtures/fe_test/checked_arithmetic_regressions.fe create mode 100644 crates/fe/tests/fixtures/fe_test/signed_arithmetic.fe create mode 100644 crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.fe create mode 100644 crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.snap create mode 100644 crates/uitest/fixtures/ty_check/const_checked_arithmetic_overflow.fe create mode 100644 crates/uitest/fixtures/ty_check/const_checked_arithmetic_overflow.snap create mode 100644 ingots/core/src/num_yul.fe diff --git a/crates/codegen/src/sonatina/lower.rs b/crates/codegen/src/sonatina/lower.rs index 61b1e6fa5a..19dd123147 100644 --- a/crates/codegen/src/sonatina/lower.rs +++ b/crates/codegen/src/sonatina/lower.rs @@ -7,7 +7,10 @@ use hir::analysis::ty::adt_def::AdtRef; use hir::analysis::ty::ty_def::{PrimTy, TyBase, TyData}; use hir::hir_def::expr::{ArithBinOp, BinOp, CompBinOp, LogicalBinOp, UnOp}; use hir::projection::{IndexSource, Projection}; -use mir::ir::{AddressSpaceKind, IntrinsicOp, Place, SyntheticValue}; +use mir::ir::{ + AddressSpaceKind, BuiltinTerminatorKind, CheckedArithmeticOp, CheckedIntrinsic, IntrinsicOp, + Place, SyntheticValue, +}; use mir::layout; use mir::layout::TargetDataLayout; use num_bigint::BigUint; @@ -17,9 +20,9 @@ use sonatina_ir::{ BlockId, GlobalVariableData, I256, Immediate, Linkage, Type, Value, ValueId, global_variable::GvInitializer, inst::{ - arith::{Add, Mul, Neg, Shl, Shr, Sub}, + arith::{Add, Mul, Neg, Sar, Shl, Shr, Sub}, cast::{Bitcast, IntToPtr, PtrToInt, Sext, Trunc, Zext}, - cmp::{Eq, Gt, IsZero, Lt, Ne}, + cmp::{Eq, Gt, IsZero, Lt, Ne, Slt}, control_flow::{Br, BrTable, Call, Jump, Return}, data::{Alloca, Gep, Mload, Mstore, SymAddr, SymSize, SymbolRef}, evm::{ @@ -28,9 +31,9 @@ use sonatina_ir::{ EvmCodeSize, EvmCoinBase, EvmCreate, EvmCreate2, EvmDelegateCall, EvmExp, EvmGas, EvmGasLimit, EvmInvalid, EvmKeccak256, EvmLog0, EvmLog1, EvmLog2, EvmLog3, EvmLog4, EvmMalloc, EvmMsize, EvmMstore8, EvmMulMod, EvmNumber, EvmOrigin, EvmPrevRandao, - EvmReturn, EvmReturnDataCopy, EvmReturnDataSize, EvmRevert, EvmSelfBalance, - EvmSelfDestruct, EvmSload, EvmSstore, EvmStaticCall, EvmStop, EvmTimestamp, EvmTload, - EvmTstore, EvmUdiv, EvmUmod, + EvmReturn, EvmReturnDataCopy, EvmReturnDataSize, EvmRevert, EvmSdiv, EvmSelfBalance, + EvmSelfDestruct, EvmSload, EvmSmod, EvmSstore, EvmStaticCall, EvmStop, EvmTimestamp, + EvmTload, EvmTstore, EvmUdiv, EvmUmod, }, logic::{And, Not, Or, Xor}, }, @@ -143,6 +146,16 @@ fn lower_rvalue<'db, C: sonatina_ir::func_cursor::FuncCursor>( Ok(Some(val)) } Rvalue::Call(call) => { + if let Some(checked) = call.checked_intrinsic { + if !call.effect_args.is_empty() { + return Err(LowerError::Internal(format!( + "checked intrinsic call unexpectedly has effect args: {checked:?}" + ))); + } + let result = lower_checked_intrinsic(ctx, checked, &call.args)?; + return Ok(Some(result)); + } + // Get the callee function reference let callee_name = call.resolved_name.as_ref().ok_or_else(|| { LowerError::Unsupported("call without resolved symbol name".to_string()) @@ -481,6 +494,15 @@ fn lower_rvalue<'db, C: sonatina_ir::func_cursor::FuncCursor>( } } + // Core numeric intrinsics (extern functions from `core::num`). + // All integer types are represented as I256 on the EVM, so the same + // Sonatina instructions apply regardless of the Fe type suffix. + if call.effect_args.is_empty() + && let Some(result) = try_lower_numeric_intrinsic(ctx, callee_name, &call.args)? + { + return Ok(Some(result)); + } + let func_ref = ctx .name_map .get(callee_name) @@ -676,7 +698,8 @@ fn lower_value_origin<'db, C: sonatina_ir::func_cursor::FuncCursor>( let var = ctx.local_vars.get(local_id).copied().ok_or_else(|| { LowerError::Internal(format!("SSA variable not found for local {local_id:?}")) })?; - Ok(ctx.fb.use_var(var)) + let val = ctx.fb.use_var(var); + Ok(val) } ValueOrigin::Unit => { // Unit is represented as 0 @@ -1864,9 +1887,22 @@ pub(super) fn lower_terminator<'db, C: sonatina_ir::func_cursor::FuncCursor>( } } - let func_ref = ctx.name_map.get(callee_name).ok_or_else(|| { - LowerError::Internal(format!("unknown function: {callee_name}")) - })?; + if let Some(builtin) = call.builtin_terminator { + match builtin { + BuiltinTerminatorKind::Abort => { + let zero = ctx.fb.make_imm_value(I256::zero()); + ctx.fb + .insert_inst_no_result(EvmRevert::new(ctx.is, zero, zero)); + return Ok(()); + } + } + } + + let Some(func_ref) = ctx.name_map.get(callee_name) else { + return Err(LowerError::Internal(format!( + "missing sonatina callee for terminating call: {callee_name}" + ))); + }; let args = lower_call_args( ctx, @@ -2341,3 +2377,618 @@ fn bitcast_ptr<'db, C: sonatina_ir::func_cursor::FuncCursor>( ctx.fb .insert_inst(Bitcast::new(ctx.is, ptr, ptr_ty), ptr_ty) } + +/// Returns `true` if the callee name suffix indicates a signed type. +fn is_signed_type(callee_name: &str) -> bool { + callee_name.ends_with("_i8") + || callee_name.ends_with("_i16") + || callee_name.ends_with("_i32") + || callee_name.ends_with("_i64") + || callee_name.ends_with("_i128") + || callee_name.ends_with("_i256") + || callee_name.ends_with("_isize") +} + +/// Emit a conditional branch to a revert block if `overflow_flag` (I1) is true. +/// Returns the continue block that execution falls through to on no overflow. +fn emit_overflow_revert( + fb: &mut sonatina_ir::builder::FunctionBuilder, + is: &sonatina_ir::inst::evm::inst_set::EvmInstSet, + overflow_flag: ValueId, +) -> BlockId { + let revert_block = fb.append_block(); + let continue_block = fb.append_block(); + fb.insert_inst_no_result(Br::new(is, overflow_flag, revert_block, continue_block)); + fb.switch_to_block(revert_block); + let zero = fb.make_imm_value(I256::zero()); + fb.insert_inst_no_result(EvmRevert::new(is, zero, zero)); + fb.switch_to_block(continue_block); + continue_block +} + +fn checked_intrinsic_prim<'db>( + db: &'db DriverDataBase, + ty: hir::analysis::ty::ty_def::TyId<'db>, +) -> Result { + let base_ty = ty.base_ty(db); + let TyData::TyBase(TyBase::Prim(prim)) = base_ty.data(db) else { + return Err(LowerError::Internal(format!( + "checked intrinsic type must be a primitive integer, got `{}`", + ty.pretty_print(db) + ))); + }; + if !prim.is_integral() { + return Err(LowerError::Internal(format!( + "checked intrinsic type must be integral, got `{}`", + ty.pretty_print(db) + ))); + } + Ok(*prim) +} + +fn checked_intrinsic_value_type(prim: PrimTy) -> Result { + match prim { + PrimTy::U8 | PrimTy::I8 => Ok(Type::I8), + PrimTy::U16 | PrimTy::I16 => Ok(Type::I16), + PrimTy::U32 | PrimTy::I32 => Ok(Type::I32), + PrimTy::U64 | PrimTy::I64 => Ok(Type::I64), + PrimTy::U128 | PrimTy::I128 => Ok(Type::I128), + PrimTy::U256 | PrimTy::I256 | PrimTy::Usize | PrimTy::Isize => Ok(Type::I256), + _ => Err(LowerError::Internal(format!( + "checked intrinsic type must be integral, got `{prim:?}`" + ))), + } +} + +fn lower_checked_operand( + fb: &mut sonatina_ir::builder::FunctionBuilder, + is: &sonatina_ir::inst::evm::inst_set::EvmInstSet, + value: ValueId, + op_ty: Type, +) -> ValueId { + if op_ty == Type::I256 { + value + } else { + fb.insert_inst(Trunc::new(is, value, op_ty), op_ty) + } +} + +fn extend_checked_result( + fb: &mut sonatina_ir::builder::FunctionBuilder, + is: &sonatina_ir::inst::evm::inst_set::EvmInstSet, + value: ValueId, + prim: PrimTy, + op_ty: Type, +) -> ValueId { + if op_ty == Type::I256 { + value + } else if prim_is_signed(prim) { + fb.insert_inst(Sext::new(is, value, Type::I256), Type::I256) + } else { + fb.insert_inst(Zext::new(is, value, Type::I256), Type::I256) + } +} + +fn i256_min_immediate( + fb: &mut sonatina_ir::builder::FunctionBuilder, +) -> ValueId { + let mut bytes = [0u8; 32]; + bytes[0] = 0x80; + fb.make_imm_value(I256::from_be_bytes(&bytes)) +} + +fn i256_neg_one_immediate( + fb: &mut sonatina_ir::builder::FunctionBuilder, +) -> ValueId { + fb.make_imm_value(I256::all_one()) +} + +fn lower_checked_intrinsic<'db, C: sonatina_ir::func_cursor::FuncCursor>( + ctx: &mut LowerCtx<'_, 'db, C>, + checked: CheckedIntrinsic<'db>, + args: &[mir::ir::ValueId], +) -> Result { + let prim = checked_intrinsic_prim(ctx.db, checked.ty)?; + let op_ty = checked_intrinsic_value_type(prim)?; + let signed = prim_is_signed(prim); + + match checked.op { + CheckedArithmeticOp::Add => { + let [a, b] = args else { + return Err(LowerError::Internal(format!( + "checked add expects 2 arguments, got {}", + args.len() + ))); + }; + let lhs_word = lower_value(ctx, *a)?; + let rhs_word = lower_value(ctx, *b)?; + let lhs = lower_checked_operand(ctx.fb, ctx.is, lhs_word, op_ty); + let rhs = lower_checked_operand(ctx.fb, ctx.is, rhs_word, op_ty); + let raw = ctx.fb.insert_inst(Add::new(ctx.is, lhs, rhs), op_ty); + let lhs_ext = extend_checked_result(ctx.fb, ctx.is, lhs, prim, op_ty); + let rhs_ext = extend_checked_result(ctx.fb, ctx.is, rhs, prim, op_ty); + let result = extend_checked_result(ctx.fb, ctx.is, raw, prim, op_ty); + let overflow = if signed { + let zero = ctx.fb.make_imm_value(I256::zero()); + let a_neg = ctx + .fb + .insert_inst(Slt::new(ctx.is, lhs_ext, zero), Type::I1); + let b_neg = ctx + .fb + .insert_inst(Slt::new(ctx.is, rhs_ext, zero), Type::I1); + let r_neg = ctx.fb.insert_inst(Slt::new(ctx.is, result, zero), Type::I1); + let signs_same = ctx.fb.insert_inst(Eq::new(ctx.is, a_neg, b_neg), Type::I1); + let sign_changed_eq = ctx.fb.insert_inst(Eq::new(ctx.is, a_neg, r_neg), Type::I1); + let sign_changed = ctx + .fb + .insert_inst(IsZero::new(ctx.is, sign_changed_eq), Type::I1); + ctx.fb + .insert_inst(And::new(ctx.is, signs_same, sign_changed), Type::I1) + } else { + ctx.fb + .insert_inst(Lt::new(ctx.is, result, lhs_ext), Type::I1) + }; + emit_overflow_revert(ctx.fb, ctx.is, overflow); + Ok(result) + } + CheckedArithmeticOp::Sub => { + let [a, b] = args else { + return Err(LowerError::Internal(format!( + "checked sub expects 2 arguments, got {}", + args.len() + ))); + }; + let lhs_word = lower_value(ctx, *a)?; + let rhs_word = lower_value(ctx, *b)?; + let lhs = lower_checked_operand(ctx.fb, ctx.is, lhs_word, op_ty); + let rhs = lower_checked_operand(ctx.fb, ctx.is, rhs_word, op_ty); + let raw = ctx.fb.insert_inst(Sub::new(ctx.is, lhs, rhs), op_ty); + let lhs_ext = extend_checked_result(ctx.fb, ctx.is, lhs, prim, op_ty); + let rhs_ext = extend_checked_result(ctx.fb, ctx.is, rhs, prim, op_ty); + let result = extend_checked_result(ctx.fb, ctx.is, raw, prim, op_ty); + let overflow = if signed { + let zero = ctx.fb.make_imm_value(I256::zero()); + let a_neg = ctx + .fb + .insert_inst(Slt::new(ctx.is, lhs_ext, zero), Type::I1); + let b_neg = ctx + .fb + .insert_inst(Slt::new(ctx.is, rhs_ext, zero), Type::I1); + let r_neg = ctx.fb.insert_inst(Slt::new(ctx.is, result, zero), Type::I1); + let signs_diff_eq = ctx.fb.insert_inst(Eq::new(ctx.is, a_neg, b_neg), Type::I1); + let signs_diff = ctx + .fb + .insert_inst(IsZero::new(ctx.is, signs_diff_eq), Type::I1); + let sign_changed_eq = ctx.fb.insert_inst(Eq::new(ctx.is, a_neg, r_neg), Type::I1); + let sign_changed = ctx + .fb + .insert_inst(IsZero::new(ctx.is, sign_changed_eq), Type::I1); + ctx.fb + .insert_inst(And::new(ctx.is, signs_diff, sign_changed), Type::I1) + } else { + ctx.fb + .insert_inst(Gt::new(ctx.is, rhs_ext, lhs_ext), Type::I1) + }; + emit_overflow_revert(ctx.fb, ctx.is, overflow); + Ok(result) + } + CheckedArithmeticOp::Mul => { + let [a, b] = args else { + return Err(LowerError::Internal(format!( + "checked mul expects 2 arguments, got {}", + args.len() + ))); + }; + let lhs_word = lower_value(ctx, *a)?; + let rhs_word = lower_value(ctx, *b)?; + let lhs = lower_checked_operand(ctx.fb, ctx.is, lhs_word, op_ty); + let rhs = lower_checked_operand(ctx.fb, ctx.is, rhs_word, op_ty); + let raw = ctx.fb.insert_inst(Mul::new(ctx.is, lhs, rhs), op_ty); + let lhs_ext = extend_checked_result(ctx.fb, ctx.is, lhs, prim, op_ty); + let rhs_ext = extend_checked_result(ctx.fb, ctx.is, rhs, prim, op_ty); + let result = extend_checked_result(ctx.fb, ctx.is, raw, prim, op_ty); + let overflow = if signed { + let zero = ctx.fb.make_imm_value(I256::zero()); + let a_nz = ctx.fb.insert_inst(Ne::new(ctx.is, lhs_ext, zero), Type::I1); + let quot = ctx + .fb + .insert_inst(EvmSdiv::new(ctx.is, result, lhs_ext), Type::I256); + let quot_ne_b = ctx.fb.insert_inst(Ne::new(ctx.is, quot, rhs_ext), Type::I1); + let div_mismatch = ctx + .fb + .insert_inst(And::new(ctx.is, a_nz, quot_ne_b), Type::I1); + if op_ty == Type::I256 { + let min = i256_min_immediate(ctx.fb); + let neg_one = i256_neg_one_immediate(ctx.fb); + let lhs_is_neg_one = ctx + .fb + .insert_inst(Eq::new(ctx.is, lhs_ext, neg_one), Type::I1); + let rhs_is_neg_one = ctx + .fb + .insert_inst(Eq::new(ctx.is, rhs_ext, neg_one), Type::I1); + let lhs_is_min = ctx.fb.insert_inst(Eq::new(ctx.is, lhs_ext, min), Type::I1); + let rhs_is_min = ctx.fb.insert_inst(Eq::new(ctx.is, rhs_ext, min), Type::I1); + let lhs_neg_one_rhs_min = ctx + .fb + .insert_inst(And::new(ctx.is, lhs_is_neg_one, rhs_is_min), Type::I1); + let rhs_neg_one_lhs_min = ctx + .fb + .insert_inst(And::new(ctx.is, rhs_is_neg_one, lhs_is_min), Type::I1); + let min_times_neg_one = ctx.fb.insert_inst( + Or::new(ctx.is, lhs_neg_one_rhs_min, rhs_neg_one_lhs_min), + Type::I1, + ); + ctx.fb + .insert_inst(Or::new(ctx.is, div_mismatch, min_times_neg_one), Type::I1) + } else { + div_mismatch + } + } else { + let zero = ctx.fb.make_imm_value(I256::zero()); + let a_nz = ctx.fb.insert_inst(Ne::new(ctx.is, lhs_ext, zero), Type::I1); + let quot = ctx + .fb + .insert_inst(EvmUdiv::new(ctx.is, result, lhs_ext), Type::I256); + let quot_ne_b = ctx.fb.insert_inst(Ne::new(ctx.is, quot, rhs_ext), Type::I1); + ctx.fb + .insert_inst(And::new(ctx.is, a_nz, quot_ne_b), Type::I1) + }; + emit_overflow_revert(ctx.fb, ctx.is, overflow); + Ok(result) + } + CheckedArithmeticOp::Neg => { + let [arg] = args else { + return Err(LowerError::Internal(format!( + "checked neg expects 1 argument, got {}", + args.len() + ))); + }; + if !signed { + return Err(LowerError::Internal(format!( + "checked neg is not defined for unsigned type `{}`", + checked.ty.pretty_print(ctx.db) + ))); + } + let val_word = lower_value(ctx, *arg)?; + let val = lower_checked_operand(ctx.fb, ctx.is, val_word, op_ty); + let zero = ctx.fb.make_imm_value(I256::zero()); + let zero_narrow = if op_ty == Type::I256 { + zero + } else { + ctx.fb.insert_inst(Trunc::new(ctx.is, zero, op_ty), op_ty) + }; + let raw = ctx + .fb + .insert_inst(Sub::new(ctx.is, zero_narrow, val), op_ty); + let result = extend_checked_result(ctx.fb, ctx.is, raw, prim, op_ty); + let val_ext = extend_checked_result(ctx.fb, ctx.is, val, prim, op_ty); + let x_nz = ctx.fb.insert_inst(Ne::new(ctx.is, val_ext, zero), Type::I1); + let r_eq_x = ctx + .fb + .insert_inst(Eq::new(ctx.is, result, val_ext), Type::I1); + let overflow = ctx.fb.insert_inst(And::new(ctx.is, x_nz, r_eq_x), Type::I1); + emit_overflow_revert(ctx.fb, ctx.is, overflow); + Ok(result) + } + } +} + +/// Valid type suffixes for core numeric intrinsics. +const INTRINSIC_TYPE_SUFFIXES: &[&str] = &[ + "_u8", "_u16", "_u32", "_u64", "_u128", "_u256", "_usize", "_i8", "_i16", "_i32", "_i64", + "_i128", "_i256", "_isize", "_bool", +]; + +/// Describes how to mask a sub-256-bit arithmetic result. +enum SubWordMask { + /// Unsigned: apply `and(result, mask)` + Unsigned { mask: I256 }, + /// Signed: truncate to `narrow_ty` then sign-extend back to I256 + Signed { narrow_ty: Type }, +} + +/// Returns the masking info for a sub-256-bit intrinsic, or `None` for 256-bit +/// types that don't need masking. +fn sub_word_mask(callee_name: &str) -> Option { + if callee_name.ends_with("_u8") { + Some(SubWordMask::Unsigned { + mask: I256::from(0xffu64), + }) + } else if callee_name.ends_with("_u16") { + Some(SubWordMask::Unsigned { + mask: I256::from(0xffffu64), + }) + } else if callee_name.ends_with("_u32") { + Some(SubWordMask::Unsigned { + mask: I256::from(0xffff_ffffu64), + }) + } else if callee_name.ends_with("_u64") { + Some(SubWordMask::Unsigned { + mask: I256::from(0xffff_ffff_ffff_ffffu64), + }) + } else if callee_name.ends_with("_u128") { + let mut bytes = [0u8; 32]; + for b in &mut bytes[16..32] { + *b = 0xff; + } + Some(SubWordMask::Unsigned { + mask: I256::from_be_bytes(&bytes), + }) + } else if callee_name.ends_with("_i8") { + Some(SubWordMask::Signed { + narrow_ty: Type::I8, + }) + } else if callee_name.ends_with("_i16") { + Some(SubWordMask::Signed { + narrow_ty: Type::I16, + }) + } else if callee_name.ends_with("_i32") { + Some(SubWordMask::Signed { + narrow_ty: Type::I32, + }) + } else if callee_name.ends_with("_i64") { + Some(SubWordMask::Signed { + narrow_ty: Type::I64, + }) + } else if callee_name.ends_with("_i128") { + Some(SubWordMask::Signed { + narrow_ty: Type::I128, + }) + } else { + None // u256, i256, usize, bool - no masking needed + } +} + +/// Apply sub-256-bit masking to an arithmetic result. +fn apply_sub_word_mask( + fb: &mut sonatina_ir::builder::FunctionBuilder, + is: &sonatina_ir::inst::evm::inst_set::EvmInstSet, + result: ValueId, + mask_info: &SubWordMask, +) -> ValueId { + match mask_info { + SubWordMask::Unsigned { mask } => { + let mask_val = fb.make_imm_value(*mask); + fb.insert_inst(And::new(is, result, mask_val), Type::I256) + } + SubWordMask::Signed { narrow_ty, .. } => { + let truncated = fb.insert_inst(Trunc::new(is, result, *narrow_ty), *narrow_ty); + fb.insert_inst(Sext::new(is, truncated, Type::I256), Type::I256) + } + } +} + +/// Try to lower a `___` core numeric intrinsic to native Sonatina +/// instructions. Returns `Ok(Some(value))` if the intrinsic was handled, +/// `Ok(None)` if the callee name is not a recognized intrinsic. +fn try_lower_numeric_intrinsic( + ctx: &mut LowerCtx<'_, '_, C>, + callee_name: &str, + args: &[mir::ir::ValueId], +) -> Result, LowerError> { + if !callee_name.starts_with("__") { + return Ok(None); + } + + // Strip the type suffix to get the operation name. + let op = INTRINSIC_TYPE_SUFFIXES + .iter() + .find_map(|suffix| callee_name.strip_suffix(suffix)) + .and_then(|s| s.strip_prefix("__")); + + let Some(op) = op else { + return Ok(None); + }; + + if op.starts_with("checked_") { + return Err(LowerError::Internal(format!( + "checked arithmetic intrinsic `{callee_name}` must be lowered via typed checked metadata" + ))); + } + + // Precompute sub-word masking info (shared by comparisons and arithmetic). + let mask_info = sub_word_mask(callee_name); + + match op { + // --- Binary comparison ops (normalize operands for sub-word types) --- + "lt" | "gt" | "eq" | "ne" | "le" | "ge" => { + let (mut lhs, mut rhs) = lower_binary_args(ctx, callee_name, args)?; + // Normalize operands so comparisons work regardless of upper-bit state. + if let Some(ref mi) = mask_info { + lhs = apply_sub_word_mask(ctx.fb, ctx.is, lhs, mi); + rhs = apply_sub_word_mask(ctx.fb, ctx.is, rhs, mi); + } + let signed = is_signed_type(callee_name); + let cmp = match op { + "lt" => { + if signed { + ctx.fb.insert_inst(Slt::new(ctx.is, lhs, rhs), Type::I1) + } else { + ctx.fb.insert_inst(Lt::new(ctx.is, lhs, rhs), Type::I1) + } + } + "gt" => { + if signed { + ctx.fb.insert_inst(Slt::new(ctx.is, rhs, lhs), Type::I1) + } else { + ctx.fb.insert_inst(Gt::new(ctx.is, lhs, rhs), Type::I1) + } + } + "eq" => ctx.fb.insert_inst(Eq::new(ctx.is, lhs, rhs), Type::I1), + "ne" => { + let eq = ctx.fb.insert_inst(Eq::new(ctx.is, lhs, rhs), Type::I1); + ctx.fb.insert_inst(IsZero::new(ctx.is, eq), Type::I1) + } + "le" => { + let gt = if signed { + ctx.fb.insert_inst(Slt::new(ctx.is, rhs, lhs), Type::I1) + } else { + ctx.fb.insert_inst(Gt::new(ctx.is, lhs, rhs), Type::I1) + }; + ctx.fb.insert_inst(IsZero::new(ctx.is, gt), Type::I1) + } + "ge" => { + let lt = if signed { + ctx.fb.insert_inst(Slt::new(ctx.is, lhs, rhs), Type::I1) + } else { + ctx.fb.insert_inst(Lt::new(ctx.is, lhs, rhs), Type::I1) + }; + ctx.fb.insert_inst(IsZero::new(ctx.is, lt), Type::I1) + } + _ => unreachable!(), + }; + Ok(Some(ctx.fb.insert_inst( + Zext::new(ctx.is, cmp, Type::I256), + Type::I256, + ))) + } + + // --- Binary arithmetic ops (may need sub-word masking) --- + "add" | "sub" | "mul" | "pow" | "shl" => { + let (lhs, rhs) = lower_binary_args(ctx, callee_name, args)?; + let raw = match op { + "add" => ctx.fb.insert_inst(Add::new(ctx.is, lhs, rhs), Type::I256), + "sub" => ctx.fb.insert_inst(Sub::new(ctx.is, lhs, rhs), Type::I256), + "mul" => ctx.fb.insert_inst(Mul::new(ctx.is, lhs, rhs), Type::I256), + "pow" => ctx + .fb + .insert_inst(EvmExp::new(ctx.is, lhs, rhs), Type::I256), + "shl" => ctx.fb.insert_inst(Shl::new(ctx.is, rhs, lhs), Type::I256), + _ => unreachable!(), + }; + let result = if let Some(ref mi) = mask_info { + apply_sub_word_mask(ctx.fb, ctx.is, raw, mi) + } else { + raw + }; + Ok(Some(result)) + } + // div/rem/shr: signed types need sign-extended operands + signed instructions. + "div" => { + let (mut lhs, mut rhs) = lower_binary_args(ctx, callee_name, args)?; + if is_signed_type(callee_name) { + if let Some(ref mi) = mask_info { + lhs = apply_sub_word_mask(ctx.fb, ctx.is, lhs, mi); + rhs = apply_sub_word_mask(ctx.fb, ctx.is, rhs, mi); + } + Ok(Some( + ctx.fb + .insert_inst(EvmSdiv::new(ctx.is, lhs, rhs), Type::I256), + )) + } else { + Ok(Some( + ctx.fb + .insert_inst(EvmUdiv::new(ctx.is, lhs, rhs), Type::I256), + )) + } + } + "rem" => { + let (mut lhs, mut rhs) = lower_binary_args(ctx, callee_name, args)?; + if is_signed_type(callee_name) { + if let Some(ref mi) = mask_info { + lhs = apply_sub_word_mask(ctx.fb, ctx.is, lhs, mi); + rhs = apply_sub_word_mask(ctx.fb, ctx.is, rhs, mi); + } + Ok(Some( + ctx.fb + .insert_inst(EvmSmod::new(ctx.is, lhs, rhs), Type::I256), + )) + } else { + Ok(Some( + ctx.fb + .insert_inst(EvmUmod::new(ctx.is, lhs, rhs), Type::I256), + )) + } + } + "shr" => { + let (lhs, rhs) = lower_binary_args(ctx, callee_name, args)?; + if is_signed_type(callee_name) { + let val = if let Some(ref mi) = mask_info { + apply_sub_word_mask(ctx.fb, ctx.is, lhs, mi) + } else { + lhs + }; + Ok(Some( + ctx.fb.insert_inst(Sar::new(ctx.is, rhs, val), Type::I256), + )) + } else { + Ok(Some( + ctx.fb.insert_inst(Shr::new(ctx.is, rhs, lhs), Type::I256), + )) + } + } + + // --- Bitwise binary ops (don't need masking) --- + "bitand" => { + let (lhs, rhs) = lower_binary_args(ctx, callee_name, args)?; + Ok(Some( + ctx.fb.insert_inst(And::new(ctx.is, lhs, rhs), Type::I256), + )) + } + "bitor" => { + let (lhs, rhs) = lower_binary_args(ctx, callee_name, args)?; + Ok(Some( + ctx.fb.insert_inst(Or::new(ctx.is, lhs, rhs), Type::I256), + )) + } + "bitxor" => { + let (lhs, rhs) = lower_binary_args(ctx, callee_name, args)?; + Ok(Some( + ctx.fb.insert_inst(Xor::new(ctx.is, lhs, rhs), Type::I256), + )) + } + + // --- Unary ops (may need sub-word masking) --- + "bitnot" | "not" => { + let val = lower_unary_arg(ctx, callee_name, args)?; + let raw = ctx.fb.insert_inst(Not::new(ctx.is, val), Type::I256); + let result = if let Some(ref mi) = mask_info { + apply_sub_word_mask(ctx.fb, ctx.is, raw, mi) + } else { + raw + }; + Ok(Some(result)) + } + "neg" => { + let val = lower_unary_arg(ctx, callee_name, args)?; + let raw = ctx.fb.insert_inst(Neg::new(ctx.is, val), Type::I256); + let result = if let Some(ref mi) = mask_info { + apply_sub_word_mask(ctx.fb, ctx.is, raw, mi) + } else { + raw + }; + Ok(Some(result)) + } + + // Not a recognized intrinsic operation. + _ => Ok(None), + } +} + +fn lower_binary_args( + ctx: &mut LowerCtx<'_, '_, C>, + callee_name: &str, + args: &[mir::ir::ValueId], +) -> Result<(ValueId, ValueId), LowerError> { + let [a, b] = args else { + return Err(LowerError::Internal(format!( + "{callee_name} requires 2 arguments" + ))); + }; + let lhs = lower_value(ctx, *a)?; + let rhs = lower_value(ctx, *b)?; + Ok((lhs, rhs)) +} + +fn lower_unary_arg( + ctx: &mut LowerCtx<'_, '_, C>, + callee_name: &str, + args: &[mir::ir::ValueId], +) -> Result { + let [a] = args else { + return Err(LowerError::Internal(format!( + "{callee_name} requires 1 argument" + ))); + }; + lower_value(ctx, *a) +} diff --git a/crates/codegen/src/sonatina/tests.rs b/crates/codegen/src/sonatina/tests.rs index c4c3f11136..77c98de89c 100644 --- a/crates/codegen/src/sonatina/tests.rs +++ b/crates/codegen/src/sonatina/tests.rs @@ -77,6 +77,7 @@ pub fn emit_test_module_sonatina( ) -> Result { let ingot = top_mod.ingot(db); let mir_module = lower_ingot(db, ingot)?; + let tests = collect_tests(db, &mir_module.functions); if tests.is_empty() { diff --git a/crates/codegen/src/yul/emitter/control_flow.rs b/crates/codegen/src/yul/emitter/control_flow.rs index 769cb36537..a1a3e2758d 100644 --- a/crates/codegen/src/yul/emitter/control_flow.rs +++ b/crates/codegen/src/yul/emitter/control_flow.rs @@ -2,7 +2,7 @@ use mir::{ BasicBlockId, LoopInfo, Terminator, ValueId, - ir::{IntrinsicValue, SwitchTarget, SwitchValue}, + ir::{BuiltinTerminatorKind, IntrinsicValue, SwitchTarget, SwitchValue}, }; use rustc_hash::{FxHashMap, FxHashSet}; @@ -127,6 +127,14 @@ impl<'db> FunctionEmitter<'db> { } Terminator::TerminatingCall { call, .. } => match call { mir::TerminatingCall::Call(call) => { + if let Some(builtin) = call.builtin_terminator { + match builtin { + BuiltinTerminatorKind::Abort => { + ctx.docs.push(YulDoc::line("revert(0, 0)")); + return Ok(()); + } + } + } let call_expr = self.lower_call_value(call, ctx.state)?; ctx.docs.push(YulDoc::line(call_expr)); Ok(()) diff --git a/crates/codegen/src/yul/emitter/expr.rs b/crates/codegen/src/yul/emitter/expr.rs index 53dea86d52..6384b15008 100644 --- a/crates/codegen/src/yul/emitter/expr.rs +++ b/crates/codegen/src/yul/emitter/expr.rs @@ -24,6 +24,331 @@ use super::{ }; impl<'db> FunctionEmitter<'db> { + /// Attempts to lower a call to a core numeric intrinsic directly to inline Yul. + /// + /// This is an optimization that avoids generating separate Yul functions for + /// primitive arithmetic intrinsics like `__add_u8`, `__sub_i32`, `__mul_u256`, etc. + /// Instead, it recognizes the naming pattern `___` and emits the + /// corresponding Yul opcode inline with appropriate bit masking. + /// + /// For types smaller than 256 bits, proper masking is applied: + /// - **Unsigned types**: Results are masked with `and(result, mask)` to truncate + /// overflow bits (e.g., `u8` uses mask `0xff`). + /// - **Signed types**: Results use `signextend(byte, and(value, mask))` to + /// correctly propagate the sign bit. + /// - **256-bit types** (`u256`, `i256`): No masking needed. + /// + /// # Parameters + /// - `call`: The call origin containing the target function and arguments. + /// - `state`: Current block state for lowering argument values. + /// + /// # Returns + /// - `Ok(Some(yul))`: The intrinsic was recognized and lowered to inline Yul. + /// - `Ok(None)`: The call is not a recognized core numeric intrinsic; the caller + /// should fall back to normal function call emission. + /// - `Err(...)`: An error occurred during lowering. + fn try_lower_core_numeric_intrinsic_call( + &self, + call: &CallOrigin<'_>, + state: &BlockState, + ) -> Result, YulError> { + let Some(target) = call.hir_target.as_ref() else { + return Ok(None); + }; + let CallableDef::Func(func) = target.callable_def else { + return Ok(None); + }; + if func.body(self.db).is_some() { + return Ok(None); + } + + match target.callable_def.ingot(self.db).kind(self.db) { + IngotKind::Core | IngotKind::Std => {} + _ => return Ok(None), + } + + let Some(name) = target.callable_def.name(self.db) else { + return Ok(None); + }; + let name = name.data(self.db).as_str(); + if name == "__bitcast" || !name.starts_with("__") { + return Ok(None); + } + + let Some((op, suffix)) = name[2..].rsplit_once('_') else { + return Ok(None); + }; + + let mut lowered_args = Vec::with_capacity(call.args.len()); + for &arg in &call.args { + lowered_args.push(self.lower_value(arg, state)?); + } + if !call.effect_args.is_empty() { + return Err(YulError::Unsupported(format!( + "core numeric intrinsic `{name}` unexpectedly has effect args" + ))); + } + + #[derive(Clone, Copy, Debug)] + enum IntPrim { + Unsigned { + mask: Option<&'static str>, + }, + Signed { + mask: Option<&'static str>, + signextend_byte: Option, + }, + } + + fn int_prim_from_suffix(suffix: &str) -> Option { + Some(match suffix { + "u8" => IntPrim::Unsigned { mask: Some("0xff") }, + "u16" => IntPrim::Unsigned { + mask: Some("0xffff"), + }, + "u32" => IntPrim::Unsigned { + mask: Some("0xffffffff"), + }, + "u64" => IntPrim::Unsigned { + mask: Some("0xffffffffffffffff"), + }, + "u128" => IntPrim::Unsigned { + mask: Some("0xffffffffffffffffffffffffffffffff"), + }, + "u256" | "usize" => IntPrim::Unsigned { mask: None }, + "i8" => IntPrim::Signed { + mask: Some("0xff"), + signextend_byte: Some(0), + }, + "i16" => IntPrim::Signed { + mask: Some("0xffff"), + signextend_byte: Some(1), + }, + "i32" => IntPrim::Signed { + mask: Some("0xffffffff"), + signextend_byte: Some(3), + }, + "i64" => IntPrim::Signed { + mask: Some("0xffffffffffffffff"), + signextend_byte: Some(7), + }, + "i128" => IntPrim::Signed { + mask: Some("0xffffffffffffffffffffffffffffffff"), + signextend_byte: Some(15), + }, + "i256" | "isize" => IntPrim::Signed { + mask: None, + signextend_byte: None, + }, + _ => return None, + }) + } + + fn trunc_bits(value: &str, prim: IntPrim) -> String { + match prim { + IntPrim::Unsigned { mask: Some(mask) } + | IntPrim::Signed { + mask: Some(mask), .. + } => { + format!("and({value}, {mask})") + } + IntPrim::Unsigned { mask: None } | IntPrim::Signed { mask: None, .. } => { + value.to_string() + } + } + } + + fn canonical_unsigned(value: &str, mask: Option<&'static str>) -> String { + match mask { + Some(mask) => format!("and({value}, {mask})"), + None => value.to_string(), + } + } + + fn canonical_signed( + value: &str, + mask: Option<&'static str>, + signextend_byte: Option, + ) -> String { + match (mask, signextend_byte) { + (Some(mask), Some(byte)) => format!("signextend({byte}, and({value}, {mask}))"), + _ => value.to_string(), + } + } + + let lowered = if suffix == "bool" { + let normalize_bool = |value: &str| format!("iszero(iszero({value}))"); + + match (op, lowered_args.as_slice()) { + ("not", [arg]) => Some(format!("iszero({})", normalize_bool(arg))), + ("bitand", [lhs, rhs]) => Some(format!( + "and({}, {})", + normalize_bool(lhs), + normalize_bool(rhs) + )), + ("bitor", [lhs, rhs]) => Some(format!( + "or({}, {})", + normalize_bool(lhs), + normalize_bool(rhs) + )), + ("bitxor", [lhs, rhs]) => Some(format!( + "xor({}, {})", + normalize_bool(lhs), + normalize_bool(rhs) + )), + ("eq", [lhs, rhs]) => Some(format!( + "eq({}, {})", + normalize_bool(lhs), + normalize_bool(rhs) + )), + ("ne", [lhs, rhs]) => Some(format!( + "iszero(eq({}, {}))", + normalize_bool(lhs), + normalize_bool(rhs) + )), + _ => None, + } + } else if let Some(int_prim) = int_prim_from_suffix(suffix) { + let (mask, signextend_byte, signed) = match int_prim { + IntPrim::Unsigned { mask } => (mask, None, false), + IntPrim::Signed { + mask, + signextend_byte, + } => (mask, signextend_byte, true), + }; + + let arg_unsigned = |value: &str| canonical_unsigned(value, mask); + let arg_signed = |value: &str| canonical_signed(value, mask, signextend_byte); + let result_unsigned = |value: String| canonical_unsigned(&value, mask); + let result_signed = |value: String| canonical_signed(&value, mask, signextend_byte); + + match (op, lowered_args.as_slice()) { + ("add", [lhs, rhs]) => Some(if signed { + result_signed(format!("add({}, {})", arg_signed(lhs), arg_signed(rhs))) + } else { + result_unsigned(format!("add({}, {})", arg_unsigned(lhs), arg_unsigned(rhs))) + }), + ("sub", [lhs, rhs]) => Some(if signed { + result_signed(format!("sub({}, {})", arg_signed(lhs), arg_signed(rhs))) + } else { + result_unsigned(format!("sub({}, {})", arg_unsigned(lhs), arg_unsigned(rhs))) + }), + ("mul", [lhs, rhs]) => Some(if signed { + result_signed(format!("mul({}, {})", arg_signed(lhs), arg_signed(rhs))) + } else { + result_unsigned(format!("mul({}, {})", arg_unsigned(lhs), arg_unsigned(rhs))) + }), + ("div", [lhs, rhs]) => Some(if signed { + result_signed(format!("sdiv({}, {})", arg_signed(lhs), arg_signed(rhs))) + } else { + result_unsigned(format!("div({}, {})", arg_unsigned(lhs), arg_unsigned(rhs))) + }), + ("rem", [lhs, rhs]) => Some(if signed { + result_signed(format!("smod({}, {})", arg_signed(lhs), arg_signed(rhs))) + } else { + result_unsigned(format!("mod({}, {})", arg_unsigned(lhs), arg_unsigned(rhs))) + }), + ("pow", [lhs, rhs]) => { + let base_bits = trunc_bits(lhs, int_prim); + let exp_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("exp({base_bits}, {exp_bits})")) + } else { + result_unsigned(format!("exp({base_bits}, {exp_bits})")) + }) + } + ("shl", [lhs, rhs]) => { + let value_bits = trunc_bits(lhs, int_prim); + let shift_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("shl({shift_bits}, {value_bits})")) + } else { + result_unsigned(format!("shl({shift_bits}, {value_bits})")) + }) + } + ("shr", [lhs, rhs]) => { + let shift_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("sar({shift_bits}, {})", arg_signed(lhs))) + } else { + result_unsigned(format!("shr({shift_bits}, {})", arg_unsigned(lhs))) + }) + } + ("bitand", [lhs, rhs]) => { + let lhs_bits = trunc_bits(lhs, int_prim); + let rhs_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("and({lhs_bits}, {rhs_bits})")) + } else { + result_unsigned(format!("and({lhs_bits}, {rhs_bits})")) + }) + } + ("bitor", [lhs, rhs]) => { + let lhs_bits = trunc_bits(lhs, int_prim); + let rhs_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("or({lhs_bits}, {rhs_bits})")) + } else { + result_unsigned(format!("or({lhs_bits}, {rhs_bits})")) + }) + } + ("bitxor", [lhs, rhs]) => { + let lhs_bits = trunc_bits(lhs, int_prim); + let rhs_bits = trunc_bits(rhs, int_prim); + Some(if signed { + result_signed(format!("xor({lhs_bits}, {rhs_bits})")) + } else { + result_unsigned(format!("xor({lhs_bits}, {rhs_bits})")) + }) + } + ("bitnot", [arg]) => { + let arg_bits = trunc_bits(arg, int_prim); + Some(if signed { + result_signed(format!("not({arg_bits})")) + } else { + result_unsigned(format!("not({arg_bits})")) + }) + } + ("neg", [arg]) => Some(result_signed(format!("sub(0, {})", arg_signed(arg)))), + ("eq", [lhs, rhs]) => { + let lhs_bits = trunc_bits(lhs, int_prim); + let rhs_bits = trunc_bits(rhs, int_prim); + Some(format!("eq({lhs_bits}, {rhs_bits})")) + } + ("ne", [lhs, rhs]) => { + let lhs_bits = trunc_bits(lhs, int_prim); + let rhs_bits = trunc_bits(rhs, int_prim); + Some(format!("iszero(eq({lhs_bits}, {rhs_bits}))")) + } + ("lt", [lhs, rhs]) => Some(if signed { + format!("slt({}, {})", arg_signed(lhs), arg_signed(rhs)) + } else { + format!("lt({}, {})", arg_unsigned(lhs), arg_unsigned(rhs)) + }), + ("le", [lhs, rhs]) => Some(if signed { + format!("iszero(sgt({}, {}))", arg_signed(lhs), arg_signed(rhs)) + } else { + format!("iszero(gt({}, {}))", arg_unsigned(lhs), arg_unsigned(rhs)) + }), + ("gt", [lhs, rhs]) => Some(if signed { + format!("sgt({}, {})", arg_signed(lhs), arg_signed(rhs)) + } else { + format!("gt({}, {})", arg_unsigned(lhs), arg_unsigned(rhs)) + }), + ("ge", [lhs, rhs]) => Some(if signed { + format!("iszero(slt({}, {}))", arg_signed(lhs), arg_signed(rhs)) + } else { + format!("iszero(lt({}, {}))", arg_unsigned(lhs), arg_unsigned(rhs)) + }), + _ => None, + } + } else { + None + }; + + Ok(lowered) + } + fn format_hir_expr_context(&self, expr: hir::hir_def::ExprId) -> String { let Some(body) = (match self.mir_func.origin { MirFunctionOrigin::Hir(func) => func.body(self.db), @@ -267,6 +592,10 @@ impl<'db> FunctionEmitter<'db> { )); } + if let Some(intrinsic) = self.try_lower_core_numeric_intrinsic_call(call, state)? { + return Ok(intrinsic); + } + let is_evm_op = match call.hir_target.as_ref() { Some(target) => { matches!( diff --git a/crates/codegen/src/yul/emitter/module.rs b/crates/codegen/src/yul/emitter/module.rs index a4cb6fe38c..1622f3bd5a 100644 --- a/crates/codegen/src/yul/emitter/module.rs +++ b/crates/codegen/src/yul/emitter/module.rs @@ -1,10 +1,14 @@ //! Module-level Yul emission helpers (functions + code regions). -use common::ingot::Ingot; +use common::{ + InputDb, + ingot::{Ingot, IngotKind}, +}; use driver::DriverDataBase; use hir::HirDb; use hir::analysis::HirAnalysisDb; -use hir::hir_def::{ItemKind, TopLevelMod}; +use hir::analysis::ty::ty_def::{PrimTy, TyBase, TyData}; +use hir::hir_def::{HirIngot, ItemKind, TopLevelMod}; use mir::analysis::{ CallGraph, ContractRegion, ContractRegionKind, build_call_graph, build_contract_graph, reachable_functions, @@ -84,7 +88,8 @@ pub fn emit_module_yul_with_layout( top_mod: TopLevelMod<'_>, layout: TargetDataLayout, ) -> Result { - let module = lower_module(db, top_mod).map_err(EmitModuleError::MirLower)?; + let mut module = lower_module(db, top_mod).map_err(EmitModuleError::MirLower)?; + link_yul_checked_arithmetic_helpers(db, &mut module)?; emit_lowered_module_yul_with_layout(db, &module, layout) } @@ -98,7 +103,8 @@ pub fn emit_ingot_yul_with_layout( ingot: Ingot<'_>, layout: TargetDataLayout, ) -> Result { - let module = lower_ingot(db, ingot).map_err(EmitModuleError::MirLower)?; + let mut module = lower_ingot(db, ingot).map_err(EmitModuleError::MirLower)?; + link_yul_checked_arithmetic_helpers(db, &mut module)?; emit_lowered_module_yul_with_layout(db, &module, layout) } @@ -302,7 +308,8 @@ pub fn emit_test_module_yul_with_layout( layout: TargetDataLayout, ) -> Result { let ingot = top_mod.ingot(db); - let module = lower_ingot(db, ingot).map_err(EmitModuleError::MirLower)?; + let mut module = lower_ingot(db, ingot).map_err(EmitModuleError::MirLower)?; + link_yul_checked_arithmetic_helpers(db, &mut module)?; let contract_graph = build_contract_graph(&module.functions); @@ -490,6 +497,160 @@ fn sanitize_symbol(component: &str) -> String { .collect() } +fn link_yul_checked_arithmetic_helpers<'db>( + db: &'db DriverDataBase, + module: &mut mir::MirModule<'db>, +) -> Result<(), EmitModuleError> { + fn checked_intrinsic_ty_suffix<'db>( + db: &'db DriverDataBase, + ty: hir::analysis::ty::ty_def::TyId<'db>, + ) -> Result<&'static str, EmitModuleError> { + let base_ty = ty.base_ty(db); + let TyData::TyBase(TyBase::Prim(prim)) = base_ty.data(db) else { + return Err(EmitModuleError::Yul(YulError::Unsupported(format!( + "checked arithmetic helper type must be primitive integral, got `{}`", + ty.pretty_print(db) + )))); + }; + match prim { + PrimTy::U8 => Ok("u8"), + PrimTy::U16 => Ok("u16"), + PrimTy::U32 => Ok("u32"), + PrimTy::U64 => Ok("u64"), + PrimTy::U128 => Ok("u128"), + PrimTy::U256 => Ok("u256"), + PrimTy::Usize => Ok("usize"), + PrimTy::I8 => Ok("i8"), + PrimTy::I16 => Ok("i16"), + PrimTy::I32 => Ok("i32"), + PrimTy::I64 => Ok("i64"), + PrimTy::I128 => Ok("i128"), + PrimTy::I256 => Ok("i256"), + PrimTy::Isize => Ok("isize"), + _ => Err(EmitModuleError::Yul(YulError::Unsupported(format!( + "checked arithmetic helper type must be integral, got `{}`", + ty.pretty_print(db) + )))), + } + } + + fn helper_symbol_from_checked_intrinsic<'db>( + db: &'db DriverDataBase, + intrinsic: mir::ir::CheckedIntrinsic<'db>, + ) -> Result { + let suffix = checked_intrinsic_ty_suffix(db, intrinsic.ty)?; + Ok(format!( + "{}_{}", + intrinsic.op.helper_symbol_prefix(), + suffix + )) + } + + let mut required_helpers = FxHashSet::default(); + for func in &mut module.functions { + for block in &mut func.body.blocks { + for inst in &mut block.insts { + if let MirInst::Assign { + rvalue: Rvalue::Call(call), + .. + } = inst + && let Some(intrinsic) = call.checked_intrinsic + { + let helper = helper_symbol_from_checked_intrinsic(db, intrinsic)?; + required_helpers.insert(helper.clone()); + call.resolved_name = Some(helper); + } + } + + if let mir::Terminator::TerminatingCall { + call: mir::TerminatingCall::Call(call), + .. + } = &mut block.terminator + && let Some(intrinsic) = call.checked_intrinsic + { + let helper = helper_symbol_from_checked_intrinsic(db, intrinsic)?; + required_helpers.insert(helper.clone()); + call.resolved_name = Some(helper); + } + } + } + + if required_helpers.is_empty() { + return Ok(()); + } + + let current_ingot = module.top_mod.ingot(db); + let core_ingot = if current_ingot.kind(db) == IngotKind::Core { + current_ingot + } else { + current_ingot + .resolved_external_ingots(db) + .iter() + .find_map(|(name, ingot)| { + if name.data(db) == "core" { + Some(*ingot) + } else { + None + } + }) + .ok_or_else(|| { + EmitModuleError::Yul(YulError::Unsupported( + "failed to resolve `core` ingot while linking checked arithmetic helpers" + .into(), + )) + })? + }; + + let num_yul_url = core_ingot.base(db).join("src/num_yul.fe").map_err(|_| { + EmitModuleError::Yul(YulError::Unsupported( + "failed to locate `core::num_yul` source while linking checked arithmetic helpers" + .into(), + )) + })?; + let num_yul_file = db.workspace().get(db, &num_yul_url).ok_or_else(|| { + EmitModuleError::Yul(YulError::Unsupported( + "missing `core::num_yul` source while linking checked arithmetic helpers".into(), + )) + })?; + let num_yul_top_mod = db.top_mod(num_yul_file); + + let num_yul_module = lower_module(db, num_yul_top_mod).map_err(EmitModuleError::MirLower)?; + let num_yul_call_graph = build_call_graph(&num_yul_module.functions); + + let mut required_symbols = FxHashSet::default(); + for helper in &required_helpers { + required_symbols.extend(reachable_functions(&num_yul_call_graph, helper)); + } + + let mut by_symbol: FxHashMap<_, _> = num_yul_module + .functions + .into_iter() + .map(|func| (func.symbol_name.clone(), func)) + .collect(); + + let mut known = FxHashSet::default(); + for func in &module.functions { + known.insert(func.symbol_name.clone()); + } + + let mut symbols: Vec<_> = required_symbols.into_iter().collect(); + symbols.sort(); + for symbol in symbols { + if known.contains(&symbol) { + continue; + } + let Some(func) = by_symbol.remove(&symbol) else { + return Err(EmitModuleError::Yul(YulError::Unsupported(format!( + "missing required checked arithmetic helper function `{symbol}`" + )))); + }; + known.insert(symbol); + module.functions.push(func); + } + + Ok(()) +} + struct FunctionDocInfo { docs: Vec, /// Data regions collected during emission for Yul data sections. diff --git a/crates/codegen/tests/fixtures/arg_bindings.snap b/crates/codegen/tests/fixtures/arg_bindings.snap index 40aa2f548a..9bfe66e6a0 100644 --- a/crates/codegen/tests/fixtures/arg_bindings.snap +++ b/crates/codegen/tests/fixtures/arg_bindings.snap @@ -1,11 +1,47 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/arg_bindings.fe --- function $arg_bindings($x, $y) -> ret { - let v0 := add($x, $y) + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($x, $y) + let v1 := v0 + ret := v1 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } ret := v0 leave } +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/aug_assign.snap b/crates/codegen/tests/fixtures/aug_assign.snap index 36a3d8559a..4db991d94f 100644 --- a/crates/codegen/tests/fixtures/aug_assign.snap +++ b/crates/codegen/tests/fixtures/aug_assign.snap @@ -1,13 +1,108 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/aug_assign.fe --- function $aug_assign($x, $y) -> ret { let v0 := $x - v0 := add(v0, $y) - v0 := mul(v0, 2) - ret := div(v0, 2) + let v1 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0, $y) + v0 := v1 + let v2 := $u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul(v0, 2) + v0 := v2 + let v3 := $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v0, 2) + ret := v3 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u64($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := and(div(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v2 + leave +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_mul_u64($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_mul_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := and(mul(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/aug_assign_bit_ops.snap b/crates/codegen/tests/fixtures/aug_assign_bit_ops.snap index 5cd03efd9d..0abd240128 100644 --- a/crates/codegen/tests/fixtures/aug_assign_bit_ops.snap +++ b/crates/codegen/tests/fixtures/aug_assign_bit_ops.snap @@ -1,17 +1,202 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/aug_assign_bit_ops.fe --- function $aug_assign_bit_ops($x, $y) -> ret { let v0 := $x - v0 := exp(v0, $y) - v0 := shl(3, v0) - v0 := shr(1, v0) - v0 := and(v0, 255) - v0 := or(v0, 1) - v0 := xor(v0, 2) + let v1 := $u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow(v0, $y) + v0 := v1 + let v2 := $u256_h3271ca15373d4483_shl_hfe0d524bf4e7a124_shl(v0, 3) + v0 := v2 + let v3 := $u256_h3271ca15373d4483_shr_hb0ca004ad39836df_shr(v0, 1) + v0 := v3 + let v4 := $u256_h3271ca15373d4483_bitand_h78a0a00271c00767_bitand(v0, 255) + v0 := v4 + let v5 := $u256_h3271ca15373d4483_bitor_h862fc0845ef3fe28_bitor(v0, 1) + v0 := v5 + let v6 := $u256_h3271ca15373d4483_bitxor_he2c04823a0ac81d4_bitxor(v0, 2) + v0 := v6 + ret := v0 + leave +} +function $u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow($self, $other) -> ret { + let v0 := $pow_checked__u256__3271ca15373d4483($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_shl_hfe0d524bf4e7a124_shl($self, $other) -> ret { + let v0 := shl($other, $self) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_shr_hb0ca004ad39836df_shr($self, $other) -> ret { + let v0 := shr($other, $self) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_bitand_h78a0a00271c00767_bitand($self, $other) -> ret { + let v0 := and($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_bitor_h862fc0845ef3fe28_bitor($self, $other) -> ret { + let v0 := or($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_bitxor_he2c04823a0ac81d4_bitxor($self, $other) -> ret { + let v0 := xor($self, $other) + ret := v0 + leave +} +function $pow_checked__u256__3271ca15373d4483($base, $exp) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($exp) + let v1 := and(v0, 115792089237316195423570985008687907853269984665640564039457584007913129639935) + let v2 := 0 + if v2 { + let v3 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v1, 0), 0) + let v4 := v3 + if v4 { + revert(0, 0) + } + let v5 := 1 + let v6 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($base) + let v7 := v1 + for { } 1 { } { + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v7, 0) + if iszero(v8) { + break + } + let v9 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v7, 1), 0) + let v10 := v9 + if v10 { + let v11 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v5) + let v12 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v13 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v11, v12) + let v14 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v13) + v5 := v14 + } + v7 := shr(1, v7) + let v15 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v7, 0) + let v16 := v15 + if v16 { + let v17 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v18 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v19 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v17, v18) + let v20 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v19) + v6 := v20 + } + if iszero(v16) { + } + } + let v21 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v5) + ret := v21 + leave + } + if iszero(v2) { + let v22 := 1 + let v23 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($base) + let v24 := v1 + for { } 1 { } { + let v25 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v24, 0) + if iszero(v25) { + break + } + let v26 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v24, 1), 0) + let v27 := v26 + if v27 { + let v28 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v22) + let v29 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v30 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v28, v29) + let v31 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v30) + v22 := v31 + } + v24 := shr(1, v24) + let v32 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v24, 0) + let v33 := v32 + if v33 { + let v34 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v35 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v36 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v34, v35) + let v37 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v36) + v23 := v37 + } + if iszero(v33) { + } + } + let v38 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v22) + ret := v38 + leave + } +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($word) -> ret { + ret := $word + leave +} +function $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u256($self, $other) + ret := v0 + leave +} +function $checked_mul_u256($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } +} +function $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := div($self, $other) + ret := v2 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := mul($self, $other) ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/bit_ops.snap b/crates/codegen/tests/fixtures/bit_ops.snap index 1b6d6b83be..6b04554467 100644 --- a/crates/codegen/tests/fixtures/bit_ops.snap +++ b/crates/codegen/tests/fixtures/bit_ops.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/bit_ops.fe --- @@ -24,6 +23,162 @@ function $bit_ops($x, $y) -> ret { leave } function $pow_op($x, $y) -> ret { - ret := exp($x, $y) + let v0 := $u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow($x, $y) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow($self, $other) -> ret { + let v0 := $pow_checked__u256__3271ca15373d4483($self, $other) + ret := v0 + leave +} +function $pow_checked__u256__3271ca15373d4483($base, $exp) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($exp) + let v1 := and(v0, 115792089237316195423570985008687907853269984665640564039457584007913129639935) + let v2 := 0 + if v2 { + let v3 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v1, 0), 0) + let v4 := v3 + if v4 { + revert(0, 0) + } + let v5 := 1 + let v6 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($base) + let v7 := v1 + for { } 1 { } { + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v7, 0) + if iszero(v8) { + break + } + let v9 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v7, 1), 0) + let v10 := v9 + if v10 { + let v11 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v5) + let v12 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v13 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v11, v12) + let v14 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v13) + v5 := v14 + } + v7 := shr(1, v7) + let v15 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v7, 0) + let v16 := v15 + if v16 { + let v17 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v18 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v6) + let v19 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v17, v18) + let v20 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v19) + v6 := v20 + } + if iszero(v16) { + } + } + let v21 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v5) + ret := v21 + leave + } + if iszero(v2) { + let v22 := 1 + let v23 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($base) + let v24 := v1 + for { } 1 { } { + let v25 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v24, 0) + if iszero(v25) { + break + } + let v26 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(and(v24, 1), 0) + let v27 := v26 + if v27 { + let v28 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v22) + let v29 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v30 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v28, v29) + let v31 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v30) + v22 := v31 + } + v24 := shr(1, v24) + let v32 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v24, 0) + let v33 := v32 + if v33 { + let v34 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v35 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v23) + let v36 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v34, v35) + let v37 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v36) + v23 := v37 + } + if iszero(v33) { + } + } + let v38 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v22) + ret := v38 + leave + } +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word($word) -> ret { + ret := $word + leave +} +function $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u256($self, $other) + ret := v0 + leave +} +function $checked_mul_u256($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } +} +function $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := div($self, $other) + ret := v2 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := mul($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/block_expr.snap b/crates/codegen/tests/fixtures/block_expr.snap index 83d8bc0cea..25fbbf83e0 100644 --- a/crates/codegen/tests/fixtures/block_expr.snap +++ b/crates/codegen/tests/fixtures/block_expr.snap @@ -4,6 +4,43 @@ expression: output input_file: tests/fixtures/block_expr.fe --- function $block_expr() -> ret { - ret := add(1, 2) + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(1, 2) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/borrow_storage_field_handle.snap b/crates/codegen/tests/fixtures/borrow_storage_field_handle.snap index 860cb21617..c3c72716ad 100644 --- a/crates/codegen/tests/fixtures/borrow_storage_field_handle.snap +++ b/crates/codegen/tests/fixtures/borrow_storage_field_handle.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/borrow_storage_field_handle.fe --- @@ -8,8 +7,45 @@ function $borrow_storage_field_handle__StorPtr_CoinStore___ba1c0d0726e89ba2($sto let v0 := $store let v1 := v0 let v2 := sload(v1) - sstore(v1, add(v2, 1)) - let v3 := sload($store) - ret := v3 + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 1) + sstore(v1, v3) + let v4 := sload($store) + ret := v4 + leave +} +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/by_ref_trait_provider_storage_bug.snap b/crates/codegen/tests/fixtures/by_ref_trait_provider_storage_bug.snap index b37ac280d5..5b53a7443e 100644 --- a/crates/codegen/tests/fixtures/by_ref_trait_provider_storage_bug.snap +++ b/crates/codegen/tests/fixtures/by_ref_trait_provider_storage_bug.snap @@ -129,15 +129,50 @@ object "ByRefTraitProviderStorageBug" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -182,7 +217,8 @@ object "ByRefTraitProviderStorageBug" { function $pair_h956dff41e88ee341_ctx_h4952b3c1f066f039_sum_stor_arg0_root_stor($self) -> ret { let v0 := sload($self) let v1 := sload(add($self, 1)) - ret := add(v0, v1) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0, v1) + ret := v2 leave } function $return_value__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f_u256__c4b26908c66ef75f($self, $value) { @@ -204,13 +240,14 @@ object "ByRefTraitProviderStorageBug" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -252,37 +289,41 @@ object "ByRefTraitProviderStorageBug" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -306,14 +347,54 @@ object "ByRefTraitProviderStorageBug" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383($self, $e) { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/cast_u8_usize_cmp.snap b/crates/codegen/tests/fixtures/cast_u8_usize_cmp.snap index 1c5f8ea88e..db7923d766 100644 --- a/crates/codegen/tests/fixtures/cast_u8_usize_cmp.snap +++ b/crates/codegen/tests/fixtures/cast_u8_usize_cmp.snap @@ -1,31 +1,50 @@ --- source: crates/codegen/tests/yul.rs +assertion_line: 33 expression: output input_file: tests/fixtures/cast_u8_usize_cmp.fe --- function $cast_u8_usize_cmp($indices, $i, $j) -> ret { let v0 := and(mload(add($indices, mul($i, 32))), 0xff) - let v1 := lt($j, v0) - if v1 { + let v1 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt($j, v0) + let v2 := v1 + if v2 { ret := 1 leave } - if iszero(v1) { - let v2 := eq($j, v0) - if v2 { + if iszero(v2) { + let v3 := $usize_ha12462c6d36e68b0_eq_he50383edd273619f_eq($j, v0) + let v4 := v3 + if v4 { ret := 2 leave } - if iszero(v2) { - let v3 := gt($j, v0) - if v3 { + if iszero(v4) { + let v5 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_gt($j, v0) + let v6 := v5 + if v6 { ret := 3 leave } - if iszero(v3) { + if iszero(v6) { ret := 0 leave } } } } +function $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} diff --git a/crates/codegen/tests/fixtures/code_region.snap b/crates/codegen/tests/fixtures/code_region.snap index 32ac758ca9..e1482b9c22 100644 --- a/crates/codegen/tests/fixtures/code_region.snap +++ b/crates/codegen/tests/fixtures/code_region.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/code_region.fe --- @@ -8,11 +7,30 @@ object "Foo" { code { function $allocate__Evm_hef0af3106e109414__3af54274b2985741($bytes, $mem) -> ret { let v0 := mload(64) - let v1 := eq(v0, 0) - if v1 { + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { v0 := 96 } - mstore(64, add(v0, $bytes)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $bytes) + mstore(64, v3) + ret := v0 + leave + } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } ret := v0 leave } @@ -36,6 +54,30 @@ object "Foo" { codecopy(v8, v6, v5) return(v8, v5) } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } $init__StorPtr_Evm___207f35a85ac4062e() } diff --git a/crates/codegen/tests/fixtures/comparison_ops.snap b/crates/codegen/tests/fixtures/comparison_ops.snap index fb270d32d1..b495425abc 100644 --- a/crates/codegen/tests/fixtures/comparison_ops.snap +++ b/crates/codegen/tests/fixtures/comparison_ops.snap @@ -8,17 +8,53 @@ function $comparison_ops() -> ret { let v0 := 1 let v1 := 2 let v2 := 3 - let v3 := mload(0x40) - if iszero(v3) { - v3 := 0x80 + let v3 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, v0) + let v4 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0, v1) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0, v1) + let v6 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_le(v1, v1) + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v2, v1) + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v2, v2) + let v9 := mload(0x40) + if iszero(v9) { + v9 := 0x80 } - mstore(0x40, add(v3, 192)) - mstore(v3, iszero(iszero(eq(v0, v0)))) - mstore(add(v3, 32), iszero(iszero(iszero(eq(v0, v1))))) - mstore(add(v3, 64), iszero(iszero(lt(v0, v1)))) - mstore(add(v3, 96), iszero(iszero(iszero(gt(v1, v1))))) - mstore(add(v3, 128), iszero(iszero(gt(v2, v1)))) - mstore(add(v3, 160), iszero(iszero(iszero(lt(v2, v2))))) - ret := v3 + mstore(0x40, add(v9, 192)) + mstore(v9, iszero(iszero(v3))) + mstore(add(v9, 32), iszero(iszero(v4))) + mstore(add(v9, 64), iszero(iszero(v5))) + mstore(add(v9, 96), iszero(iszero(v6))) + mstore(add(v9, 128), iszero(iszero(v7))) + mstore(add(v9, 160), iszero(iszero(v8))) + ret := v9 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_le($self, $other) -> ret { + let v0 := iszero(gt($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge($self, $other) -> ret { + let v0 := iszero(lt($self, $other)) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/const_array.snap b/crates/codegen/tests/fixtures/const_array.snap index be2aafbf1c..f956368715 100644 --- a/crates/codegen/tests/fixtures/const_array.snap +++ b/crates/codegen/tests/fixtures/const_array.snap @@ -12,27 +12,64 @@ object "main" { } mstore(0x40, add(v0, 96)) datacopy(v0, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) - let v1 := mload(add(v0, mul($i, 32))) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v1 := mload(0x40) + if iszero(v1) { + v1 := 0x80 } - mstore(0x40, add(v2, 96)) - datacopy(v2, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) - let v3 := mload(add(v2, mul($j, 32))) - let v4 := mload(0x40) - if iszero(v4) { - v4 := 0x80 - } - mstore(0x40, add(v4, 96)) - datacopy(v4, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) + mstore(0x40, add(v1, 96)) + datacopy(v1, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) + let v2 := mload(add(v0, mul($i, 32))) + let v3 := mload(add(v1, mul($j, 32))) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, v3) let v5 := mload(0x40) if iszero(v5) { v5 := 0x80 } mstore(0x40, add(v5, 96)) datacopy(v5, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) - ret := add(v1, v3) + let v6 := mload(0x40) + if iszero(v6) { + v6 := 0x80 + } + mstore(0x40, add(v6, 96)) + datacopy(v6, dataoffset("data_sum_two_0"), datasize("data_sum_two_0")) + ret := v4 + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } } diff --git a/crates/codegen/tests/fixtures/const_array_add.snap b/crates/codegen/tests/fixtures/const_array_add.snap index c540495ff6..8dbe32d117 100644 --- a/crates/codegen/tests/fixtures/const_array_add.snap +++ b/crates/codegen/tests/fixtures/const_array_add.snap @@ -13,7 +13,44 @@ object "main" { mstore(0x40, add(v0, 96)) datacopy(v0, dataoffset("data_get_sum_0"), datasize("data_get_sum_0")) let v1 := mload(v0) - ret := add(1, v1) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(1, v1) + ret := v2 + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } } diff --git a/crates/codegen/tests/fixtures/create_contract.snap b/crates/codegen/tests/fixtures/create_contract.snap index 386600841f..5800468f1e 100644 --- a/crates/codegen/tests/fixtures/create_contract.snap +++ b/crates/codegen/tests/fixtures/create_contract.snap @@ -91,87 +91,130 @@ object "Factory" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $create2_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d62e9c9ad3__8303e18f50f8d8ed($self, $value, $args, $salt) -> ret { let v0 := $__Child_init_code_len() let v1 := $__Child_init_code_offset() let v2 := 64 - let v3 := add(v0, v2) - let v4 := mload(64) - if iszero(v4) { - v4 := 0x80 - } - mstore(64, add(v4, v3)) - codecopy(v4, v1, v0) - let v5 := add(v4, v0) - let v6 := mload(0x40) - if iszero(v6) { - v6 := 0x80 - } - mstore(0x40, add(v6, 96)) - mstore(v6, v5) - mstore(add(v6, 32), v5) - mstore(add(v6, 64), add(v5, v2)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v2) + let v4 := v3 + let v5 := mload(64) + if iszero(v5) { + v5 := 0x80 + } + mstore(64, add(v5, v4)) + codecopy(v5, v1, v0) + let v6 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v5, v0) let v7 := v6 - $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v7) - let v8 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create2_raw_stor_arg0_root_stor($self, $value, v4, v3, $salt) - let v9 := eq(v8, 0) - if v9 { - let v10 := returndatasize() - let v11 := mload(64) - if iszero(v11) { - v11 := 0x80 + let v8 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v7, v2) + let v9 := mload(0x40) + if iszero(v9) { + v9 := 0x80 + } + mstore(0x40, add(v9, 96)) + mstore(v9, v7) + mstore(add(v9, 32), v7) + mstore(add(v9, 64), v8) + let v10 := v9 + $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v10) + let v11 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create2_raw_stor_arg0_root_stor($self, $value, v5, v4, $salt) + let v12 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v11, 0) + let v13 := v12 + if v13 { + let v14 := returndatasize() + let v15 := mload(64) + if iszero(v15) { + v15 := 0x80 } - mstore(64, add(v11, v10)) - returndatacopy(v11, 0, v10) - revert(v11, v10) + mstore(64, add(v15, v14)) + returndatacopy(v15, 0, v14) + revert(v15, v14) } - ret := v8 + ret := v11 leave } function $create_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d62e9c9ad3__8303e18f50f8d8ed($self, $value, $args) -> ret { let v0 := $__Child_init_code_len() let v1 := $__Child_init_code_offset() let v2 := 64 - let v3 := add(v0, v2) - let v4 := mload(64) - if iszero(v4) { - v4 := 0x80 - } - mstore(64, add(v4, v3)) - codecopy(v4, v1, v0) - let v5 := add(v4, v0) - let v6 := mload(0x40) - if iszero(v6) { - v6 := 0x80 - } - mstore(0x40, add(v6, 96)) - mstore(v6, v5) - mstore(add(v6, 32), v5) - mstore(add(v6, 64), add(v5, v2)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v2) + let v4 := v3 + let v5 := mload(64) + if iszero(v5) { + v5 := 0x80 + } + mstore(64, add(v5, v4)) + codecopy(v5, v1, v0) + let v6 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v5, v0) let v7 := v6 - $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v7) - let v8 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor($self, $value, v4, v3) - let v9 := eq(v8, 0) - if v9 { - let v10 := returndatasize() - let v11 := mload(64) - if iszero(v11) { - v11 := 0x80 + let v8 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v7, v2) + let v9 := mload(0x40) + if iszero(v9) { + v9 := 0x80 + } + mstore(0x40, add(v9, 96)) + mstore(v9, v7) + mstore(add(v9, 32), v7) + mstore(add(v9, 64), v8) + let v10 := v9 + $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v10) + let v11 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor($self, $value, v5, v4) + let v12 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v11, 0) + let v13 := v12 + if v13 { + let v14 := returndatasize() + let v15 := mload(64) + if iszero(v15) { + v15 := 0x80 } - mstore(64, add(v11, v10)) - returndatacopy(v11, 0, v10) - revert(v11, v10) + mstore(64, add(v15, v14)) + returndatacopy(v15, 0, v14) + revert(v15, v14) } - ret := v8 + ret := v11 leave } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { @@ -264,13 +307,14 @@ object "Factory" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -298,21 +342,24 @@ object "Factory" { let v0 := mload($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) let v2 := mload(add($self, 32)) - let v3 := add(v2, 32) - let v4 := mload(add($self, 32)) - let v5 := lt(v3, v4) - if v5 { + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 32) + let v4 := v3 + let v5 := mload(add($self, 32)) + let v6 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v4, v5) + let v7 := v6 + if v7 { revert(0, 0) } - let v6 := gt(v3, v1) - if v6 { + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v4, v1) + let v9 := v8 + if v9 { revert(0, 0) } - let v7 := mload($self) - let v8 := mload(add($self, 32)) - let v9 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v7, v8) - mstore(add($self, 32), v3) - ret := v9 + let v10 := mload($self) + let v11 := mload(add($self, 32)) + let v12 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v10, v11) + mstore(add($self, 32), v4) + ret := v12 leave } function $soldecoder_i__ha12a03fcb5ba844b_with_base__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($input, $base) -> ret { @@ -333,37 +380,41 @@ object "Factory" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 - } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) - } - let v3 := mload($self) - ret := v3 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 + } + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) + } + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -378,6 +429,11 @@ object "Factory" { ret := v0 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_CallData___fe17857f71623b98($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($d) ret := v0 @@ -387,10 +443,40 @@ object "Factory" { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave @@ -436,6 +522,23 @@ object "Factory" { sstore(add($state, 1), $y) leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } function $cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { let v0 := mload(0x40) if iszero(v0) { @@ -469,7 +572,7 @@ object "Factory" { } function $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { let v0 := mload($self) - let v1 := add(v0, $byte_offset) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $byte_offset) let v2 := mload(v1) ret := v2 leave @@ -482,20 +585,23 @@ object "Factory" { function $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($self) -> ret { let v0 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len($self) let v1 := mload(add($self, 64)) - let v2 := add(v1, 32) - let v3 := mload(add($self, 64)) - let v4 := lt(v2, v3) - if v4 { + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v3 := v2 + let v4 := mload(add($self, 64)) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v3, v4) + let v6 := v5 + if v6 { revert(0, 0) } - let v5 := gt(v2, v0) - if v5 { + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v3, v0) + let v8 := v7 + if v8 { revert(0, 0) } - let v6 := mload(add($self, 64)) - let v7 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v6) - mstore(add($self, 64), v2) - ret := v7 + let v9 := mload(add($self, 64)) + let v10 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v9) + mstore(add($self, 64), v3) + ret := v10 leave } function $soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -522,11 +628,35 @@ object "Factory" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_MemoryBytes___a53dbc6192a658d6($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($d) ret := v0 leave } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } $__Child_init() } @@ -543,15 +673,50 @@ object "Factory" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -596,13 +761,14 @@ object "Factory" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -645,10 +811,40 @@ object "Factory" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/effect_ptr_domains.snap b/crates/codegen/tests/fixtures/effect_ptr_domains.snap index 14cbba7ee0..61c756735b 100644 --- a/crates/codegen/tests/fixtures/effect_ptr_domains.snap +++ b/crates/codegen/tests/fixtures/effect_ptr_domains.snap @@ -1,14 +1,15 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/effect_ptr_domains.fe --- function $bump__StorPtr_Foo___3698cc3c4b2626e3($foo) { let v0 := sload($foo) - sstore($foo, add(v0, 1)) - let v1 := sload(add($foo, 1)) - sstore(add($foo, 1), add(v1, 2)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0, 1) + sstore($foo, v1) + let v2 := sload(add($foo, 1)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v2, 2) + sstore(add($foo, 1), v3) leave } function $test_effect_ptr_domains__Evm_hef0af3106e109414_Evm_hef0af3106e109414__7ab75559784fbc59($st, $mem) { @@ -30,6 +31,11 @@ function $test_effect_ptr_domains__Evm_hef0af3106e109414_Evm_hef0af3106e109414__ $bump__MemPtr_Foo___cdd30998d577b6ea(v5) leave } +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} function $mem_ptr_stor_arg0_root_stor__Evm_hef0af3106e109414_Foo_h6dbce71a6ea992b8__c09e6c6fc5a7b23d($self, $addr) -> ret { let v0 := $memptr_t__hf71ec14ffe47fb3f_effecthandle_hfc52f915596f993a_from_raw__Foo_h6dbce71a6ea992b8__21493237fe9c2c26($addr) ret := v0 @@ -37,9 +43,11 @@ function $mem_ptr_stor_arg0_root_stor__Evm_hef0af3106e109414_Foo_h6dbce71a6ea992 } function $bump__MemPtr_Foo___cdd30998d577b6ea($foo) { let v0 := mload($foo) - mstore($foo, add(v0, 1)) - let v1 := mload(add($foo, 32)) - mstore(add($foo, 32), add(v1, 2)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 1) + mstore($foo, v1) + let v2 := mload(add($foo, 32)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 2) + mstore(add($foo, 32), v3) leave } function $stor_ptr_stor_arg0_root_stor__Evm_hef0af3106e109414_Foo_h6dbce71a6ea992b8__c09e6c6fc5a7b23d($self, $slot) -> ret { @@ -51,7 +59,43 @@ function $memptr_t__hf71ec14ffe47fb3f_effecthandle_hfc52f915596f993a_from_raw__F ret := $raw leave } +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} function $storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__Foo_h6dbce71a6ea992b8__21493237fe9c2c26($raw) -> ret { ret := $raw leave } +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} diff --git a/crates/codegen/tests/fixtures/enum_variant_contract.snap b/crates/codegen/tests/fixtures/enum_variant_contract.snap index edad8d817d..4ff26b3655 100644 --- a/crates/codegen/tests/fixtures/enum_variant_contract.snap +++ b/crates/codegen/tests/fixtures/enum_variant_contract.snap @@ -25,88 +25,96 @@ object "EnumContract" { function $runtime__StorPtr_Evm___207f35a85ac4062e() { let v0 := calldataload(0) let v1 := shr(224, v0) - let v2 := eq(v1, 1817627404) - if v2 { - let v3 := calldataload(4) - let v4 := mload(0x40) - if iszero(v4) { - v4 := 0x80 + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v1, 1817627404) + let v3 := v2 + if v3 { + let v4 := calldataload(4) + let v5 := mload(0x40) + if iszero(v5) { + v5 := 0x80 } - mstore(0x40, add(v4, 64)) - mstore(v4, 1) - mstore(add(v4, 32), v3) - let v5 := 0 - let v6 := mload(v4) - switch v6 + mstore(0x40, add(v5, 64)) + mstore(v5, 1) + mstore(add(v5, 32), v4) + let v6 := 0 + let v7 := mload(v5) + switch v7 case 1 { - let v7 := mload(add(v4, 32)) - let v8 := v7 - v5 := v8 + let v8 := mload(add(v5, 32)) + let v9 := v8 + v6 := v9 } case 0 { - v5 := 0 + v6 := 0 } default { } - let v9 := v4 let v10 := v5 - $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v10, 0) + let v11 := v6 + $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v11, 0) } - if iszero(v2) { - let v11 := eq(v1, 1163776883) - if v11 { - let v12 := mload(0x40) - if iszero(v12) { - v12 := 0x80 + if iszero(v3) { + let v12 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v1, 1163776883) + let v13 := v12 + if v13 { + let v14 := mload(0x40) + if iszero(v14) { + v14 := 0x80 } - mstore(0x40, add(v12, 64)) - mstore(v12, 0) - let v13 := 0 - let v14 := mload(v12) - switch v14 + mstore(0x40, add(v14, 64)) + mstore(v14, 0) + let v15 := 0 + let v16 := mload(v14) + switch v16 case 1 { - let v15 := mload(add(v12, 32)) - let v16 := v15 - v13 := v16 + let v17 := mload(add(v14, 32)) + let v18 := v17 + v15 := v18 } case 0 { - v13 := 0 + v15 := 0 } default { } - let v17 := v12 - let v18 := v13 - $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v18, 0) + let v19 := v14 + let v20 := v15 + $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v20, 0) } - if iszero(v11) { - let v19 := eq(v1, 3572425762) - if iszero(v19) { + if iszero(v13) { + let v21 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v1, 3572425762) + let v22 := v21 + if iszero(v22) { return(0, 0) } - let v20 := calldataload(4) - let v21 := mload(0x40) - if iszero(v21) { - v21 := 0x80 + let v23 := calldataload(4) + let v24 := mload(0x40) + if iszero(v24) { + v24 := 0x80 } - mstore(0x40, add(v21, 64)) - mstore(v21, 1) - mstore(add(v21, 32), v20) - let v22 := 0 - let v23 := mload(v21) - switch v23 + mstore(0x40, add(v24, 64)) + mstore(v24, 1) + mstore(add(v24, 32), v23) + let v25 := 0 + let v26 := mload(v24) + switch v26 case 1 { - v22 := 1 + v25 := 1 } case 0 { - v22 := 0 + v25 := 0 } default { } - let v24 := v22 - $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v24, 0) + let v27 := v25 + $abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741(v27, 0) } } } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } $runtime__StorPtr_Evm___207f35a85ac4062e() return(0, 0) } diff --git a/crates/codegen/tests/fixtures/erc20.snap b/crates/codegen/tests/fixtures/erc20.snap index 6d12b14cdc..181958a491 100644 --- a/crates/codegen/tests/fixtures/erc20.snap +++ b/crates/codegen/tests/fixtures/erc20.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/erc20.fe --- @@ -41,8 +40,9 @@ object "CoolCoin" { function $__CoolCoin_init_contract($initial_supply, $owner, $store, $auth, $ctx, $log) { $accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__577ab43c73dd3cef($auth, 1, $owner) $accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__577ab43c73dd3cef($auth, 2, $owner) - let v0 := gt($initial_supply, 0) - if v0 { + let v0 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($initial_supply, 0) + let v1 := v0 + if v1 { $mint__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb($owner, $initial_supply, $store, $log) } leave @@ -50,9 +50,11 @@ object "CoolCoin" { function $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u256_Address_h257056268eac7027__802280feae02d9df($ptr, $self) -> ret { let v0 := mload($self) let v1 := $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, v0) - let v2 := mload(add($self, 32)) - let v3 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(add($ptr, v1), v2) - ret := add(v1, v3) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($ptr, v1) + let v3 := mload(add($self, 32)) + let v4 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v2, v3) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, v4) + ret := v5 leave } function $accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__577ab43c73dd3cef($self, $role, $to) { @@ -72,7 +74,8 @@ object "CoolCoin" { leave } function $address_h257056268eac7027_eq_h14b330e44530c410_eq($self, $other) -> ret { - ret := eq($self, $other) + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) + ret := v0 leave } function $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { @@ -107,6 +110,40 @@ object "CoolCoin" { ret := v0 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { let v0 := mload(0x40) if iszero(v0) { @@ -158,7 +195,7 @@ object "CoolCoin" { } function $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { let v0 := mload($self) - let v1 := add(v0, $byte_offset) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $byte_offset) let v2 := mload(v1) ret := v2 leave @@ -168,21 +205,23 @@ object "CoolCoin" { let v1 := $ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2($to, v0) $assert(v1) let v2 := sload($store) - sstore($store, add(v2, $amount)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, $amount) + sstore($store, v3) pop($store) pop($store) - let v3 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, add(v3, $amount)) - let v4 := $address_h257056268eac7027_zero() - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 - } - mstore(0x40, add(v5, 96)) - mstore(v5, v4) - mstore(add(v5, 32), $to) - mstore(add(v5, 64), $amount) - $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v5) + let v4 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v4, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, v5) + let v6 := $address_h257056268eac7027_zero() + let v7 := mload(0x40) + if iszero(v7) { + v7 := 0x80 + } + mstore(0x40, add(v7, 96)) + mstore(v7, v6) + mstore(add(v7, 32), $to) + mstore(add(v7, 64), $amount) + $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v7) leave } function $ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2($self, $other) -> ret { @@ -198,20 +237,23 @@ object "CoolCoin" { function $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($self) -> ret { let v0 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len($self) let v1 := mload(add($self, 64)) - let v2 := add(v1, 32) - let v3 := mload(add($self, 64)) - let v4 := lt(v2, v3) - if v4 { + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v3 := v2 + let v4 := mload(add($self, 64)) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v3, v4) + let v6 := v5 + if v6 { revert(0, 0) } - let v5 := gt(v2, v0) - if v5 { + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v3, v0) + let v8 := v7 + if v8 { revert(0, 0) } - let v6 := mload(add($self, 64)) - let v7 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v6) - mstore(add($self, 64), v2) - ret := v7 + let v9 := mload(add($self, 64)) + let v10 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v9) + mstore(add($self, 64), v3) + ret := v10 leave } function $soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -232,37 +274,41 @@ object "CoolCoin" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 - } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 + } + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -326,10 +372,11 @@ object "CoolCoin" { } mstore(64, add(v0, 0)) let v1 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storagemap_storage_slot_with_salt___u256__Address___c7c570db20cdd393($key, $salt) -> ret { @@ -339,10 +386,11 @@ object "CoolCoin" { } mstore(64, add(v0, 0)) let v1 := $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u256_Address_h257056268eac7027__802280feae02d9df(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__TokenStore_0__1___175215aa56127bde($raw) -> ret { @@ -368,6 +416,11 @@ object "CoolCoin" { $evm_hef0af3106e109414_log_h22d1a10952034bae_log3_arg0_root_stor($log, v6, v8, 106268374300910980166318620624040158066582587003704178075307865084173350203760, v10, v12) leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_MemoryBytes___a53dbc6192a658d6($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($d) ret := v0 @@ -377,11 +430,35 @@ object "CoolCoin" { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { mstore($ptr, $self) ret := 32 leave } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_from_word($word) -> ret { ret := $word leave @@ -390,6 +467,16 @@ object "CoolCoin" { ret := $self leave } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } $__CoolCoin_init() } @@ -512,7 +599,8 @@ object "CoolCoin" { mstore(v5, v4) mstore(add(v5, 32), v1) let v6 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v5) - $approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb(v4, v1, add(v6, v3), $store, $log) + let v7 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v6, v3) + $approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb(v4, v1, v7, $store, $log) ret := 1 leave } @@ -531,8 +619,10 @@ object "CoolCoin" { mstore(v5, v4) mstore(add(v5, 32), v1) let v6 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v5) - $assert(iszero(lt(v6, v3))) - $approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb(v4, v1, sub(v6, v3), $store, $log) + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v6, v3) + $assert(v7) + let v8 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v6, v3) + $approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb(v4, v1, v8, $store, $log) ret := 1 leave } @@ -619,17 +709,21 @@ object "CoolCoin" { function $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2($ptr, $self) -> ret { let v0 := mload($self) let v1 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key($ptr, v0) - let v2 := mload(add($self, 32)) - let v3 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(add($ptr, v1), v2) - ret := add(v1, v3) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($ptr, v1) + let v3 := mload(add($self, 32)) + let v4 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v2, v3) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, v4) + ret := v5 leave } function $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u256_Address_h257056268eac7027__802280feae02d9df($ptr, $self) -> ret { let v0 := mload($self) let v1 := $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, v0) - let v2 := mload(add($self, 32)) - let v3 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(add($ptr, v1), v2) - ret := add(v1, v3) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($ptr, v1) + let v3 := mload(add($self, 32)) + let v4 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v2, v3) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, v4) + ret := v5 leave } function $accesscontrol____h4c85da5bbb505ade_require_stor_arg0_root_stor__3_Evm_hef0af3106e109414__5baaa260f0d18873($self, $role, $ctx) { @@ -642,7 +736,8 @@ object "CoolCoin" { mstore(v1, $role) mstore(add(v1, 32), v0) let v2 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___u256__Address__bool_3__5e1c6d4e3f4fb7e8(0, v1) - $assert(eq(v2, 1)) + let v3 := $bool_h947c0c03c59c6f07_eq_he50383edd273619f_eq(v2, 1) + $assert(v3) leave } function $address_h257056268eac7027_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_CallData___fe17857f71623b98($d) -> ret { @@ -651,7 +746,8 @@ object "CoolCoin" { leave } function $address_h257056268eac7027_eq_h14b330e44530c410_eq($self, $other) -> ret { - ret := eq($self, $other) + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) + ret := v0 leave } function $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { @@ -761,8 +857,14 @@ object "CoolCoin" { } leave } + function $bool_h947c0c03c59c6f07_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(iszero(iszero($self)), iszero(iszero($other))) + ret := v0 + leave + } function $bool_h947c0c03c59c6f07_wordrepr_h7483d41ac8178d88_from_word($word) -> ret { - ret := iszero(eq($word, 0)) + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($word, 0) + ret := v0 leave } function $burn__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb($from, $amount, $store, $log) { @@ -771,21 +873,24 @@ object "CoolCoin" { $assert(v1) pop($store) let v2 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from) - $assert(iszero(lt(v2, $amount))) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v2, $amount) + $assert(v3) pop($store) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, sub(v2, $amount)) - let v3 := sload($store) - sstore($store, sub(v3, $amount)) - let v4 := $address_h257056268eac7027_zero() - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 + let v4 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v2, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, v4) + let v5 := sload($store) + let v6 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v5, $amount) + sstore($store, v6) + let v7 := $address_h257056268eac7027_zero() + let v8 := mload(0x40) + if iszero(v8) { + v8 := 0x80 } - mstore(0x40, add(v5, 96)) - mstore(v5, $from) - mstore(add(v5, 32), v4) - mstore(add(v5, 64), $amount) - $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v5) + mstore(0x40, add(v8, 96)) + mstore(v8, $from) + mstore(add(v8, 32), v7) + mstore(add(v8, 64), $amount) + $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v8) leave } function $burn_h25a61f4466d20eed_decode_h624c3cd8c996d995_decode__SolDecoder_CallData___c1e4510fd444b966($d) -> ret { @@ -808,15 +913,50 @@ object "CoolCoin" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -906,21 +1046,23 @@ object "CoolCoin" { let v1 := $ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2($to, v0) $assert(v1) let v2 := sload($store) - sstore($store, add(v2, $amount)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, $amount) + sstore($store, v3) pop($store) pop($store) - let v3 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, add(v3, $amount)) - let v4 := $address_h257056268eac7027_zero() - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 + let v4 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v4, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, v5) + let v6 := $address_h257056268eac7027_zero() + let v7 := mload(0x40) + if iszero(v7) { + v7 := 0x80 } - mstore(0x40, add(v5, 96)) - mstore(v5, v4) - mstore(add(v5, 32), $to) - mstore(add(v5, 64), $amount) - $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v5) + mstore(0x40, add(v7, 96)) + mstore(v7, v6) + mstore(add(v7, 32), $to) + mstore(add(v7, 64), $amount) + $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v7) leave } function $mint_ha2f94817be433a2e_decode_h624c3cd8c996d995_decode__SolDecoder_CallData___c1e4510fd444b966($d) -> ret { @@ -1003,13 +1145,14 @@ object "CoolCoin" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -1037,21 +1180,24 @@ object "CoolCoin" { let v0 := mload($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) let v2 := mload(add($self, 32)) - let v3 := add(v2, 32) - let v4 := mload(add($self, 32)) - let v5 := lt(v3, v4) - if v5 { + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 32) + let v4 := v3 + let v5 := mload(add($self, 32)) + let v6 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v4, v5) + let v7 := v6 + if v7 { revert(0, 0) } - let v6 := gt(v3, v1) - if v6 { + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v4, v1) + let v9 := v8 + if v9 { revert(0, 0) } - let v7 := mload($self) - let v8 := mload(add($self, 32)) - let v9 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v7, v8) - mstore(add($self, 32), v3) - ret := v9 + let v10 := mload($self) + let v11 := mload(add($self, 32)) + let v12 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v10, v11) + mstore(add($self, 32), v4) + ret := v12 leave } function $soldecoder_i__ha12a03fcb5ba844b_with_base__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($input, $base) -> ret { @@ -1072,37 +1218,41 @@ object "CoolCoin" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -1127,16 +1277,18 @@ object "CoolCoin" { mstore(v0, $owner) mstore(add(v0, 32), $spender) let v1 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v0) - $assert(iszero(lt(v1, $amount))) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v1, $amount) + $assert(v2) pop($store) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, $owner) - mstore(add(v2, 32), $spender) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v2, sub(v1, $amount)) + mstore(0x40, add(v3, 64)) + mstore(v3, $owner) + mstore(add(v3, 32), $spender) + let v4 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v3, v4) leave } function $stor_ptr__Evm_hef0af3106e109414_AccessControl_3___1911f7c438797961($self, $slot) -> ret { @@ -1212,10 +1364,11 @@ object "CoolCoin" { } mstore(64, add(v0, 0)) let v1 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storagemap_storage_slot_with_salt___Address__Address___c32d499da259c78e($key, $salt) -> ret { @@ -1225,10 +1378,11 @@ object "CoolCoin" { } mstore(64, add(v0, 0)) let v1 := $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storagemap_storage_slot_with_salt___u256__Address___c7c570db20cdd393($key, $salt) -> ret { @@ -1238,10 +1392,11 @@ object "CoolCoin" { } mstore(64, add(v0, 0)) let v1 := $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u256_Address_h257056268eac7027__802280feae02d9df(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__TokenStore_0__1___175215aa56127bde($raw) -> ret { @@ -1268,22 +1423,25 @@ object "CoolCoin" { $assert(v3) pop($store) let v4 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from) - $assert(iszero(lt(v4, $amount))) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v4, $amount) + $assert(v5) pop($store) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, sub(v4, $amount)) + let v6 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v4, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, v6) pop($store) pop($store) - let v5 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, add(v5, $amount)) - let v6 := mload(0x40) - if iszero(v6) { - v6 := 0x80 + let v7 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to) + let v8 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v7, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, v8) + let v9 := mload(0x40) + if iszero(v9) { + v9 := 0x80 } - mstore(0x40, add(v6, 96)) - mstore(v6, $from) - mstore(add(v6, 32), $to) - mstore(add(v6, 64), $amount) - $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v6) + mstore(0x40, add(v9, 96)) + mstore(v9, $from) + mstore(add(v9, 32), $to) + mstore(add(v9, 64), $amount) + $emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63($log, v9) leave } function $transfer_h13f5ec5985ebba60_decode_h624c3cd8c996d995_decode__SolDecoder_CallData___c1e4510fd444b966($d) -> ret { @@ -1333,6 +1491,11 @@ object "CoolCoin" { ret := v3 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_CallData___fe17857f71623b98($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($d) ret := v0 @@ -1342,15 +1505,45 @@ object "CoolCoin" { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge($self, $other) -> ret { + let v0 := iszero(lt($self, $other)) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { mstore($ptr, $self) ret := 32 leave } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_from_word($word) -> ret { ret := $word leave @@ -1359,6 +1552,16 @@ object "CoolCoin" { ret := $self leave } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/erc20_low_level.snap b/crates/codegen/tests/fixtures/erc20_low_level.snap index 90e9dc4fee..9fcfdc0ebe 100644 --- a/crates/codegen/tests/fixtures/erc20_low_level.snap +++ b/crates/codegen/tests/fixtures/erc20_low_level.snap @@ -6,7 +6,8 @@ input_file: tests/fixtures/erc20_low_level.fe object "Erc20Contract" { code { function $address_h257056268eac7027_eq_h14b330e44530c410_eq_stor_arg0_root_stor($self, $other) -> ret { - ret := eq($self, $other) + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq_stor_arg0_root_stor($self, $other) + ret := v0 leave } function $address_h257056268eac7027_zero() -> ret { @@ -52,6 +53,11 @@ object "Erc20Contract" { ret := $raw leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq_stor_arg0_root_stor($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } $init__StorPtr_Evm___207f35a85ac4062e() } @@ -60,9 +66,11 @@ object "Erc20Contract" { function $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2($ptr, $self) -> ret { let v0 := mload($self) let v1 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key($ptr, v0) - let v2 := mload(add($self, 32)) - let v3 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(add($ptr, v1), v2) - ret := add(v1, v3) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($ptr, v1) + let v3 := mload(add($self, 32)) + let v4 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v2, v3) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, v4) + ret := v5 leave } function $abi_encode_string__Evm_hef0af3106e109414__3af54274b2985741($word, $len, $ops) { @@ -76,7 +84,8 @@ object "Erc20Contract" { return(0, 32) } function $address_h257056268eac7027_eq_h14b330e44530c410_eq_arg1_root_stor($self, $other) -> ret { - ret := eq($self, $other) + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq_arg1_root_stor($self, $other) + ret := v0 leave } function $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { @@ -109,6 +118,40 @@ object "Erc20Contract" { ret := v0 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $erc20_______h94f6fe6e679122ca_allowance_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $owner, $spender) -> ret { pop($self) let v0 := mload(0x40) @@ -150,41 +193,48 @@ object "Erc20Contract" { } let v4 := $erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $to) pop($self) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, add(v4, $amount)) - let v5 := sload($self) - sstore($self, add(v5, $amount)) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v4, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, v5) + let v6 := sload($self) + let v7 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v6, $amount) + sstore($self, v7) leave } function $erc20_______h94f6fe6e679122ca_transfer_from_stor_arg0_root_stor__0_1_Evm_hef0af3106e109414_Evm_hef0af3106e109414__ca7def21e0c734ee($self, $owner, $to, $amount, $ctx, $ops) { let v0 := caller() let v1 := $erc20_______h94f6fe6e679122ca_allowance_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $owner, v0) - let v2 := lt(v1, $amount) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, $amount) + let v3 := v2 + if v3 { revert(0, 0) } $erc20_______h94f6fe6e679122ca_transfer_stor_arg0_root_stor__0_1_Evm_hef0af3106e109414__2bfe0780cafbc4d2($self, $owner, $to, $amount, $ops) pop($self) - let v3 := mload(0x40) - if iszero(v3) { - v3 := 0x80 + let v4 := mload(0x40) + if iszero(v4) { + v4 := 0x80 } - mstore(0x40, add(v3, 64)) - mstore(v3, $owner) - mstore(add(v3, 32), v0) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v3, sub(v1, $amount)) + mstore(0x40, add(v4, 64)) + mstore(v4, $owner) + mstore(add(v4, 32), v0) + let v5 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(0, v4, v5) leave } function $erc20_______h94f6fe6e679122ca_transfer_stor_arg0_root_stor__0_1_Evm_hef0af3106e109414__2bfe0780cafbc4d2($self, $from, $to, $amount, $ops) { let v0 := $erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $from) - let v1 := lt(v0, $amount) - if v1 { + let v1 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0, $amount) + let v2 := v1 + if v2 { revert(0, 0) } - let v2 := $erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $to) + let v3 := $erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2($self, $to) pop($self) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, sub(v0, $amount)) + let v4 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $from, v4) pop($self) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, add(v2, $amount)) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(0, $to, v5) leave } function $mint__0_1_StorPtr_Erc20_0__1___Evm_hef0af3106e109414_Evm_hef0af3106e109414__d36080519ce8fddb($to, $amount, $erc20, $ctx, $ops) -> ret { @@ -316,10 +366,11 @@ object "Erc20Contract" { } mstore(64, add(v0, 0)) let v1 := $address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storagemap_storage_slot_with_salt___Address__Address___c32d499da259c78e($key, $salt) -> ret { @@ -329,10 +380,11 @@ object "Erc20Contract" { } mstore(64, add(v0, 0)) let v1 := $_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__Erc20_0__1___b48e7ab92637d703($raw) -> ret { @@ -350,11 +402,45 @@ object "Erc20Contract" { ret := 1 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq_arg1_root_stor($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { mstore($ptr, $self) ret := 32 leave } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_from_word($word) -> ret { ret := $word leave @@ -363,6 +449,16 @@ object "Erc20Contract" { ret := $self leave } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } $runtime__StorPtr_Evm___207f35a85ac4062e() return(0, 0) } diff --git a/crates/codegen/tests/fixtures/event_logging.snap b/crates/codegen/tests/fixtures/event_logging.snap index f948a3bc62..b5022e869a 100644 --- a/crates/codegen/tests/fixtures/event_logging.snap +++ b/crates/codegen/tests/fixtures/event_logging.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/event_logging.fe --- @@ -50,19 +49,21 @@ function $solencoder_h1b9228b90dad6928_new() -> ret { } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383($self, $e) { @@ -72,14 +73,15 @@ function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb80 function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $address_h257056268eac7027_topicvalue_hc8981c1d4c24e77d_as_topic($self) -> ret { @@ -90,9 +92,83 @@ function $evm_hef0af3106e109414_log_h22d1a10952034bae_log3($self, $offset, $len, log3($offset, $len, $topic0, $topic1, $topic2) leave } +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) + leave +} +function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/event_logging_via_log.snap b/crates/codegen/tests/fixtures/event_logging_via_log.snap index ad475867a7..25015cae20 100644 --- a/crates/codegen/tests/fixtures/event_logging_via_log.snap +++ b/crates/codegen/tests/fixtures/event_logging_via_log.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/event_logging_via_log.fe --- @@ -53,19 +52,21 @@ function $solencoder_h1b9228b90dad6928_new() -> ret { } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383($self, $e) { @@ -75,14 +76,15 @@ function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb80 function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $address_h257056268eac7027_topicvalue_hc8981c1d4c24e77d_as_topic($self) -> ret { @@ -93,9 +95,83 @@ function $evm_hef0af3106e109414_log_h22d1a10952034bae_log3($self, $offset, $len, log3($offset, $len, $topic0, $topic1, $topic2) leave } +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) + leave +} +function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/for_array.snap b/crates/codegen/tests/fixtures/for_array.snap index 214715c9b3..148b9f16b9 100644 --- a/crates/codegen/tests/fixtures/for_array.snap +++ b/crates/codegen/tests/fixtures/for_array.snap @@ -19,7 +19,8 @@ object "main" { for { } lt(v3, v4) { v3 := add(v3, 1) } { let v5 := $_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u64_25__540b817a073b29f5(v1, v3) let v6 := v5 - v2 := add(v2, v6) + let v7 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v2, v6) + v2 := v7 } ret := v2 leave @@ -33,6 +34,42 @@ object "main" { ret := v0 leave } + function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave + } + function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave + } + function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } } data "data_for_array_sum_0" hex"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000013000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000019" } diff --git a/crates/codegen/tests/fixtures/for_array_large.snap b/crates/codegen/tests/fixtures/for_array_large.snap index 44f159165d..a6a6c6453b 100644 --- a/crates/codegen/tests/fixtures/for_array_large.snap +++ b/crates/codegen/tests/fixtures/for_array_large.snap @@ -19,7 +19,8 @@ object "main" { for { } lt(v3, v4) { v3 := add(v3, 1) } { let v5 := $_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u64_10__2b47acd750beacf4(v1, v3) let v6 := v5 - v2 := add(v2, v6) + let v7 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v2, v6) + v2 := v7 } ret := v2 leave @@ -33,6 +34,42 @@ object "main" { ret := v0 leave } + function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave + } + function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave + } + function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } } data "data_for_array_large_sum_0" hex"000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000a" } diff --git a/crates/codegen/tests/fixtures/for_range.snap b/crates/codegen/tests/fixtures/for_range.snap index 3d051357c9..86ce55e5db 100644 --- a/crates/codegen/tests/fixtures/for_range.snap +++ b/crates/codegen/tests/fixtures/for_range.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/for_range.fe --- @@ -20,7 +19,8 @@ function $for_range_sum() -> ret { for { } lt(v4, v5) { v4 := add(v4, 1) } { let v6 := $range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_get(v3, v4) let v7 := v6 - v0 := add(v0, v7) + let v8 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, v7) + v0 := v8 } ret := v0 leave @@ -29,20 +29,96 @@ function $range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_len($s let v0 := 0 let v1 := mload(add($self, 32)) let v2 := mload($self) - let v3 := lt(v1, v2) - if v3 { + let v3 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { v0 := 0 } - if iszero(v3) { - let v4 := mload(add($self, 32)) - let v5 := mload($self) - v0 := sub(v4, v5) + if iszero(v4) { + let v5 := mload(add($self, 32)) + let v6 := mload($self) + let v7 := $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(v5, v6) + v0 := v7 } ret := v0 leave } function $range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_get($self, $i) -> ret { let v0 := mload($self) - ret := add(v0, $i) + let v1 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, $i) + ret := v1 + leave +} +function $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_usize($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_usize($self, $other) + ret := v0 + leave +} +function $checked_add_unsigned_impl__usize__a12462c6d36e68b0($a, $b) -> ret { + let v0 := $usize_ha12462c6d36e68b0_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_add_usize($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__usize__a12462c6d36e68b0($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__usize__a12462c6d36e68b0($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $usize_ha12462c6d36e68b0_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $checked_sub_usize($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__usize__a12462c6d36e68b0($a, $b) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $usize_ha12462c6d36e68b0_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/full_contract.snap b/crates/codegen/tests/fixtures/full_contract.snap index decbda7fa7..4919432a37 100644 --- a/crates/codegen/tests/fixtures/full_contract.snap +++ b/crates/codegen/tests/fixtures/full_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/full_contract.fe --- @@ -22,47 +21,147 @@ object "ShapeDispatcher" { mstore(v0, $value) return(v0, 32) } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_mul_u256($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_mul_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } + } function $dispatch__StorPtr_Evm___207f35a85ac4062e() { let v0 := calldataload(0) let v1 := shr(224, v0) - let v2 := eq(v1, 151146943) - if v2 { - let v3 := calldataload(4) - let v4 := calldataload(36) - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v1, 151146943) + let v3 := v2 + if v3 { + let v4 := calldataload(4) + let v5 := calldataload(36) + let v6 := mload(0x40) + if iszero(v6) { + v6 := 0x80 } - mstore(0x40, add(v5, 64)) - mstore(v5, v3) - mstore(add(v5, 32), v4) - let v6 := v5 - let v7 := mload(v6) - mstore(v6, add(v7, 1)) - let v8 := mload(add(v6, 32)) - mstore(add(v6, 32), add(v8, 2)) - let v9 := $point_hac92469562809d28_area(v6) - $abi_encode__Evm_hef0af3106e109414__3af54274b2985741(v9, 0) + mstore(0x40, add(v6, 64)) + mstore(v6, v4) + mstore(add(v6, 32), v5) + let v7 := v6 + let v8 := mload(v7) + let v9 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v8, 1) + mstore(v7, v9) + let v10 := mload(add(v7, 32)) + let v11 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v10, 2) + mstore(add(v7, 32), v11) + let v12 := $point_hac92469562809d28_area(v7) + $abi_encode__Evm_hef0af3106e109414__3af54274b2985741(v12, 0) } - let v10 := eq(v1, 2066295049) - if v10 { - let v11 := calldataload(4) - let v12 := v11 - v12 := add(v12, 3) - let v13 := $square_h97afaa872b6ea17e_area(v12) - $abi_encode__Evm_hef0af3106e109414__3af54274b2985741(v13, 0) + let v13 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v1, 2066295049) + let v14 := v13 + if v14 { + let v15 := calldataload(4) + let v16 := v15 + let v17 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v16, 3) + v16 := v17 + let v18 := $square_h97afaa872b6ea17e_area(v16) + $abi_encode__Evm_hef0af3106e109414__3af54274b2985741(v18, 0) } return(0, 0) } function $point_hac92469562809d28_area($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 32)) - ret := mul(v0, v1) + let v2 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v0, v1) + ret := v2 leave } function $square_h97afaa872b6ea17e_area($self) -> ret { let v0 := $self - ret := mul(v0, v0) + let v1 := $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v0, v0) + ret := v1 + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := div($self, $other) + ret := v2 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := mul($self, $other) + ret := v0 leave } $dispatch__StorPtr_Evm___207f35a85ac4062e() diff --git a/crates/codegen/tests/fixtures/function_call.snap b/crates/codegen/tests/fixtures/function_call.snap index 0ceb3f4f3d..45c7ca1d69 100644 --- a/crates/codegen/tests/fixtures/function_call.snap +++ b/crates/codegen/tests/fixtures/function_call.snap @@ -1,11 +1,11 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/function_call.fe --- function $add_one($x) -> ret { - ret := add($x, 1) + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($x, 1) + ret := v0 leave } function $call_add_one() -> ret { @@ -13,3 +13,39 @@ function $call_add_one() -> ret { ret := v0 leave } +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/high_level_contract.snap b/crates/codegen/tests/fixtures/high_level_contract.snap index 0a14758bcd..4d77dd0bf0 100644 --- a/crates/codegen/tests/fixtures/high_level_contract.snap +++ b/crates/codegen/tests/fixtures/high_level_contract.snap @@ -41,6 +41,23 @@ object "EchoContract" { sstore(add($state, 1), $y) leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } function $cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { let v0 := mload(0x40) if iszero(v0) { @@ -74,7 +91,7 @@ object "EchoContract" { } function $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { let v0 := mload($self) - let v1 := add(v0, $byte_offset) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $byte_offset) let v2 := mload(v1) ret := v2 leave @@ -87,20 +104,23 @@ object "EchoContract" { function $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($self) -> ret { let v0 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len($self) let v1 := mload(add($self, 64)) - let v2 := add(v1, 32) - let v3 := mload(add($self, 64)) - let v4 := lt(v2, v3) - if v4 { + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v3 := v2 + let v4 := mload(add($self, 64)) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v3, v4) + let v6 := v5 + if v6 { revert(0, 0) } - let v5 := gt(v2, v0) - if v5 { + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v3, v0) + let v8 := v7 + if v8 { revert(0, 0) } - let v6 := mload(add($self, 64)) - let v7 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v6) - mstore(add($self, 64), v2) - ret := v7 + let v9 := mload(add($self, 64)) + let v10 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v9) + mstore(add($self, 64), v3) + ret := v10 leave } function $soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -127,11 +147,35 @@ object "EchoContract" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_MemoryBytes___a53dbc6192a658d6($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($d) ret := v0 leave } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } $__EchoContract_init() } @@ -180,15 +224,50 @@ object "EchoContract" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -254,13 +333,14 @@ object "EchoContract" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -288,21 +368,24 @@ object "EchoContract" { let v0 := mload($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) let v2 := mload(add($self, 32)) - let v3 := add(v2, 32) - let v4 := mload(add($self, 32)) - let v5 := lt(v3, v4) - if v5 { + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 32) + let v4 := v3 + let v5 := mload(add($self, 32)) + let v6 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v4, v5) + let v7 := v6 + if v7 { revert(0, 0) } - let v6 := gt(v3, v1) - if v6 { + let v8 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v4, v1) + let v9 := v8 + if v9 { revert(0, 0) } - let v7 := mload($self) - let v8 := mload(add($self, 32)) - let v9 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v7, v8) - mstore(add($self, 32), v3) - ret := v9 + let v10 := mload($self) + let v11 := mload(add($self, 32)) + let v12 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v10, v11) + mstore(add($self, 32), v4) + ret := v12 leave } function $soldecoder_i__ha12a03fcb5ba844b_with_base__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($input, $base) -> ret { @@ -323,37 +406,41 @@ object "EchoContract" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -377,6 +464,11 @@ object "EchoContract" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_CallData___fe17857f71623b98($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($d) ret := v0 @@ -386,10 +478,40 @@ object "EchoContract" { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/if_else.snap b/crates/codegen/tests/fixtures/if_else.snap index 0d5525e4cc..e1cd5fedb7 100644 --- a/crates/codegen/tests/fixtures/if_else.snap +++ b/crates/codegen/tests/fixtures/if_else.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/if_else.fe --- @@ -19,6 +18,43 @@ function $if_else($cond) -> ret { leave } function $helper($x) -> ret { - ret := add($x, 1) + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($x, 1) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/init_args_with_child_dep.snap b/crates/codegen/tests/fixtures/init_args_with_child_dep.snap index 5941175cfb..6993bb009d 100644 --- a/crates/codegen/tests/fixtures/init_args_with_child_dep.snap +++ b/crates/codegen/tests/fixtures/init_args_with_child_dep.snap @@ -62,41 +62,62 @@ object "Parent" { $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v1, $e) leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } function $create_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d62e9c9ad3__8303e18f50f8d8ed($self, $value, $args) -> ret { let v0 := $__Child_init_code_len() let v1 := $__Child_init_code_offset() let v2 := 64 - let v3 := add(v0, v2) - let v4 := mload(64) - if iszero(v4) { - v4 := 0x80 - } - mstore(64, add(v4, v3)) - codecopy(v4, v1, v0) - let v5 := add(v4, v0) - let v6 := mload(0x40) - if iszero(v6) { - v6 := 0x80 - } - mstore(0x40, add(v6, 96)) - mstore(v6, v5) - mstore(add(v6, 32), v5) - mstore(add(v6, 64), add(v5, v2)) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v2) + let v4 := v3 + let v5 := mload(64) + if iszero(v5) { + v5 := 0x80 + } + mstore(64, add(v5, v4)) + codecopy(v5, v1, v0) + let v6 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v5, v0) let v7 := v6 - $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v7) - let v8 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor($self, $value, v4, v3) - let v9 := eq(v8, 0) - if v9 { - let v10 := returndatasize() - let v11 := mload(64) - if iszero(v11) { - v11 := 0x80 - } - mstore(64, add(v11, v10)) - returndatacopy(v11, 0, v10) - revert(v11, v10) - } - ret := v8 + let v8 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v7, v2) + let v9 := mload(0x40) + if iszero(v9) { + v9 := 0x80 + } + mstore(0x40, add(v9, 96)) + mstore(v9, v7) + mstore(add(v9, 32), v7) + mstore(add(v9, 64), v8) + let v10 := v9 + $_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64($args, v10) + let v11 := $evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor($self, $value, v5, v4) + let v12 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v11, 0) + let v13 := v12 + if v13 { + let v14 := returndatasize() + let v15 := mload(64) + if iszero(v15) { + v15 := 0x80 + } + mstore(64, add(v15, v14)) + returndatacopy(v15, 0, v14) + revert(v15, v14) + } + ret := v11 leave } function $cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -127,7 +148,7 @@ object "Parent" { } function $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { let v0 := mload($self) - let v1 := add(v0, $byte_offset) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $byte_offset) let v2 := mload(v1) ret := v2 leave @@ -140,20 +161,23 @@ object "Parent" { function $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($self) -> ret { let v0 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len($self) let v1 := mload(add($self, 64)) - let v2 := add(v1, 32) - let v3 := mload(add($self, 64)) - let v4 := lt(v2, v3) - if v4 { + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v3 := v2 + let v4 := mload(add($self, 64)) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v3, v4) + let v6 := v5 + if v6 { revert(0, 0) } - let v5 := gt(v2, v0) - if v5 { + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v3, v0) + let v8 := v7 + if v8 { revert(0, 0) } - let v6 := mload(add($self, 64)) - let v7 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v6) - mstore(add($self, 64), v2) - ret := v7 + let v9 := mload(add($self, 64)) + let v10 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v9) + mstore(add($self, 64), v3) + ret := v10 leave } function $soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -174,7 +198,13 @@ object "Parent" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 leave } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_MemoryBytes___a53dbc6192a658d6($d) -> ret { @@ -186,6 +216,30 @@ object "Parent" { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } $__Parent_init() } @@ -201,15 +255,50 @@ object "Parent" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -249,13 +338,14 @@ object "Parent" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -289,10 +379,40 @@ object "Parent" { ret := v2 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave @@ -336,6 +456,23 @@ object "Parent" { function $__Child_init_contract($x, $y) { leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } function $cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { let v0 := mload(0x40) if iszero(v0) { @@ -359,7 +496,7 @@ object "Parent" { } function $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { let v0 := mload($self) - let v1 := add(v0, $byte_offset) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, $byte_offset) let v2 := mload(v1) ret := v2 leave @@ -372,20 +509,23 @@ object "Parent" { function $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($self) -> ret { let v0 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len($self) let v1 := mload(add($self, 64)) - let v2 := add(v1, 32) - let v3 := mload(add($self, 64)) - let v4 := lt(v2, v3) - if v4 { + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v3 := v2 + let v4 := mload(add($self, 64)) + let v5 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v3, v4) + let v6 := v5 + if v6 { revert(0, 0) } - let v5 := gt(v2, v0) - if v5 { + let v7 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v3, v0) + let v8 := v7 + if v8 { revert(0, 0) } - let v6 := mload(add($self, 64)) - let v7 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v6) - mstore(add($self, 64), v2) - ret := v7 + let v9 := mload(add($self, 64)) + let v10 := $memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at($self, v9) + mstore(add($self, 64), v3) + ret := v10 leave } function $soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($input) -> ret { @@ -403,11 +543,35 @@ object "Parent" { ret := v1 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_decode_hb2fe2bf528775e55_decode__Sol_hfd482bb803ad8c5f_SolDecoder_MemoryBytes___a53dbc6192a658d6($d) -> ret { let v0 := $soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_word__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b($d) ret := v0 leave } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } $__Child_init() } @@ -423,15 +587,50 @@ object "Parent" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -471,13 +670,14 @@ object "Parent" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -511,10 +711,40 @@ object "Parent" { ret := v2 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/literal_add.snap b/crates/codegen/tests/fixtures/literal_add.snap index e749ba1abb..737397c222 100644 --- a/crates/codegen/tests/fixtures/literal_add.snap +++ b/crates/codegen/tests/fixtures/literal_add.snap @@ -9,6 +9,43 @@ function $main() -> ret { leave } function $add($a, $b) -> ret { - ret := add($a, $b) + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($a, $b) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/literal_sub.snap b/crates/codegen/tests/fixtures/literal_sub.snap index 8fb0d7f1a8..0f04753598 100644 --- a/crates/codegen/tests/fixtures/literal_sub.snap +++ b/crates/codegen/tests/fixtures/literal_sub.snap @@ -4,6 +4,43 @@ expression: output input_file: tests/fixtures/literal_sub.fe --- function $literal_sub() -> ret { - ret := sub(1, 2) + let v0 := $u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub(1, 2) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u64($self, $other) + ret := v0 + leave +} +function $checked_sub_u64($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := and(sub(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/local_bindings.snap b/crates/codegen/tests/fixtures/local_bindings.snap index 1e79743024..c7176c6492 100644 --- a/crates/codegen/tests/fixtures/local_bindings.snap +++ b/crates/codegen/tests/fixtures/local_bindings.snap @@ -4,8 +4,45 @@ expression: output input_file: tests/fixtures/local_bindings.fe --- function $local_bindings() -> ret { - let v0 := add(1, 2) - let v1 := 3 - ret := v1 + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(1, 2) + let v1 := v0 + let v2 := 3 + ret := v2 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self leave } diff --git a/crates/codegen/tests/fixtures/match_mixed_return.snap b/crates/codegen/tests/fixtures/match_mixed_return.snap index cb7949a764..83672b2632 100644 --- a/crates/codegen/tests/fixtures/match_mixed_return.snap +++ b/crates/codegen/tests/fixtures/match_mixed_return.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/match_mixed_return.fe --- @@ -18,6 +17,43 @@ function $f($e) -> ret { default { } let v2 := v0 - ret := add(v2, 1) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v2, 1) + ret := v3 + leave +} +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/match_struct.snap b/crates/codegen/tests/fixtures/match_struct.snap index 90d119ad21..ab025ea8ac 100644 --- a/crates/codegen/tests/fixtures/match_struct.snap +++ b/crates/codegen/tests/fixtures/match_struct.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/match_struct.fe --- @@ -30,7 +29,8 @@ function $match_struct_fields($p) -> ret { default { let v7 := and(mload(add(v1, 32)), 0xff) let v8 := and(mload(v1), 0xff) - v0 := add(v8, v7) + let v9 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v8, v7) + v0 := v9 } } ret := v0 @@ -57,3 +57,39 @@ function $match_struct_wildcard($p) -> ret { ret := v0 leave } +function $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u8($self, $other) + ret := v0 + leave +} +function $checked_add_u8($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xff), and($other, 0xff)), 0xff) + ret := v0 + leave +} diff --git a/crates/codegen/tests/fixtures/match_tuple_binding.snap b/crates/codegen/tests/fixtures/match_tuple_binding.snap index b3cafac12d..59047931ac 100644 --- a/crates/codegen/tests/fixtures/match_tuple_binding.snap +++ b/crates/codegen/tests/fixtures/match_tuple_binding.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/match_tuple_binding.fe --- @@ -26,10 +25,11 @@ function $match_tuple_extract($t) -> ret { let v8 := v7 let v9 := and(mload(add($t, 32)), 0xff) let v10 := v9 - v0 := add(v8, v10) + let v11 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v8, v10) + v0 := v11 } } - let v11 := $t + let v12 := $t ret := v0 leave } @@ -53,36 +53,76 @@ function $match_nested_extract($t) -> ret { let v7 := v6 let v8 := and(mload($t), 0xff) let v9 := v8 - v0 := add(v9, v7) + let v10 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v9, v7) + v0 := v10 } default { - let v10 := and(mload($t), 0xff) - let v11 := v10 - let v12 := and(mload(add($t, 64)), 0xff) - let v13 := v12 - v0 := add(v11, v13) + let v11 := and(mload($t), 0xff) + let v12 := v11 + let v13 := and(mload(add($t, 64)), 0xff) + let v14 := v13 + let v15 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v12, v14) + v0 := v15 } } } default { - let v14 := and(mload(add($t, 64)), 0xff) - switch v14 + let v16 := and(mload(add($t, 64)), 0xff) + switch v16 case 0 { - let v15 := and(mload(add($t, 32)), 0xff) - let v16 := v15 - let v17 := and(mload($t), 0xff) + let v17 := and(mload(add($t, 32)), 0xff) let v18 := v17 - v0 := add(v18, v16) - } - default { let v19 := and(mload($t), 0xff) let v20 := v19 - let v21 := and(mload(add($t, 64)), 0xff) - let v22 := v21 - v0 := add(v20, v22) + let v21 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v20, v18) + v0 := v21 + } + default { + let v22 := and(mload($t), 0xff) + let v23 := v22 + let v24 := and(mload(add($t, 64)), 0xff) + let v25 := v24 + let v26 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v23, v25) + v0 := v26 } } - let v23 := $t + let v27 := $t + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u8($self, $other) + ret := v0 + leave +} +function $checked_add_u8($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xff), and($other, 0xff)), 0xff) ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/math_ops.snap b/crates/codegen/tests/fixtures/math_ops.snap index 93a3e312c3..f15db29467 100644 --- a/crates/codegen/tests/fixtures/math_ops.snap +++ b/crates/codegen/tests/fixtures/math_ops.snap @@ -4,6 +4,22 @@ expression: output input_file: tests/fixtures/math_ops.fe --- function $math_ops() -> ret { - ret := mod(div(mul(sub(10, 3), 2), 7), 3) + let v0 := $u64_haee7f05a097ffa16_rem_h890eb23a7e6cfef7_rem(div(mul(sub(10, 3), 2), 7), 3) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_rem_h890eb23a7e6cfef7_rem($self, $other) -> ret { + let v0 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := and(mod(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v2 + leave +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/momo.snap b/crates/codegen/tests/fixtures/momo.snap index 7c6696683b..df035781c3 100644 --- a/crates/codegen/tests/fixtures/momo.snap +++ b/crates/codegen/tests/fixtures/momo.snap @@ -1,12 +1,48 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/momo.fe --- function $read_x($val) -> ret { let v0 := and(mload($val), 0xff) let v1 := and(mload(add($val, 32)), 0xff) - ret := add(v0, v1) + let v2 := $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v0, v1) + ret := v2 + leave +} +function $u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u8($self, $other) + ret := v0 + leave +} +function $checked_add_u8($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u8__bc9d6eeaea22ffb5($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u8_hbc9d6eeaea22ffb5_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xff), and($other, 0xff)), 0xff) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/name_collisions.snap b/crates/codegen/tests/fixtures/name_collisions.snap index 9c64b86b64..74326a7931 100644 --- a/crates/codegen/tests/fixtures/name_collisions.snap +++ b/crates/codegen/tests/fixtures/name_collisions.snap @@ -14,7 +14,8 @@ function $a_b_h948d5ab23860c017_flattened_fn() -> ret { function $test_module_qualifier_flatten_collision() -> ret { let v0 := $a_b_h12fd23afeb13a092_flattened_fn() let v1 := $a_b_h948d5ab23860c017_flattened_fn() - ret := add(v0, v1) + let v2 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v0, v1) + ret := v2 leave } function $test_generic_type_collision() -> ret { @@ -40,13 +41,16 @@ function $test_trait_method_collision() -> ret { let v1 := $multitraitimpl_h60cc862fc809464_trait_h79853acec5b2b3ad_same_method(v0) let v2 := 100 let v3 := $multitraitimpl_h60cc862fc809464_trait_ha6da5e54b37dd39c_same_method(v2) - ret := add(v1, v3) + let v4 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v1, v3) + ret := v4 leave } function $param_local_collision($v0) -> ret { - let v0 := add($v0, 1) - let v1 := add(v0, 2) - ret := v1 + let v0 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add($v0, 1) + let v1 := v0 + let v2 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v1, 2) + let v3 := v2 + ret := v3 leave } function $test_param_local_collision() -> ret { @@ -65,7 +69,8 @@ function $test_cast_shim_collision() -> ret { leave } function $ret_param_collision($ret) -> ret { - ret := add($ret, 1) + let v0 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add($ret, 1) + ret := v0 leave } function $test_ret_param_collision() -> ret { @@ -104,22 +109,31 @@ function $main() -> ret { } function $widget_h8588afca9d68e578_process($self) -> ret { let v0 := $self - ret := mul(v0, 2) + let v1 := $u32_h20aa0c10687491ad_mul_h290dcc921ed80777_mul(v0, 2) + ret := v1 leave } function $widget_h6847c0e3e0e4aa1e_process($self) -> ret { let v0 := $self - ret := mul(v0, 3) + let v1 := $u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul(v0, 3) + ret := v1 leave } function $multitraitimpl_h60cc862fc809464_trait_h79853acec5b2b3ad_same_method($self) -> ret { let v0 := $self - ret := add(v0, 1) + let v1 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v0, 1) + ret := v1 leave } function $multitraitimpl_h60cc862fc809464_trait_ha6da5e54b37dd39c_same_method($self) -> ret { let v0 := $self - ret := add(v0, 2) + let v1 := $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v0, 2) + ret := v1 + leave +} +function $u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u32($self, $other) + ret := v0 leave } function $generic_fn__S_h730d9dc564aaaf27__8d32801e7ec9d42b($val) -> ret { @@ -130,3 +144,143 @@ function $generic_fn__S_h2db58d011b97b333__42a13489a1ec39e8($val) -> ret { ret := $val leave } +function $u32_h20aa0c10687491ad_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u32($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul($self, $other) -> ret { + let v0 := $checked_mul_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u32($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u32__20aa0c10687491ad($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u32__20aa0c10687491ad($a, $b) -> ret { + let v0 := $u32_h20aa0c10687491ad_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_mul_u32($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u32__20aa0c10687491ad($a, $b) + ret := v0 + leave +} +function $checked_mul_u64($a, $b) -> ret { + let v0 := $checked_mul_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_mul_unsigned_impl__u32__20aa0c10687491ad($a, $b) -> ret { + let v0 := $u32_h20aa0c10687491ad_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u32_h20aa0c10687491ad_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } +} +function $checked_mul_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v1, 0) + let v3 := v2 + if v3 { + let v4 := $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v0, $a) + let v5 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v4) + let v6 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v7 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v5, v6) + let v8 := v7 + if v8 { + revert(0, 0) + } + ret := v0 + leave + } + if iszero(v3) { + ret := v0 + leave + } +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u32_h20aa0c10687491ad_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u32_h20aa0c10687491ad_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := and(div(and($self, 0xffffffff), and($other, 0xffffffff)), 0xffffffff) + ret := v2 + leave +} +function $u32_h20aa0c10687491ad_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffff), and($other, 0xffffffff)) + ret := v0 + leave +} +function $u32_h20aa0c10687491ad_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffff), and($other, 0xffffffff)), 0xffffffff) + ret := v0 + leave +} +function $u32_h20aa0c10687491ad_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := and(mul(and($self, 0xffffffff), and($other, 0xffffffff)), 0xffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := and(div(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v2 + leave +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := and(mul(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/nested_struct.snap b/crates/codegen/tests/fixtures/nested_struct.snap index 90a28c1da0..288b3a868f 100644 --- a/crates/codegen/tests/fixtures/nested_struct.snap +++ b/crates/codegen/tests/fixtures/nested_struct.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/nested_struct.fe --- diff --git a/crates/codegen/tests/fixtures/newtype_field_mut_method_call.snap b/crates/codegen/tests/fixtures/newtype_field_mut_method_call.snap index b4a0999eb0..1c9997b31c 100644 --- a/crates/codegen/tests/fixtures/newtype_field_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/newtype_field_mut_method_call.snap @@ -29,12 +29,50 @@ function $newtype_field_mut_method_call($x) -> ret { function $counter_h872958864d1ad471_bump($self) { let v0 := $self let v1 := mload(v0) - mstore(v0, add(v1, 1)) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 1) + mstore(v0, v2) leave } function $wrapcounter_hbcbd3a74a267488b_bump($self) { let v0 := $self let v1 := mload(v0) - mstore(v0, add(v1, 1)) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 1) + mstore(v0, v2) + leave +} +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } diff --git a/crates/codegen/tests/fixtures/newtype_storage_byplace_effect_arg.snap b/crates/codegen/tests/fixtures/newtype_storage_byplace_effect_arg.snap index 617536eabe..81a19c5fa5 100644 --- a/crates/codegen/tests/fixtures/newtype_storage_byplace_effect_arg.snap +++ b/crates/codegen/tests/fixtures/newtype_storage_byplace_effect_arg.snap @@ -116,9 +116,10 @@ object "NewtypeByPlaceEffectArg" { function $__NewtypeByPlaceEffectArg_recv_0_0($args, $w, $x) -> ret { $bump__StorPtr_Wrap___5036bb3e02939b91($w) let v0 := sload($x) - sstore($x, add(v0, 1)) - let v1 := sload($x) - ret := v1 + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 1) + sstore($x, v1) + let v2 := sload($x) + ret := v2 leave } function $__NewtypeByPlaceEffectArg_runtime() { @@ -138,7 +139,8 @@ object "NewtypeByPlaceEffectArg" { } function $bump__StorPtr_Wrap___5036bb3e02939b91($w) { let v0 := sload($w) - sstore($w, add(v0, 1)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 1) + sstore($w, v1) leave } function $bump_hfb5a53c6af92b8a6_decode_h624c3cd8c996d995_decode__SolDecoder_CallData___c1e4510fd444b966($d) { @@ -146,15 +148,50 @@ object "NewtypeByPlaceEffectArg" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -217,13 +254,14 @@ object "NewtypeByPlaceEffectArg" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -265,37 +303,41 @@ object "NewtypeByPlaceEffectArg" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -324,14 +366,49 @@ object "NewtypeByPlaceEffectArg" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383($self, $e) { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/newtype_storage_field_mut_method_call.snap b/crates/codegen/tests/fixtures/newtype_storage_field_mut_method_call.snap index c664bf37e6..215bfa0409 100644 --- a/crates/codegen/tests/fixtures/newtype_storage_field_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/newtype_storage_field_mut_method_call.snap @@ -140,15 +140,50 @@ object "NewtypeStorageFieldMutMethodCall" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -211,13 +246,14 @@ object "NewtypeStorageFieldMutMethodCall" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -259,37 +295,41 @@ object "NewtypeStorageFieldMutMethodCall" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -318,14 +358,49 @@ object "NewtypeStorageFieldMutMethodCall" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383($self, $e) { $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($e, $self) leave } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave @@ -333,7 +408,8 @@ object "NewtypeStorageFieldMutMethodCall" { function $wrap_haf9e70905fcbd513_bump_stor_arg0_root_stor($self) { let v0 := $self let v1 := sload($self) - sstore($self, add(v1, 1)) + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 1) + sstore($self, v2) leave } $__NewtypeStorageFieldMutMethodCall_runtime() diff --git a/crates/codegen/tests/fixtures/newtype_word_mut_method_call.snap b/crates/codegen/tests/fixtures/newtype_word_mut_method_call.snap index 475147aa46..6dbbf5d7d0 100644 --- a/crates/codegen/tests/fixtures/newtype_word_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/newtype_word_mut_method_call.snap @@ -10,7 +10,44 @@ function $newtype_word_mut_method_call($x) -> ret { leave } function $wrap_haf9e70905fcbd513_bump($self) -> ret { - $self := add($self, 1) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, 1) + $self := v0 ret := $self leave } +function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave +} +function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} diff --git a/crates/codegen/tests/fixtures/range_bounds.snap b/crates/codegen/tests/fixtures/range_bounds.snap index 49c4a65311..9624e83fec 100644 --- a/crates/codegen/tests/fixtures/range_bounds.snap +++ b/crates/codegen/tests/fixtures/range_bounds.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/range_bounds.fe --- @@ -11,7 +10,8 @@ function $sum_const() -> ret { for { } lt(v1, v2) { v1 := add(v1, 1) } { let v3 := $range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c(0, v1) let v4 := v3 - v0 := add(v0, v4) + let v5 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, v4) + v0 := v5 } ret := v0 leave @@ -29,7 +29,8 @@ function $sum_dynamic_end($end) -> ret { for { } lt(v2, v3) { v2 := add(v2, 1) } { let v4 := $range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c(v1, v2) let v5 := v4 - v0 := add(v0, v5) + let v6 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, v5) + v0 := v6 } ret := v0 leave @@ -47,7 +48,8 @@ function $sum_dynamic_start($start) -> ret { for { } lt(v2, v3) { v2 := add(v2, 1) } { let v4 := $range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e(v1, v2) let v5 := v4 - v0 := add(v0, v5) + let v6 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, v5) + v0 := v6 } ret := v0 leave @@ -66,37 +68,48 @@ function $sum_dynamic($start, $end) -> ret { for { } lt(v2, v3) { v2 := add(v2, 1) } { let v4 := $range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e(v1, v2) let v5 := v4 - v0 := add(v0, v5) + let v6 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, v5) + v0 := v6 } ret := v0 leave } function $range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_len__0_4__f9605efabd18106c($self) -> ret { let v0 := 0 - let v1 := lt(4, 0) - if v1 { + let v1 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(4, 0) + let v2 := v1 + if v2 { v0 := 0 } - if iszero(v1) { - v0 := sub(4, 0) + if iszero(v2) { + let v3 := $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(4, 0) + v0 := v3 } ret := v0 leave } function $range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c($self, $i) -> ret { - ret := add(0, $i) + let v0 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(0, $i) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_usize($self, $other) + ret := v0 leave } function $range_known_const_s__usize___unknown__h4e84f6b6b8307914_seq_ha637d2df505bccf2_len__0__fc6647014fb554e5($self) -> ret { let v0 := 0 let v1 := mload($self) - let v2 := lt(v1, 0) - if v2 { + let v2 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v1, 0) + let v3 := v2 + if v3 { v0 := 0 } - if iszero(v2) { - let v3 := mload($self) - v0 := sub(v3, 0) + if iszero(v3) { + let v4 := mload($self) + let v5 := $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(v4, 0) + v0 := v5 } ret := v0 leave @@ -104,35 +117,108 @@ function $range_known_const_s__usize___unknown__h4e84f6b6b8307914_seq_ha637d2df5 function $range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_len__4__f248ae0e02044d7e($self) -> ret { let v0 := 0 let v1 := mload($self) - let v2 := lt(4, v1) - if v2 { + let v2 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(4, v1) + let v3 := v2 + if v3 { v0 := 0 } - if iszero(v2) { - let v3 := mload($self) - v0 := sub(4, v3) + if iszero(v3) { + let v4 := mload($self) + let v5 := $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(4, v4) + v0 := v5 } ret := v0 leave } function $range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e($self, $i) -> ret { let v0 := mload($self) - ret := add(v0, $i) + let v1 := $usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0, $i) + ret := v1 leave } function $range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_len($self) -> ret { let v0 := 0 let v1 := mload(add($self, 32)) let v2 := mload($self) - let v3 := lt(v1, v2) - if v3 { + let v3 := $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { v0 := 0 } - if iszero(v3) { - let v4 := mload(add($self, 32)) - let v5 := mload($self) - v0 := sub(v4, v5) + if iszero(v4) { + let v5 := mload(add($self, 32)) + let v6 := mload($self) + let v7 := $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(v5, v6) + v0 := v7 } ret := v0 leave } +function $usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_usize($self, $other) + ret := v0 + leave +} +function $checked_add_unsigned_impl__usize__a12462c6d36e68b0($a, $b) -> ret { + let v0 := $usize_ha12462c6d36e68b0_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_add_usize($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__usize__a12462c6d36e68b0($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__usize__a12462c6d36e68b0($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $usize_ha12462c6d36e68b0_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $checked_sub_usize($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__usize__a12462c6d36e68b0($a, $b) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} +function $usize_ha12462c6d36e68b0_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} +function $usize_ha12462c6d36e68b0_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave +} diff --git a/crates/codegen/tests/fixtures/ret.snap b/crates/codegen/tests/fixtures/ret.snap index 39c946feec..fdcf59ec53 100644 --- a/crates/codegen/tests/fixtures/ret.snap +++ b/crates/codegen/tests/fixtures/ret.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 42 expression: output input_file: tests/fixtures/ret.fe --- @@ -11,22 +10,104 @@ function $retfoo($b1, $x) -> ret { leave } if iszero(v0) { - let v1 := lt($x, 5) - if v1 { + let v1 := $u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt($x, 5) + let v2 := v1 + if v2 { ret := 1 leave } - if iszero(v1) { - let v2 := sub($x, 1) - let v3 := eq(v2, 42) - if v3 { + if iszero(v2) { + let v3 := $u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub($x, 1) + let v4 := v3 + let v5 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq(v4, 42) + let v6 := v5 + if v6 { ret := 2 leave } - if iszero(v3) { - ret := add(v2, 1) + if iszero(v6) { + let v7 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v4, 1) + ret := v7 leave } } } } +function $u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u64($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave +} +function $checked_sub_u64($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_sub_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := and(sub(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/sonatina_ir/arg_bindings.snap b/crates/codegen/tests/fixtures/sonatina_ir/arg_bindings.snap index bde5fbc0b9..1e96f5612d 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/arg_bindings.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/arg_bindings.snap @@ -7,10 +7,28 @@ target = "evm-ethereum-osaka" func private %arg_bindings(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v0 v1; return v3; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %arg_bindings 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/aug_assign.snap b/crates/codegen/tests/fixtures/sonatina_ir/aug_assign.snap index 1e7f2649ae..34fe5587b7 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/aug_assign.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/aug_assign.snap @@ -7,12 +7,74 @@ target = "evm-ethereum-osaka" func private %aug_assign(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v5.i256 = mul v3 2.i256; - v6.i256 = evm_udiv v5 2.i256; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v0 v1; + v5.i256 = call %u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul v3 2.i256; + v6.i256 = call %u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div v5 2.i256; return v6; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + +func private %u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = mul v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = ne v6 0.i256; + v10.i256 = evm_udiv v8 v6; + v11.i1 = ne v10 v7; + v12.i1 = and v9 v11; + br v12 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + +func private %u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v1 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v7.i256 = evm_udiv v0 v1; + return v7; +} + +func private %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = eq v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %aug_assign 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/aug_assign_bit_ops.snap b/crates/codegen/tests/fixtures/sonatina_ir/aug_assign_bit_ops.snap index 73bdc4c3ce..6ecf7d4d02 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/aug_assign_bit_ops.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/aug_assign_bit_ops.snap @@ -7,15 +7,151 @@ target = "evm-ethereum-osaka" func private %aug_assign_bit_ops(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = evm_exp v0 v1; - v5.i256 = shl 3.i256 v3; - v7.i256 = shr 1.i256 v5; - v9.i256 = and v7 255.i256; - v10.i256 = or v9 1.i256; - v12.i256 = xor v10 2.i256; + v3.i256 = call %u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow v0 v1; + v5.i256 = call %u256_h3271ca15373d4483_shl_hfe0d524bf4e7a124_shl v3 3.i256; + v7.i256 = call %u256_h3271ca15373d4483_shr_hb0ca004ad39836df_shr v5 1.i256; + v9.i256 = call %u256_h3271ca15373d4483_bitand_h78a0a00271c00767_bitand v7 255.i256; + v10.i256 = call %u256_h3271ca15373d4483_bitor_h862fc0845ef3fe28_bitor v9 1.i256; + v12.i256 = call %u256_h3271ca15373d4483_bitxor_he2c04823a0ac81d4_bitxor v10 2.i256; return v12; } +func private %u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %pow_checked__u256__3271ca15373d4483 v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_shl_hfe0d524bf4e7a124_shl(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = shl v1 v0; + return v3; +} + +func private %u256_h3271ca15373d4483_shr_hb0ca004ad39836df_shr(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = shr v1 v0; + return v3; +} + +func private %u256_h3271ca15373d4483_bitand_h78a0a00271c00767_bitand(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = and v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_bitor_h862fc0845ef3fe28_bitor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = or v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_bitxor_he2c04823a0ac81d4_bitxor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = xor v0 v1; + return v3; +} + +func private %pow_checked__u256__3271ca15373d4483(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v1; + v5.i256 = and v3 -1.i256; + v6.i1 = ne 0.i256 0.i256; + br v6 block3 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v9.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v0; + jump block4; + + block3: + v12.i256 = and v5 0.i256; + v13.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v12 0.i256; + v14.i1 = ne v13 0.i256; + br v14 block1 block2; + + block4: + v43.i256 = phi (v9 block2) (v44 block10); + v41.i256 = phi (1.i256 block2) (v46 block10); + v15.i256 = phi (v5 block2) (v31 block10); + v16.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 0.i256; + v17.i1 = ne v16 0.i256; + br v17 block5 block6; + + block5: + v19.i256 = and v15 1.i256; + v20.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v19 0.i256; + v21.i1 = ne v20 0.i256; + br v21 block7 block8; + + block6: + v23.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v41; + return v23; + + block7: + v25.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v41; + v27.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v28.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v25 v27; + v29.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v28; + jump block8; + + block8: + v46.i256 = phi (v41 block5) (v29 block7); + v31.i256 = shr 1.i256 v15; + v32.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v31 0.i256; + v33.i1 = ne v32 0.i256; + br v33 block9 block10; + + block9: + v35.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v36.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v37.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v35 v36; + v38.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v37; + jump block10; + + block10: + v44.i256 = phi (v43 block8) (v38 block9); + jump block4; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v0.i256) -> i256 { + block0: + return v0; +} + +func private %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = mul v0 v1; + v4.i1 = ne v0 0.i256; + v5.i256 = evm_udiv v3 v0; + v6.i1 = ne v5 v1; + v7.i1 = and v4 v6; + br v7 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %aug_assign_bit_ops 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/bit_ops.snap b/crates/codegen/tests/fixtures/sonatina_ir/bit_ops.snap index a214c0a94c..c3f5596642 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/bit_ops.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/bit_ops.snap @@ -36,7 +36,113 @@ func private %bit_ops(v0.i256, v1.i256) -> i256 { func private %pow_op(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = evm_exp v0 v1; + v3.i256 = call %u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_pow_haae116e5e5042c2c_pow(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %pow_checked__u256__3271ca15373d4483 v0 v1; + return v3; +} + +func private %pow_checked__u256__3271ca15373d4483(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v1; + v5.i256 = and v3 -1.i256; + v6.i1 = ne 0.i256 0.i256; + br v6 block3 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v9.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v0; + jump block4; + + block3: + v12.i256 = and v5 0.i256; + v13.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v12 0.i256; + v14.i1 = ne v13 0.i256; + br v14 block1 block2; + + block4: + v43.i256 = phi (v9 block2) (v44 block10); + v41.i256 = phi (1.i256 block2) (v46 block10); + v15.i256 = phi (v5 block2) (v31 block10); + v16.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 0.i256; + v17.i1 = ne v16 0.i256; + br v17 block5 block6; + + block5: + v19.i256 = and v15 1.i256; + v20.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v19 0.i256; + v21.i1 = ne v20 0.i256; + br v21 block7 block8; + + block6: + v23.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v41; + return v23; + + block7: + v25.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v41; + v27.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v28.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v25 v27; + v29.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v28; + jump block8; + + block8: + v46.i256 = phi (v41 block5) (v29 block7); + v31.i256 = shr 1.i256 v15; + v32.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v31 0.i256; + v33.i1 = ne v32 0.i256; + br v33 block9 block10; + + block9: + v35.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v36.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v43; + v37.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v35 v36; + v38.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word v37; + jump block10; + + block10: + v44.i256 = phi (v43 block8) (v38 block9); + jump block4; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_from_word(v0.i256) -> i256 { + block0: + return v0; +} + +func private %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = mul v0 v1; + v4.i1 = ne v0 0.i256; + v5.i256 = evm_udiv v3 v0; + v6.i1 = ne v5 v1; + v7.i1 = and v4 v6; + br v7 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: return v3; } diff --git a/crates/codegen/tests/fixtures/sonatina_ir/block_expr.snap b/crates/codegen/tests/fixtures/sonatina_ir/block_expr.snap index ca8431aa62..8303a8972e 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/block_expr.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/block_expr.snap @@ -7,10 +7,28 @@ target = "evm-ethereum-osaka" func private %block_expr() -> i256 { block0: - v3.i256 = add 1.i256 2.i256; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add 1.i256 2.i256; return v3; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %block_expr; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/borrow_storage_field_handle.snap b/crates/codegen/tests/fixtures/sonatina_ir/borrow_storage_field_handle.snap index fe66524509..f02727a978 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/borrow_storage_field_handle.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/borrow_storage_field_handle.snap @@ -8,12 +8,25 @@ target = "evm-ethereum-osaka" func private %borrow_storage_field_handle__StorPtr_CoinStore___ba1c0d0726e89ba2(v0.i256) -> i256 { block0: v2.i256 = evm_sload v0; - v4.i256 = add v2 1.i256; + v4.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v2 1.i256; evm_sstore v0 v4; v5.i256 = evm_sload v0; return v5; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %borrow_storage_field_handle__StorPtr_CoinStore___ba1c0d0726e89ba2 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/by_ref_trait_provider_storage_bug.snap b/crates/codegen/tests/fixtures/sonatina_ir/by_ref_trait_provider_storage_bug.snap index c4b99f1792..7c33a921e9 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/by_ref_trait_provider_storage_bug.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/by_ref_trait_provider_storage_bug.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/by_ref_trait_provider_storage_bug.fe --- @@ -24,7 +23,7 @@ func private %pair_h956dff41e88ee341_ctx_h4952b3c1f066f039_sum(v0.i256) -> i256 v5.*@__fe_Pair_0 = int_to_ptr v0 *@__fe_Pair_0; v7.*i256 = gep v5 0.i256 1.i256; v8.i256 = mload v7 i256; - v9.i256 = add v4 v8; + v9.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v8; return v9; } @@ -108,6 +107,19 @@ func private %__ByRefTraitProviderStorageBug_runtime() { evm_invalid; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %use_ctx_eff0_stor__Pair_h956dff41e88ee341__acec41afdc898140(v0.i256) -> i256 { block0: v2.i256 = call %pair_h956dff41e88ee341_ctx_h4952b3c1f066f039_sum_stor_arg0_root_stor v0; @@ -141,19 +153,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -189,7 +200,7 @@ func private %pair_h956dff41e88ee341_ctx_h4952b3c1f066f039_sum_stor_arg0_root_st v2.i256 = evm_sload v0; v4.i256 = add v0 1.i256; v5.i256 = evm_sload v4; - v6.i256 = add v2 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v2 v5; return v6; } @@ -236,16 +247,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -272,31 +289,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -313,16 +329,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -330,6 +346,19 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes( evm_return v1 v2; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b(v0.i256) -> i256 { block0: v3.*i8 = evm_malloc 96.i256; @@ -357,6 +386,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -404,13 +446,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_5 = int_to_ptr v0 *@__fe_SolEncoder_5; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/cast_u8_usize_cmp.snap b/crates/codegen/tests/fixtures/sonatina_ir/cast_u8_usize_cmp.snap index d0d5db632e..5018c8c293 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/cast_u8_usize_cmp.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/cast_u8_usize_cmp.snap @@ -12,28 +12,25 @@ func private %cast_u8_usize_cmp(v0.i256, v1.i256, v2.i256) -> i256 { v6.i256 = mload v5 i256; v7.i8 = trunc v6 i8; v8.i256 = zext v7 i256; - v9.i1 = lt v2 v8; - v10.i256 = zext v9 i256; - v11.i1 = ne v10 0.i256; - br v11 block1 block2; + v9.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt v2 v8; + v10.i1 = ne v9 0.i256; + br v10 block1 block2; block1: return 1.i256; block2: - v15.i1 = eq v2 v8; - v16.i256 = zext v15 i256; - v17.i1 = ne v16 0.i256; - br v17 block3 block4; + v14.i256 = call %usize_ha12462c6d36e68b0_eq_he50383edd273619f_eq v2 v8; + v15.i1 = ne v14 0.i256; + br v15 block3 block4; block3: return 2.i256; block4: - v21.i1 = gt v2 v8; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block5 block6; + v19.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_gt v2 v8; + v20.i1 = ne v19 0.i256; + br v20 block5 block6; block5: return 3.i256; @@ -42,6 +39,27 @@ func private %cast_u8_usize_cmp(v0.i256, v1.i256, v2.i256) -> i256 { return 0.i256; } +func private %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %usize_ha12462c6d36e68b0_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %cast_u8_usize_cmp 0.i256 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/code_region.snap b/crates/codegen/tests/fixtures/sonatina_ir/code_region.snap index 92615d8444..f0c45b9735 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/code_region.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/code_region.snap @@ -59,19 +59,18 @@ func private %child_runtime__StorPtr_Evm___207f35a85ac4062e() { func private %allocate__Evm_hef0af3106e109414__3af54274b2985741(v0.i256, v1.i256) -> i256 { block0: v4.i256 = mload 64.i256 i256; - v5.i1 = eq v4 0.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v4 0.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: jump block2; block2: - v9.i256 = phi (v4 block0) (96.i256 block1); - v11.i256 = add v9 v0; - mstore 64.i256 v11 i256; - return v9; + v8.i256 = phi (v4 block0) (96.i256 block1); + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v8 v0; + mstore 64.i256 v10 i256; + return v8; } func private %balance__Evm_hef0af3106e109414__3af54274b2985741(v0.i256) { @@ -97,6 +96,26 @@ func private %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create2_raw_stor_ar return v6; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + object @Child { section init { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/comparison_ops.snap b/crates/codegen/tests/fixtures/sonatina_ir/comparison_ops.snap index cac3e10f9f..520a6fe5e4 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/comparison_ops.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/comparison_ops.snap @@ -9,54 +9,90 @@ type @__fe_tuple_0 = {i256, i256, i256, i256, i256, i256}; func private %comparison_ops() -> i256 { block0: - v5.*i8 = evm_malloc 192.i256; - v6.i256 = ptr_to_int v5 i256; - v7.i1 = eq 1.i256 1.i256; - v8.i256 = zext v7 i256; - v9.i1 = ne v8 0.i256; - v10.i256 = zext v9 i256; - v11.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v12.*i256 = gep v11 0.i256 0.i256; - mstore v12 v10 i256; - v13.i1 = eq 1.i256 2.i256; - v14.i1 = is_zero v13; - v15.i256 = zext v14 i256; - v16.i1 = ne v15 0.i256; - v17.i256 = zext v16 i256; - v18.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v19.*i256 = gep v18 0.i256 1.i256; - mstore v19 v17 i256; - v20.i1 = lt 1.i256 2.i256; - v21.i256 = zext v20 i256; - v22.i1 = ne v21 0.i256; - v23.i256 = zext v22 i256; - v24.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v25.*i256 = gep v24 0.i256 2.i256; - mstore v25 v23 i256; - v26.i1 = gt 2.i256 2.i256; - v27.i1 = is_zero v26; - v28.i256 = zext v27 i256; - v29.i1 = ne v28 0.i256; + v4.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq 1.i256 1.i256; + v5.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne 1.i256 2.i256; + v6.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt 1.i256 2.i256; + v7.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_le 2.i256 2.i256; + v8.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt 3.i256 2.i256; + v9.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge 3.i256 3.i256; + v11.*i8 = evm_malloc 192.i256; + v12.i256 = ptr_to_int v11 i256; + v13.i1 = ne v4 0.i256; + v14.i256 = zext v13 i256; + v15.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v16.*i256 = gep v15 0.i256 0.i256; + mstore v16 v14 i256; + v17.i1 = ne v5 0.i256; + v18.i256 = zext v17 i256; + v19.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v20.*i256 = gep v19 0.i256 1.i256; + mstore v20 v18 i256; + v21.i1 = ne v6 0.i256; + v22.i256 = zext v21 i256; + v23.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v24.*i256 = gep v23 0.i256 2.i256; + mstore v24 v22 i256; + v25.i1 = ne v7 0.i256; + v26.i256 = zext v25 i256; + v27.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v28.*i256 = gep v27 0.i256 3.i256; + mstore v28 v26 i256; + v29.i1 = ne v8 0.i256; v30.i256 = zext v29 i256; - v31.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v32.*i256 = gep v31 0.i256 3.i256; - mstore v32 v30 i256; - v33.i1 = gt 3.i256 2.i256; - v34.i256 = zext v33 i256; - v35.i1 = ne v34 0.i256; - v36.i256 = zext v35 i256; - v37.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v39.*i256 = gep v37 0.i256 4.i256; - mstore v39 v36 i256; - v40.i1 = lt 3.i256 3.i256; - v41.i1 = is_zero v40; - v42.i256 = zext v41 i256; - v43.i1 = ne v42 0.i256; - v44.i256 = zext v43 i256; - v45.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; - v47.*i256 = gep v45 0.i256 5.i256; - mstore v47 v44 i256; - return v6; + v31.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v33.*i256 = gep v31 0.i256 4.i256; + mstore v33 v30 i256; + v34.i1 = ne v9 0.i256; + v35.i256 = zext v34 i256; + v36.*@__fe_tuple_0 = bitcast v11 *@__fe_tuple_0; + v38.*i256 = gep v36 0.i256 5.i256; + mstore v38 v35 i256; + return v12; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_le(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; } func private %__fe_sonatina_entry() { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/const_array.snap b/crates/codegen/tests/fixtures/sonatina_ir/const_array.snap index fd75867ce6..e2b145b6e2 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/const_array.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/const_array.snap @@ -14,29 +14,42 @@ func private %sum_two(v0.i256, v1.i256) -> i256 { v6.i256 = sym_addr $__fe_const_data_0; v7.i256 = sym_size $__fe_const_data_0; evm_code_copy v5 v6 v7; - v8.*[i256; 3] = bitcast v4 *[i256; 3]; - v9.*i256 = gep v8 0.i256 v0; - v10.i256 = mload v9 i256; - v11.*i8 = evm_malloc 96.i256; - v12.i256 = ptr_to_int v11 i256; - v13.i256 = sym_addr $__fe_const_data_0; - v14.i256 = sym_size $__fe_const_data_0; - evm_code_copy v12 v13 v14; - v15.*[i256; 3] = bitcast v11 *[i256; 3]; + v8.*i8 = evm_malloc 96.i256; + v9.i256 = ptr_to_int v8 i256; + v10.i256 = sym_addr $__fe_const_data_0; + v11.i256 = sym_size $__fe_const_data_0; + evm_code_copy v9 v10 v11; + v12.*[i256; 3] = bitcast v4 *[i256; 3]; + v13.*i256 = gep v12 0.i256 v0; + v14.i256 = mload v13 i256; + v15.*[i256; 3] = bitcast v8 *[i256; 3]; v16.*i256 = gep v15 0.i256 v1; v17.i256 = mload v16 i256; - v18.*i8 = evm_malloc 96.i256; - v19.i256 = ptr_to_int v18 i256; - v20.i256 = sym_addr $__fe_const_data_0; - v21.i256 = sym_size $__fe_const_data_0; - evm_code_copy v19 v20 v21; - v22.*i8 = evm_malloc 96.i256; - v23.i256 = ptr_to_int v22 i256; - v24.i256 = sym_addr $__fe_const_data_0; - v25.i256 = sym_size $__fe_const_data_0; - evm_code_copy v23 v24 v25; - v26.i256 = add v10 v17; - return v26; + v18.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v14 v17; + v19.*i8 = evm_malloc 96.i256; + v20.i256 = ptr_to_int v19 i256; + v21.i256 = sym_addr $__fe_const_data_0; + v22.i256 = sym_size $__fe_const_data_0; + evm_code_copy v20 v21 v22; + v23.*i8 = evm_malloc 96.i256; + v24.i256 = ptr_to_int v23 i256; + v25.i256 = sym_addr $__fe_const_data_0; + v26.i256 = sym_size $__fe_const_data_0; + evm_code_copy v24 v25 v26; + return v18; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; } func private %__fe_sonatina_entry() { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/const_array_add.snap b/crates/codegen/tests/fixtures/sonatina_ir/const_array_add.snap index 527583c529..c27f53e3b4 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/const_array_add.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/const_array_add.snap @@ -17,10 +17,23 @@ func private %get_sum() -> i256 { v6.*[i256; 3] = bitcast v2 *[i256; 3]; v7.*i256 = gep v6 0.i256 0.i256; v8.i256 = mload v7 i256; - v10.i256 = add 1.i256 v8; + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add 1.i256 v8; return v10; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %get_sum; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/create_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/create_contract.snap index 94d6e3d6f4..6cc27b2150 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/create_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/create_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/create_contract.fe --- @@ -184,19 +183,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -210,36 +208,35 @@ func private %create_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d62 block0: v4.i256 = call %__Child_init_code_len; v5.i256 = call %__Child_init_code_offset; - v7.i256 = add v4 64.i256; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 64.i256; v8.*i8 = evm_malloc v7; v9.i256 = ptr_to_int v8 i256; evm_code_copy v9 v5 v4; - v10.i256 = add v9 v4; - v12.*i8 = evm_malloc 96.i256; - v13.i256 = ptr_to_int v12 i256; - v14.*@__fe_SolEncoder_4 = bitcast v12 *@__fe_SolEncoder_4; - v15.*i256 = gep v14 0.i256 0.i256; - mstore v15 v10 i256; - v16.*@__fe_SolEncoder_4 = bitcast v12 *@__fe_SolEncoder_4; - v18.*i256 = gep v16 0.i256 1.i256; - mstore v18 v10 i256; - v19.i256 = add v10 64.i256; - v20.*@__fe_SolEncoder_4 = bitcast v12 *@__fe_SolEncoder_4; + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v9 v4; + v11.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 64.i256; + v13.*i8 = evm_malloc 96.i256; + v14.i256 = ptr_to_int v13 i256; + v15.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; + v16.*i256 = gep v15 0.i256 0.i256; + mstore v16 v10 i256; + v17.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; + v19.*i256 = gep v17 0.i256 1.i256; + mstore v19 v10 i256; + v20.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; v22.*i256 = gep v20 0.i256 2.i256; - mstore v22 v19 i256; - call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v13; + mstore v22 v11 i256; + call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v14; v23.i256 = call %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor v0 v1 v9 v7; - v24.i1 = eq v23 0.i256; - v25.i256 = zext v24 i256; - v26.i1 = ne v25 0.i256; - br v26 block1 block2; + v24.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v23 0.i256; + v25.i1 = ne v24 0.i256; + br v25 block1 block2; block1: - v27.i256 = evm_return_data_size; - v28.*i8 = evm_malloc v27; - v29.i256 = ptr_to_int v28 i256; - evm_return_data_copy v29 0.i256 v27; - evm_revert v29 v27; + v26.i256 = evm_return_data_size; + v27.*i8 = evm_malloc v26; + v28.i256 = ptr_to_int v27 i256; + evm_return_data_copy v28 0.i256 v26; + evm_revert v28 v26; block2: return v23; @@ -249,36 +246,35 @@ func private %create2_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d6 block0: v5.i256 = call %__Child_init_code_len; v6.i256 = call %__Child_init_code_offset; - v8.i256 = add v5 64.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 64.i256; v9.*i8 = evm_malloc v8; v10.i256 = ptr_to_int v9 i256; evm_code_copy v10 v6 v5; - v11.i256 = add v10 v5; - v13.*i8 = evm_malloc 96.i256; - v14.i256 = ptr_to_int v13 i256; - v15.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; - v16.*i256 = gep v15 0.i256 0.i256; - mstore v16 v11 i256; - v17.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; - v19.*i256 = gep v17 0.i256 1.i256; - mstore v19 v11 i256; - v20.i256 = add v11 64.i256; - v21.*@__fe_SolEncoder_4 = bitcast v13 *@__fe_SolEncoder_4; + v11.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v5; + v12.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v11 64.i256; + v14.*i8 = evm_malloc 96.i256; + v15.i256 = ptr_to_int v14 i256; + v16.*@__fe_SolEncoder_4 = bitcast v14 *@__fe_SolEncoder_4; + v17.*i256 = gep v16 0.i256 0.i256; + mstore v17 v11 i256; + v18.*@__fe_SolEncoder_4 = bitcast v14 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 1.i256; + mstore v20 v11 i256; + v21.*@__fe_SolEncoder_4 = bitcast v14 *@__fe_SolEncoder_4; v23.*i256 = gep v21 0.i256 2.i256; - mstore v23 v20 i256; - call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v14; + mstore v23 v12 i256; + call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v15; v24.i256 = call %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create2_raw_stor_arg0_root_stor v0 v1 v10 v8 v3; - v25.i1 = eq v24 0.i256; - v26.i256 = zext v25 i256; - v27.i1 = ne v26 0.i256; - br v27 block1 block2; + v25.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v24 0.i256; + v26.i1 = ne v25 0.i256; + br v26 block1 block2; block1: - v28.i256 = evm_return_data_size; - v29.*i8 = evm_malloc v28; - v30.i256 = ptr_to_int v29 i256; - evm_return_data_copy v30 0.i256 v28; - evm_revert v30 v28; + v27.i256 = evm_return_data_size; + v28.*i8 = evm_malloc v27; + v29.i256 = ptr_to_int v28 i256; + evm_return_data_copy v29 0.i256 v27; + evm_revert v29 v27; block2: return v24; @@ -376,44 +372,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; v17.*@__fe_Cursor_5 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; - v26.*@__fe_Cursor_5 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*i256 = gep v26 0.i256 1.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; - v31.*@__fe_Cursor_5 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*@__fe_MemoryBytes_0 = gep v31 0.i256 0.i256; - v34.i256 = ptr_to_int v33 i256; - v35.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v34 v29; - v37.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; - v38.*@__fe_Cursor_5 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; + v25.*@__fe_Cursor_5 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*i256 = gep v25 0.i256 1.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; + v30.*@__fe_Cursor_5 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*@__fe_MemoryBytes_0 = gep v30 0.i256 0.i256; + v33.i256 = ptr_to_int v32 i256; + v34.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v33 v28; + v36.*@__fe_SolDecoder_6 = int_to_ptr v0 *@__fe_SolDecoder_6; + v37.*@__fe_Cursor_5 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %stor_ptr__Evm_hef0af3106e109414_Pair_h956dff41e88ee341__18f2eb617f185785(v0.i256, v1.i256) -> i256 { @@ -430,16 +424,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -467,6 +467,19 @@ func private %__Child_init_code_offset() -> i256 { return v1; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64(v0.i256, v1.i256) { block0: v3.*@__fe_tuple_2 = int_to_ptr v0 *@__fe_tuple_2; @@ -486,6 +499,13 @@ func private %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg return v5; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create2_raw_stor_arg0_root_stor(v0.i256, v1.i256, v2.i256, v3.i256, v4.i256) -> i256 { block0: v6.i256 = evm_create2 v1 v2 v3 v4; @@ -509,31 +529,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %address_h257056268eac7027_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -550,16 +569,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -602,10 +621,16 @@ func private %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at( v3.*@__fe_MemoryBytes_0 = int_to_ptr v0 *@__fe_MemoryBytes_0; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i256 = add v5 v1; - v7.i256 = add v5 v1; - v8.i256 = mload v7 i256; - return v8; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 v1; + v7.i256 = mload v6 i256; + return v7; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; } func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__Pair_h956dff41e88ee341__acec41afdc898140(v0.i256) -> i256 { @@ -613,6 +638,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -663,44 +701,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; v17.*@__fe_Cursor_8 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; - v26.*@__fe_Cursor_8 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*@__fe_CallData_7 = gep v26 0.i256 0.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; - v31.*@__fe_Cursor_8 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*i256 = gep v31 0.i256 1.i256; - v34.i256 = mload v33 i256; - v35.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v29 v34; - v37.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; - v38.*@__fe_Cursor_8 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; + v25.*@__fe_Cursor_8 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*@__fe_CallData_7 = gep v25 0.i256 0.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; + v30.*@__fe_Cursor_8 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*i256 = gep v30 0.i256 1.i256; + v33.i256 = mload v32 i256; + v34.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v28 v33; + v36.*@__fe_SolDecoder_9 = int_to_ptr v0 *@__fe_SolDecoder_9; + v37.*@__fe_Cursor_8 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %solencoder_h1b9228b90dad6928_new() -> i256 { @@ -725,7 +761,7 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_wo v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/effect_ptr_domains.snap b/crates/codegen/tests/fixtures/sonatina_ir/effect_ptr_domains.snap index 6a812d6df8..72796c2a4d 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/effect_ptr_domains.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/effect_ptr_domains.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/effect_ptr_domains.fe --- @@ -11,11 +10,11 @@ type @__fe_Foo_0 = {i256, i256}; func private %bump__StorPtr_Foo___3698cc3c4b2626e3(v0.i256) { block0: v2.i256 = evm_sload v0; - v4.i256 = add v2 1.i256; + v4.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v2 1.i256; evm_sstore v0 v4; v5.i256 = add v0 1.i256; v6.i256 = evm_sload v5; - v8.i256 = add v6 2.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v6 2.i256; v9.i256 = add v0 1.i256; evm_sstore v9 v8; return; @@ -39,6 +38,19 @@ func private %test_effect_ptr_domains__Evm_hef0af3106e109414_Evm_hef0af3106e1094 return; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %mem_ptr_stor_arg0_root_stor__Evm_hef0af3106e109414_Foo_h6dbce71a6ea992b8__c09e6c6fc5a7b23d(v0.i256, v1.i256) -> i256 { block0: v3.i256 = call %memptr_t__hf71ec14ffe47fb3f_effecthandle_hfc52f915596f993a_from_raw__Foo_h6dbce71a6ea992b8__21493237fe9c2c26 v1; @@ -50,14 +62,14 @@ func private %bump__MemPtr_Foo___cdd30998d577b6ea(v0.i256) { v2.*@__fe_Foo_0 = int_to_ptr v0 *@__fe_Foo_0; v3.*i256 = gep v2 0.i256 0.i256; v4.i256 = mload v3 i256; - v6.i256 = add v4 1.i256; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 1.i256; v7.*@__fe_Foo_0 = int_to_ptr v0 *@__fe_Foo_0; v8.*i256 = gep v7 0.i256 0.i256; mstore v8 v6 i256; v9.*@__fe_Foo_0 = int_to_ptr v0 *@__fe_Foo_0; v10.*i256 = gep v9 0.i256 1.i256; v11.i256 = mload v10 i256; - v13.i256 = add v11 2.i256; + v13.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v11 2.i256; v14.*@__fe_Foo_0 = int_to_ptr v0 *@__fe_Foo_0; v15.*i256 = gep v14 0.i256 1.i256; mstore v15 v13 i256; @@ -75,6 +87,19 @@ func private %memptr_t__hf71ec14ffe47fb3f_effecthandle_hfc52f915596f993a_from_ra return v0; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__Foo_h6dbce71a6ea992b8__21493237fe9c2c26(v0.i256) -> i256 { block0: return v0; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/enum_variant_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/enum_variant_contract.snap index eadb4c8bc3..2a5c760802 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/enum_variant_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/enum_variant_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/enum_variant_contract.fe --- @@ -24,94 +23,91 @@ func private %runtime__StorPtr_Evm___207f35a85ac4062e() { block0: v1.i256 = evm_calldata_load 0.i256; v3.i256 = shr 224.i256 v1; - v5.i1 = eq v3 1817627404.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v3 1817627404.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: - v9.i256 = evm_calldata_load 4.i256; - v10.*[i8; 64] = alloca [i8; 64]; - v11.i256 = ptr_to_int v10 i256; - v13.*i256 = bitcast v10 *i256; - mstore v13 1.i256 i256; - v15.i256 = add v11 32.i256; - v16.*i256 = int_to_ptr v15 *i256; - mstore v16 v9 i256; + v8.i256 = evm_calldata_load 4.i256; + v9.*[i8; 64] = alloca [i8; 64]; + v10.i256 = ptr_to_int v9 i256; + v12.*i256 = bitcast v9 *i256; + mstore v12 1.i256 i256; + v14.i256 = add v10 32.i256; + v15.*i256 = int_to_ptr v14 *i256; + mstore v15 v8 i256; jump block6; block2: - v19.i1 = eq v3 1163776883.i256; - v20.i256 = zext v19 i256; - v21.i1 = ne v20 0.i256; - br v21 block8 block9; + v18.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v3 1163776883.i256; + v19.i1 = ne v18 0.i256; + br v19 block8 block9; block3: - v23.i256 = add v11 32.i256; - v24.*i256 = int_to_ptr v23 *i256; - v25.i256 = mload v24 i256; + v21.i256 = add v10 32.i256; + v22.*i256 = int_to_ptr v21 *i256; + v23.i256 = mload v22 i256; jump block4; block4: - v27.i256 = phi (v25 block3) (0.i256 block5); - call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v27 0.i256; + v25.i256 = phi (v23 block3) (0.i256 block5); + call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v25 0.i256; evm_invalid; block5: jump block4; block6: - v29.*i256 = int_to_ptr v11 *i256; - v30.i256 = mload v29 i256; - br_table v30 block7 (1.i256 block3) (0.i256 block5); + v27.*i256 = int_to_ptr v10 *i256; + v28.i256 = mload v27 i256; + br_table v28 block7 (1.i256 block3) (0.i256 block5); block7: evm_invalid; block8: - v31.*[i8; 64] = alloca [i8; 64]; - v32.i256 = ptr_to_int v31 i256; - v33.*i256 = bitcast v31 *i256; - mstore v33 0.i256 i256; + v29.*[i8; 64] = alloca [i8; 64]; + v30.i256 = ptr_to_int v29 i256; + v31.*i256 = bitcast v29 *i256; + mstore v31 0.i256 i256; jump block13; block9: - v36.i1 = eq v3 3572425762.i256; - v37.i256 = zext v36 i256; - v38.i1 = ne v37 0.i256; - br v38 block15 block16; + v34.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v3 3572425762.i256; + v35.i1 = ne v34 0.i256; + br v35 block15 block16; block10: - v40.i256 = add v32 32.i256; - v41.*i256 = int_to_ptr v40 *i256; - v42.i256 = mload v41 i256; + v37.i256 = add v30 32.i256; + v38.*i256 = int_to_ptr v37 *i256; + v39.i256 = mload v38 i256; jump block11; block11: - v44.i256 = phi (v42 block10) (0.i256 block12); - call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v44 0.i256; + v41.i256 = phi (v39 block10) (0.i256 block12); + call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v41 0.i256; evm_invalid; block12: jump block11; block13: - v46.*i256 = int_to_ptr v32 *i256; - v47.i256 = mload v46 i256; - br_table v47 block14 (1.i256 block10) (0.i256 block12); + v43.*i256 = int_to_ptr v30 *i256; + v44.i256 = mload v43 i256; + br_table v44 block14 (1.i256 block10) (0.i256 block12); block14: evm_invalid; block15: - v48.i256 = evm_calldata_load 4.i256; - v49.*[i8; 64] = alloca [i8; 64]; - v50.i256 = ptr_to_int v49 i256; - v51.*i256 = bitcast v49 *i256; - mstore v51 1.i256 i256; - v52.i256 = add v50 32.i256; - v53.*i256 = int_to_ptr v52 *i256; - mstore v53 v48 i256; + v45.i256 = evm_calldata_load 4.i256; + v46.*[i8; 64] = alloca [i8; 64]; + v47.i256 = ptr_to_int v46 i256; + v48.*i256 = bitcast v46 *i256; + mstore v48 1.i256 i256; + v49.i256 = add v47 32.i256; + v50.*i256 = int_to_ptr v49 *i256; + mstore v50 v45 i256; jump block20; block16: @@ -121,22 +117,29 @@ func private %runtime__StorPtr_Evm___207f35a85ac4062e() { jump block18; block18: - v54.i256 = phi (1.i256 block17) (0.i256 block19); - call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v54 0.i256; + v51.i256 = phi (1.i256 block17) (0.i256 block19); + call %abi_encode_u256__Evm_hef0af3106e109414__3af54274b2985741 v51 0.i256; evm_invalid; block19: jump block18; block20: - v56.*i256 = int_to_ptr v50 *i256; - v57.i256 = mload v56 i256; - br_table v57 block21 (1.i256 block17) (0.i256 block19); + v53.*i256 = int_to_ptr v47 *i256; + v54.i256 = mload v53 i256; + br_table v54 block21 (1.i256 block17) (0.i256 block19); block21: evm_invalid; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + object @EnumContract { section init { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/erc20.snap b/crates/codegen/tests/fixtures/sonatina_ir/erc20.snap index 035367efad..16b1a6895c 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/erc20.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/erc20.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/erc20.fe --- @@ -32,10 +31,9 @@ func private %__CoolCoin_init_contract(v0.i256, v1.i256, v2.i256, v3.i256, v4.i2 block0: call %accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__577ab43c73dd3cef v3 1.i256 v1; call %accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__577ab43c73dd3cef v3 2.i256 v1; - v9.i1 = gt v0 0.i256; - v10.i256 = zext v9 i256; - v11.i1 = ne v10 0.i256; - br v11 block1 block2; + v9.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v0 0.i256; + v10.i1 = ne v9 0.i256; + br v10 block1 block2; block1: call %mint__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb v1 v0 v2 v5; @@ -187,7 +185,7 @@ func private %__CoolCoin_recv_1_3(v0.i256, v1.i256, v2.i256, v3.i256) -> i256 { v19.*@__fe_Address_0 = gep v18 0.i256 1.i256; mstore v19 v7 i256; v20.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v15; - v21.i256 = add v20 v11; + v21.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v20 v11; call %approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb v12 v7 v21 v2 v3; return 1.i256; } @@ -210,12 +208,10 @@ func private %__CoolCoin_recv_1_4(v0.i256, v1.i256, v2.i256, v3.i256) -> i256 { v19.*@__fe_Address_0 = gep v18 0.i256 1.i256; mstore v19 v7 i256; v20.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v15; - v21.i1 = lt v20 v11; - v22.i1 = is_zero v21; - v23.i256 = zext v22 i256; - call %assert v23; - v24.i256 = sub v20 v11; - call %approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb v12 v7 v24 v2 v3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge v20 v11; + call %assert v21; + v22.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v20 v11; + call %approve__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb v12 v7 v22 v2 v3; return 1.i256; } @@ -371,16 +367,23 @@ func private %accesscontrol____h4c85da5bbb505ade_grant_stor_arg0_root_stor__3__5 return; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %mint__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60766812ceb(v0.i256, v1.i256, v2.i256, v3.i256) { block0: v5.i256 = call %address_h257056268eac7027_zero; v6.i256 = call %ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2 v0 v5; call %assert v6; v7.i256 = evm_sload v2; - v8.i256 = add v7 v1; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v7 v1; evm_sstore v2 v8; v9.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0; - v10.i256 = add v9 v1; + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v9 v1; call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0 v10; v11.i256 = call %address_h257056268eac7027_zero; v13.*i8 = evm_malloc 96.i256; @@ -407,27 +410,25 @@ func private %transfer__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__409 v9.i256 = call %ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2 v1 v8; call %assert v9; v10.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0; - v11.i1 = lt v10 v2; - v12.i1 = is_zero v11; - v13.i256 = zext v12 i256; - call %assert v13; - v14.i256 = sub v10 v2; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0 v14; - v15.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1; - v16.i256 = add v15 v2; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1 v16; - v18.*i8 = evm_malloc 96.i256; - v19.i256 = ptr_to_int v18 i256; - v20.*@__fe_TransferEvent_12 = bitcast v18 *@__fe_TransferEvent_12; - v21.*@__fe_Address_0 = gep v20 0.i256 0.i256; - mstore v21 v0 i256; - v22.*@__fe_TransferEvent_12 = bitcast v18 *@__fe_TransferEvent_12; - v24.*@__fe_Address_0 = gep v22 0.i256 1.i256; - mstore v24 v1 i256; - v25.*@__fe_TransferEvent_12 = bitcast v18 *@__fe_TransferEvent_12; - v27.*i256 = gep v25 0.i256 2.i256; - mstore v27 v2 i256; - call %emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63 v4 v19; + v11.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge v10 v2; + call %assert v11; + v12.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v10 v2; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0 v12; + v13.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1; + v14.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 v2; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1 v14; + v16.*i8 = evm_malloc 96.i256; + v17.i256 = ptr_to_int v16 i256; + v18.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; + v19.*@__fe_Address_0 = gep v18 0.i256 0.i256; + mstore v19 v0 i256; + v20.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; + v22.*@__fe_Address_0 = gep v20 0.i256 1.i256; + mstore v22 v1 i256; + v23.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; + v25.*i256 = gep v23 0.i256 2.i256; + mstore v25 v2 i256; + call %emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63 v4 v17; return; } @@ -474,20 +475,18 @@ func private %spend_allowance__0_1_StorPtr_TokenStore_0__1____d3adca980e228028(v v12.*@__fe_Address_0 = gep v10 0.i256 1.i256; mstore v12 v1 i256; v13.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v7; - v14.i1 = lt v13 v2; - v15.i1 = is_zero v14; - v16.i256 = zext v15 i256; - call %assert v16; - v17.*i8 = evm_malloc 64.i256; - v18.i256 = ptr_to_int v17 i256; - v19.*@__fe_tuple_5 = bitcast v17 *@__fe_tuple_5; - v20.*@__fe_Address_0 = gep v19 0.i256 0.i256; - mstore v20 v0 i256; - v21.*@__fe_tuple_5 = bitcast v17 *@__fe_tuple_5; - v22.*@__fe_Address_0 = gep v21 0.i256 1.i256; - mstore v22 v1 i256; - v23.i256 = sub v13 v2; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v18 v23; + v14.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge v13 v2; + call %assert v14; + v15.*i8 = evm_malloc 64.i256; + v16.i256 = ptr_to_int v15 i256; + v17.*@__fe_tuple_5 = bitcast v15 *@__fe_tuple_5; + v18.*@__fe_Address_0 = gep v17 0.i256 0.i256; + mstore v18 v0 i256; + v19.*@__fe_tuple_5 = bitcast v15 *@__fe_tuple_5; + v20.*@__fe_Address_0 = gep v19 0.i256 1.i256; + mstore v20 v1 i256; + v21.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v13 v2; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v16 v21; return; } @@ -517,9 +516,8 @@ func private %accesscontrol____h4c85da5bbb505ade_require_stor_arg0_root_stor__3_ v12.*@__fe_Address_0 = gep v10 0.i256 1.i256; mstore v12 v4 i256; v13.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor___u256__Address__bool_3__5e1c6d4e3f4fb7e8 0.i256 v7; - v14.i1 = eq v13 1.i256; - v15.i256 = zext v14 i256; - call %assert v15; + v14.i256 = call %bool_h947c0c03c59c6f07_eq_he50383edd273619f_eq v13 1.i256; + call %assert v14; return; } @@ -529,31 +527,50 @@ func private %burn__0_1_StorPtr_TokenStore_0__1___Evm_hef0af3106e109414__4094b60 v6.i256 = call %ne__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2 v0 v5; call %assert v6; v7.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0; - v8.i1 = lt v7 v1; - v9.i1 = is_zero v8; - v10.i256 = zext v9 i256; - call %assert v10; - v11.i256 = sub v7 v1; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0 v11; - v12.i256 = evm_sload v2; - v13.i256 = sub v12 v1; - evm_sstore v2 v13; - v14.i256 = call %address_h257056268eac7027_zero; - v16.*i8 = evm_malloc 96.i256; - v17.i256 = ptr_to_int v16 i256; - v18.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; - v19.*@__fe_Address_0 = gep v18 0.i256 0.i256; - mstore v19 v0 i256; - v20.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; - v22.*@__fe_Address_0 = gep v20 0.i256 1.i256; - mstore v22 v14 i256; - v23.*@__fe_TransferEvent_12 = bitcast v16 *@__fe_TransferEvent_12; - v25.*i256 = gep v23 0.i256 2.i256; - mstore v25 v1 i256; - call %emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63 v3 v17; + v8.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge v7 v1; + call %assert v8; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v7 v1; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v0 v9; + v10.i256 = evm_sload v2; + v11.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v10 v1; + evm_sstore v2 v11; + v12.i256 = call %address_h257056268eac7027_zero; + v14.*i8 = evm_malloc 96.i256; + v15.i256 = ptr_to_int v14 i256; + v16.*@__fe_TransferEvent_12 = bitcast v14 *@__fe_TransferEvent_12; + v17.*@__fe_Address_0 = gep v16 0.i256 0.i256; + mstore v17 v0 i256; + v18.*@__fe_TransferEvent_12 = bitcast v14 *@__fe_TransferEvent_12; + v20.*@__fe_Address_0 = gep v18 0.i256 1.i256; + mstore v20 v12 i256; + v21.*@__fe_TransferEvent_12 = bitcast v14 *@__fe_TransferEvent_12; + v23.*i256 = gep v21 0.i256 2.i256; + mstore v23 v1 i256; + call %emit_stor_arg0_root_stor__Evm_hef0af3106e109414_TransferEvent_h1c9ba82714a4a1f0__6ee531292f5eff63 v3 v15; return; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_ge(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + func private %assert(v0.i256) { block0: v2.i1 = is_zero v0; @@ -568,6 +585,19 @@ func private %assert(v0.i256) { return; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %init_field__Evm_hef0af3106e109414_TokenStore_0__1___db7d7c067dc14cc5(v0.i256, v1.i256) -> i256 { block0: v3.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_field__TokenStore_0__1___175215aa56127bde v0 v1; @@ -619,19 +649,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -949,6 +978,13 @@ func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0 return v5; } +func private %bool_h947c0c03c59c6f07_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %soldecoder_i__ha12a03fcb5ba844b_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b(v0.i256) -> i256 { block0: v2.i256 = call %cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b v0; @@ -991,44 +1027,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; v17.*@__fe_Cursor_15 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; - v26.*@__fe_Cursor_15 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*i256 = gep v26 0.i256 1.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; - v31.*@__fe_Cursor_15 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*@__fe_MemoryBytes_10 = gep v31 0.i256 0.i256; - v34.i256 = ptr_to_int v33 i256; - v35.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v34 v29; - v37.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; - v38.*@__fe_Cursor_15 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; + v25.*@__fe_Cursor_15 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*i256 = gep v25 0.i256 1.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; + v30.*@__fe_Cursor_15 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*@__fe_MemoryBytes_10 = gep v30 0.i256 0.i256; + v33.i256 = ptr_to_int v32 i256; + v34.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v33 v28; + v36.*@__fe_SolDecoder_16 = int_to_ptr v0 *@__fe_SolDecoder_16; + v37.*@__fe_Cursor_15 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %stor_ptr__Evm_hef0af3106e109414_TokenStore_0__1___db7d7c067dc14cc5(v0.i256, v1.i256) -> i256 { @@ -1051,16 +1085,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -1099,31 +1139,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %bool_h947c0c03c59c6f07_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -1151,16 +1190,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_14 = bitcast v10 *@__fe_tuple_14; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_14 = bitcast v10 *@__fe_tuple_14; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_14 = bitcast v11 *@__fe_tuple_14; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_14 = bitcast v11 *@__fe_tuple_14; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -1211,9 +1250,8 @@ func private %storagemap_set_word_with_salt___u256__Address___c7c570db20cdd393(v func private %address_h257056268eac7027_eq_h14b330e44530c410_eq(v0.i256, v1.i256) -> i256 { block0: - v3.i1 = eq v0 v1; - v4.i256 = zext v3 i256; - return v4; + v3.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v0 v1; + return v3; } func private %u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_to_word(v0.i256) -> i256 { @@ -1294,12 +1332,11 @@ func private %storagemap_storage_slot_with_salt__Address_h257056268eac7027__5ab9 v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %storagemap_storage_slot_with_salt___Address__Address___c32d499da259c78e(v0.i256, v1.i256) -> i256 { @@ -1307,12 +1344,11 @@ func private %storagemap_storage_slot_with_salt___Address__Address___c32d499da25 v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2 v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %storagemap_get_word_with_salt___u256__Address___c7c570db20cdd393(v0.i256, v1.i256) -> i256 { @@ -1324,10 +1360,8 @@ func private %storagemap_get_word_with_salt___u256__Address___c7c570db20cdd393(v func private %bool_h947c0c03c59c6f07_wordrepr_h7483d41ac8178d88_from_word(v0.i256) -> i256 { block0: - v2.i1 = eq v0 0.i256; - v3.i1 = is_zero v2; - v4.i256 = zext v3 i256; - return v4; + v2.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v0 0.i256; + return v2; } func private %cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b(v0.i256) -> i256 { @@ -1365,10 +1399,9 @@ func private %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at( v3.*@__fe_MemoryBytes_10 = int_to_ptr v0 *@__fe_MemoryBytes_10; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i256 = add v5 v1; - v7.i256 = add v5 v1; - v8.i256 = mload v7 i256; - return v8; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 v1; + v7.i256 = mload v6 i256; + return v7; } func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__TokenStore_0__1___175215aa56127bde(v0.i256) -> i256 { @@ -1420,44 +1453,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; v17.*@__fe_Cursor_19 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; - v26.*@__fe_Cursor_19 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*@__fe_CallData_18 = gep v26 0.i256 0.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; - v31.*@__fe_Cursor_19 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*i256 = gep v31 0.i256 1.i256; - v34.i256 = mload v33 i256; - v35.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v29 v34; - v37.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; - v38.*@__fe_Cursor_19 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; + v25.*@__fe_Cursor_19 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*@__fe_CallData_18 = gep v25 0.i256 0.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; + v30.*@__fe_Cursor_19 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*i256 = gep v30 0.i256 1.i256; + v33.i256 = mload v32 i256; + v34.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v28 v33; + v36.*@__fe_SolDecoder_20 = int_to_ptr v0 *@__fe_SolDecoder_20; + v37.*@__fe_Cursor_19 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %solencoder_h1b9228b90dad6928_new() -> i256 { @@ -1476,13 +1507,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_17 = int_to_ptr v0 *@__fe_SolEncoder_17; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; @@ -1494,12 +1532,11 @@ func private %storagemap_storage_slot_with_salt___u256__Address___c7c570db20cdd3 v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u256_Address_h257056268eac7027__802280feae02d9df v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %address_h257056268eac7027_topicvalue_hc8981c1d4c24e77d_as_topic(v0.i256) -> i256 { @@ -1525,15 +1562,23 @@ func private %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__A v4.*@__fe_Address_0 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; v6.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v0 v5; - v7.*@__fe_tuple_5 = int_to_ptr v1 *@__fe_tuple_5; - v9.*@__fe_Address_0 = gep v7 0.i256 1.i256; - v10.i256 = mload v9 i256; - v11.i256 = add v0 v6; - v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v11 v10; - v13.i256 = add v6 v12; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v6; + v8.*@__fe_tuple_5 = int_to_ptr v1 *@__fe_tuple_5; + v10.*@__fe_Address_0 = gep v8 0.i256 1.i256; + v11.i256 = mload v10 i256; + v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v7 v11; + v13.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 v12; return v13; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + func private %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0.i256) -> i256 { block0: return v0; @@ -1579,12 +1624,12 @@ func private %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__u v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; v6.i256 = call %u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key v0 v5; - v7.*@__fe_tuple_11 = int_to_ptr v1 *@__fe_tuple_11; - v9.*@__fe_Address_0 = gep v7 0.i256 1.i256; - v10.i256 = mload v9 i256; - v11.i256 = add v0 v6; - v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v11 v10; - v13.i256 = add v6 v12; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v6; + v8.*@__fe_tuple_11 = int_to_ptr v1 *@__fe_tuple_11; + v10.*@__fe_Address_0 = gep v8 0.i256 1.i256; + v11.i256 = mload v10 i256; + v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v7 v11; + v13.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 v12; return v13; } diff --git a/crates/codegen/tests/fixtures/sonatina_ir/erc20_low_level.snap b/crates/codegen/tests/fixtures/sonatina_ir/erc20_low_level.snap index a2c18915a3..80ed6412fd 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/erc20_low_level.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/erc20_low_level.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/erc20_low_level.fe --- @@ -200,20 +199,19 @@ func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get_stor_arg0 func private %erc20_______h94f6fe6e679122ca_transfer_stor_arg0_root_stor__0_1_Evm_hef0af3106e109414__2bfe0780cafbc4d2(v0.i256, v1.i256, v2.i256, v3.i256, v4.i256) { block0: v6.i256 = call %erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2 v0 v1; - v7.i1 = lt v6 v3; - v8.i256 = zext v7 i256; - v9.i1 = ne v8 0.i256; - br v9 block1 block2; + v7.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v6 v3; + v8.i1 = ne v7 0.i256; + br v8 block1 block2; block1: evm_revert 0.i256 0.i256; block2: - v12.i256 = call %erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2 v0 v2; - v16.i256 = sub v6 v3; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1 v16; - v17.i256 = add v12 v3; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v2 v17; + v11.i256 = call %erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2 v0 v2; + v14.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v6 v3; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1 v14; + v16.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v11 v3; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v2 v16; return; } @@ -235,26 +233,25 @@ func private %erc20_______h94f6fe6e679122ca_transfer_from_stor_arg0_root_stor__0 block0: v7.i256 = evm_caller; v8.i256 = call %erc20_______h94f6fe6e679122ca_allowance_stor_arg0_root_stor__0_1__e4c8be10cab939c2 v0 v1 v7; - v9.i1 = lt v8 v3; - v10.i256 = zext v9 i256; - v11.i1 = ne v10 0.i256; - br v11 block1 block2; + v9.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v8 v3; + v10.i1 = ne v9 0.i256; + br v10 block1 block2; block1: evm_revert 0.i256 0.i256; block2: call %erc20_______h94f6fe6e679122ca_transfer_stor_arg0_root_stor__0_1_Evm_hef0af3106e109414__2bfe0780cafbc4d2 v0 v1 v2 v3 v5; - v18.*i8 = evm_malloc 64.i256; - v19.i256 = ptr_to_int v18 i256; - v20.*@__fe_tuple_1 = bitcast v18 *@__fe_tuple_1; - v21.*@__fe_Address_0 = gep v20 0.i256 0.i256; - mstore v21 v1 i256; - v23.*@__fe_tuple_1 = bitcast v18 *@__fe_tuple_1; - v25.*@__fe_Address_0 = gep v23 0.i256 1.i256; - mstore v25 v7 i256; - v27.i256 = sub v8 v3; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v19 v27; + v17.*i8 = evm_malloc 64.i256; + v18.i256 = ptr_to_int v17 i256; + v19.*@__fe_tuple_1 = bitcast v17 *@__fe_tuple_1; + v20.*@__fe_Address_0 = gep v19 0.i256 0.i256; + mstore v20 v1 i256; + v22.*@__fe_tuple_1 = bitcast v17 *@__fe_tuple_1; + v24.*@__fe_Address_0 = gep v22 0.i256 1.i256; + mstore v24 v7 i256; + v26.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v3; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f 0.i256 v18 v26; return; } @@ -272,10 +269,10 @@ func private %erc20_______h94f6fe6e679122ca_mint_stor_arg0_root_stor__0_1_Evm_he block2: v14.i256 = call %erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1__e4c8be10cab939c2 v0 v1; - v16.i256 = add v14 v2; + v16.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v14 v2; call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3 0.i256 v1 v16; v17.i256 = evm_sload v0; - v18.i256 = add v17 v2; + v18.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v17 v2; evm_sstore v0 v18; return; } @@ -318,6 +315,26 @@ func private %erc20_______h94f6fe6e679122ca_balance_of_stor_arg0_root_stor__0_1_ return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor__Address_h257056268eac7027_u256_0__6e989e4cb63e64c3(v0.i256, v1.i256, v2.i256) { block0: v4.i256 = call %u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_to_word v2; @@ -325,6 +342,19 @@ func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0 return; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set_stor_arg0_root_stor___Address__Address__u256_1__12414c27d5bfff1f(v0.i256, v1.i256, v2.i256) { block0: v4.i256 = call %u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_to_word v2; @@ -354,11 +384,23 @@ func private %ne_arg1_root_stor__Address_h257056268eac7027_Address_h257056268eac return v5; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %address_h257056268eac7027_eq_h14b330e44530c410_eq_stor_arg0_root_stor(v0.i256, v1.i256) -> i256 { block0: - v3.i1 = eq v0 v1; - v4.i256 = zext v3 i256; - return v4; + v3.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq_stor_arg0_root_stor v0 v1; + return v3; } func private %storagemap_storage_slot_with_salt__Address_h257056268eac7027__5ab99f7153cdba29(v0.i256, v1.i256) -> i256 { @@ -366,12 +408,11 @@ func private %storagemap_storage_slot_with_salt__Address_h257056268eac7027__5ab9 v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %storagemap_storage_slot_with_salt___Address__Address___c32d499da259c78e(v0.i256, v1.i256) -> i256 { @@ -379,12 +420,11 @@ func private %storagemap_storage_slot_with_salt___Address__Address___c32d499da25 v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__Address_h257056268eac7027_Address_h257056268eac7027__af929e62fa4c68f2 v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_to_word(v0.i256) -> i256 { @@ -407,6 +447,12 @@ func private %storagemap_set_word_with_salt___Address__Address___c32d499da259c78 } func private %address_h257056268eac7027_eq_h14b330e44530c410_eq_arg1_root_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq_arg1_root_stor v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq_stor_arg0_root_stor(v0.i256, v1.i256) -> i256 { block0: v3.i1 = eq v0 v1; v4.i256 = zext v3 i256; @@ -425,15 +471,22 @@ func private %_a__b__h47f120de72304a2d_storagekey_hf9e3d38a13ff4409_write_key__A v4.*@__fe_Address_0 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; v6.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v0 v5; - v7.*@__fe_tuple_1 = int_to_ptr v1 *@__fe_tuple_1; - v9.*@__fe_Address_0 = gep v7 0.i256 1.i256; - v10.i256 = mload v9 i256; - v11.i256 = add v0 v6; - v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v11 v10; - v13.i256 = add v6 v12; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v6; + v8.*@__fe_tuple_1 = int_to_ptr v1 *@__fe_tuple_1; + v10.*@__fe_Address_0 = gep v8 0.i256 1.i256; + v11.i256 = mload v10 i256; + v12.i256 = call %address_h257056268eac7027_storagekey_hf9e3d38a13ff4409_write_key v7 v11; + v13.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 v12; return v13; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq_arg1_root_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key(v0.i256, v1.i256) -> i256 { block0: mstore v0 v1 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/event_logging.snap b/crates/codegen/tests/fixtures/sonatina_ir/event_logging.snap index 7104ca028d..fdb24b9b24 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/event_logging.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/event_logging.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/event_logging.fe --- @@ -76,31 +75,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -117,16 +115,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %address_h257056268eac7027_topicvalue_hc8981c1d4c24e77d_as_topic(v0.i256) -> i256 { @@ -140,19 +138,52 @@ func private %evm_hef0af3106e109414_log_h22d1a10952034bae_log3(v0.i256, v1.i256, return; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; return; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: call %emit_transfer 0.i256 0.i256 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/event_logging_via_log.snap b/crates/codegen/tests/fixtures/sonatina_ir/event_logging_via_log.snap index bc85a38da7..602cef4a87 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/event_logging_via_log.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/event_logging_via_log.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/event_logging_via_log.fe --- @@ -82,31 +81,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -123,16 +121,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_2 = bitcast v10 *@__fe_tuple_2; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_2 = bitcast v11 *@__fe_tuple_2; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %address_h257056268eac7027_topicvalue_hc8981c1d4c24e77d_as_topic(v0.i256) -> i256 { @@ -146,19 +144,52 @@ func private %evm_hef0af3106e109414_log_h22d1a10952034bae_log3(v0.i256, v1.i256, return; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_3 = int_to_ptr v0 *@__fe_SolEncoder_3; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; return; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: call %emit_transfer 0.i256 0.i256 0.i256 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/for_array.snap b/crates/codegen/tests/fixtures/sonatina_ir/for_array.snap index 59e66e3c51..f003f90c5d 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/for_array.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/for_array.snap @@ -27,7 +27,7 @@ func private %for_array_sum() -> i256 { block2: v14.i256 = call %_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u64_25__540b817a073b29f5 v3 v7; - v16.i256 = add v24 v14; + v16.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v24 v14; jump block3; block3: @@ -53,6 +53,24 @@ func private %_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u return v7; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %for_array_sum; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/for_array_large.snap b/crates/codegen/tests/fixtures/sonatina_ir/for_array_large.snap index 7227305f1f..59d9cd13bb 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/for_array_large.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/for_array_large.snap @@ -27,7 +27,7 @@ func private %for_array_large_sum() -> i256 { block2: v14.i256 = call %_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u64_10__2b47acd750beacf4 v3 v7; - v16.i256 = add v24 v14; + v16.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v24 v14; jump block3; block3: @@ -53,6 +53,24 @@ func private %_t__const_n__usize__h8b63f3f6d3df6413_seq_ha637d2df505bccf2_get__u return v7; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %for_array_large_sum; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/for_range.snap b/crates/codegen/tests/fixtures/sonatina_ir/for_range.snap index c7eb59e1be..24344f4eec 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/for_range.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/for_range.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/for_range.fe --- @@ -28,7 +27,7 @@ func private %for_range_sum() -> i256 { block2: v17.i256 = call %range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_get v4 v10; - v19.i256 = add v27 v17; + v19.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v27 v17; jump block3; block3: @@ -46,36 +45,68 @@ func private %range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_le v5.i256 = mload v4 i256; v6.*i256 = int_to_ptr v0 *i256; v7.i256 = mload v6 i256; - v8.i1 = lt v5 v7; - v9.i256 = zext v8 i256; - v10.i1 = ne v9 0.i256; - br v10 block1 block2; + v8.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt v5 v7; + v9.i1 = ne v8 0.i256; + br v9 block1 block2; block1: jump block3; block2: - v12.i256 = add v0 32.i256; - v13.*i256 = int_to_ptr v12 *i256; - v14.i256 = mload v13 i256; - v15.*i256 = int_to_ptr v0 *i256; - v16.i256 = mload v15 i256; - v17.i256 = sub v14 v16; + v11.i256 = add v0 32.i256; + v12.*i256 = int_to_ptr v11 *i256; + v13.i256 = mload v12 i256; + v14.*i256 = int_to_ptr v0 *i256; + v15.i256 = mload v14 i256; + v16.i256 = call %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub v13 v15; jump block3; block3: - v18.i256 = phi (0.i256 block1) (v17 block2); - return v18; + v17.i256 = phi (0.i256 block1) (v16 block2); + return v17; } func private %range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_get(v0.i256, v1.i256) -> i256 { block0: v3.*i256 = int_to_ptr v0 *i256; v4.i256 = mload v3 i256; - v5.i256 = add v4 v1; + v5.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v4 v1; return v5; } +func private %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + +func private %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %for_range_sum; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/full_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/full_contract.snap index 3ee4b4259b..5dfb6f9f0e 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/full_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/full_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/full_contract.fe --- @@ -26,51 +25,49 @@ func private %dispatch__StorPtr_Evm___207f35a85ac4062e() { block0: v1.i256 = evm_calldata_load 0.i256; v3.i256 = shr 224.i256 v1; - v5.i1 = eq v3 151146943.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v3 151146943.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: - v9.i256 = evm_calldata_load 4.i256; - v11.i256 = evm_calldata_load 36.i256; - v13.*i8 = evm_malloc 64.i256; - v14.i256 = ptr_to_int v13 i256; - v15.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v16.*i256 = gep v15 0.i256 0.i256; - mstore v16 v9 i256; - v17.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v19.*i256 = gep v17 0.i256 1.i256; - mstore v19 v11 i256; - v20.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v21.*i256 = gep v20 0.i256 0.i256; - v22.i256 = mload v21 i256; - v23.i256 = add v22 1.i256; - v24.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v25.*i256 = gep v24 0.i256 0.i256; - mstore v25 v23 i256; - v26.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v27.*i256 = gep v26 0.i256 1.i256; - v28.i256 = mload v27 i256; - v30.i256 = add v28 2.i256; - v31.*@__fe_Point_0 = bitcast v13 *@__fe_Point_0; - v32.*i256 = gep v31 0.i256 1.i256; - mstore v32 v30 i256; - v33.i256 = call %point_hac92469562809d28_area v14; - call %abi_encode__Evm_hef0af3106e109414__3af54274b2985741 v33 0.i256; + v8.i256 = evm_calldata_load 4.i256; + v10.i256 = evm_calldata_load 36.i256; + v12.*i8 = evm_malloc 64.i256; + v13.i256 = ptr_to_int v12 i256; + v14.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v15.*i256 = gep v14 0.i256 0.i256; + mstore v15 v8 i256; + v16.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v18.*i256 = gep v16 0.i256 1.i256; + mstore v18 v10 i256; + v19.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v20.*i256 = gep v19 0.i256 0.i256; + v21.i256 = mload v20 i256; + v22.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v21 1.i256; + v23.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v24.*i256 = gep v23 0.i256 0.i256; + mstore v24 v22 i256; + v25.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v26.*i256 = gep v25 0.i256 1.i256; + v27.i256 = mload v26 i256; + v29.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v27 2.i256; + v30.*@__fe_Point_0 = bitcast v12 *@__fe_Point_0; + v31.*i256 = gep v30 0.i256 1.i256; + mstore v31 v29 i256; + v32.i256 = call %point_hac92469562809d28_area v13; + call %abi_encode__Evm_hef0af3106e109414__3af54274b2985741 v32 0.i256; evm_invalid; block2: - v36.i1 = eq v3 2066295049.i256; - v37.i256 = zext v36 i256; - v38.i1 = ne v37 0.i256; - br v38 block3 block4; + v35.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v3 2066295049.i256; + v36.i1 = ne v35 0.i256; + br v36 block3 block4; block3: - v39.i256 = evm_calldata_load 4.i256; - v41.i256 = add v39 3.i256; - v42.i256 = call %square_h97afaa872b6ea17e_area v41; - call %abi_encode__Evm_hef0af3106e109414__3af54274b2985741 v42 0.i256; + v37.i256 = evm_calldata_load 4.i256; + v39.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v37 3.i256; + v40.i256 = call %square_h97afaa872b6ea17e_area v39; + call %abi_encode__Evm_hef0af3106e109414__3af54274b2985741 v40 0.i256; evm_invalid; block4: @@ -85,16 +82,52 @@ func private %point_hac92469562809d28_area(v0.i256) -> i256 { v5.*@__fe_Point_0 = int_to_ptr v0 *@__fe_Point_0; v7.*i256 = gep v5 0.i256 1.i256; v8.i256 = mload v7 i256; - v9.i256 = mul v4 v8; + v9.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v4 v8; return v9; } func private %square_h97afaa872b6ea17e_area(v0.i256) -> i256 { block0: - v2.i256 = mul v0 v0; + v2.i256 = call %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul v0 v0; return v2; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + +func private %u256_h3271ca15373d4483_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = mul v0 v1; + v4.i1 = ne v0 0.i256; + v5.i256 = evm_udiv v3 v0; + v6.i1 = ne v5 v1; + v7.i1 = and v4 v6; + br v7 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + object @ShapeDispatcher { section init { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/function_call.snap b/crates/codegen/tests/fixtures/sonatina_ir/function_call.snap index 2ac8a53847..dccee4b7ba 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/function_call.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/function_call.snap @@ -7,7 +7,7 @@ target = "evm-ethereum-osaka" func private %add_one(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v0 1.i256; return v3; } @@ -17,6 +17,24 @@ func private %call_add_one() -> i256 { return v2; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %add_one 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/high_level_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/high_level_contract.snap index 0659748fda..b9dbc37f49 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/high_level_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/high_level_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/high_level_contract.fe --- @@ -142,19 +141,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -238,44 +236,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; v17.*@__fe_Cursor_2 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; - v26.*@__fe_Cursor_2 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*i256 = gep v26 0.i256 1.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; - v31.*@__fe_Cursor_2 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*@__fe_MemoryBytes_0 = gep v31 0.i256 0.i256; - v34.i256 = ptr_to_int v33 i256; - v35.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v34 v29; - v37.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; - v38.*@__fe_Cursor_2 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; + v25.*@__fe_Cursor_2 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*i256 = gep v25 0.i256 1.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; + v30.*@__fe_Cursor_2 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*@__fe_MemoryBytes_0 = gep v30 0.i256 0.i256; + v33.i256 = ptr_to_int v32 i256; + v34.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v33 v28; + v36.*@__fe_SolDecoder_3 = int_to_ptr v0 *@__fe_SolDecoder_3; + v37.*@__fe_Cursor_2 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %stor_ptr__Evm_hef0af3106e109414_Foo_h6dbce71a6ea992b8__c09e6c6fc5a7b23d(v0.i256, v1.i256) -> i256 { @@ -292,16 +288,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -328,31 +330,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -369,16 +370,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -422,15 +423,34 @@ func private %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_len(v0.i return v5; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: v3.*@__fe_MemoryBytes_0 = int_to_ptr v0 *@__fe_MemoryBytes_0; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i256 = add v5 v1; - v7.i256 = add v5 v1; - v8.i256 = mload v7 i256; - return v8; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 v1; + v7.i256 = mload v6 i256; + return v7; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; } func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__Foo_h6dbce71a6ea992b8__21493237fe9c2c26(v0.i256) -> i256 { @@ -438,6 +458,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -485,13 +518,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; @@ -511,44 +551,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; v17.*@__fe_Cursor_6 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; - v26.*@__fe_Cursor_6 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*@__fe_CallData_5 = gep v26 0.i256 0.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; - v31.*@__fe_Cursor_6 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*i256 = gep v31 0.i256 1.i256; - v34.i256 = mload v33 i256; - v35.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v29 v34; - v37.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; - v38.*@__fe_Cursor_6 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; + v25.*@__fe_Cursor_6 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*@__fe_CallData_5 = gep v25 0.i256 0.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; + v30.*@__fe_Cursor_6 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*i256 = gep v30 0.i256 1.i256; + v33.i256 = mload v32 i256; + v34.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v28 v33; + v36.*@__fe_SolDecoder_7 = int_to_ptr v0 *@__fe_SolDecoder_7; + v37.*@__fe_Cursor_6 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0.i256) -> i256 { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/if_else.snap b/crates/codegen/tests/fixtures/sonatina_ir/if_else.snap index b5e991d479..7374310837 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/if_else.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/if_else.snap @@ -25,10 +25,28 @@ func private %if_else(v0.i256) -> i256 { func private %helper(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v0 1.i256; return v3; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %if_else 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/init_args_with_child_dep.snap b/crates/codegen/tests/fixtures/sonatina_ir/init_args_with_child_dep.snap index 69c4366cbc..93e867b39d 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/init_args_with_child_dep.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/init_args_with_child_dep.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/init_args_with_child_dep.fe --- @@ -154,19 +153,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -180,36 +178,35 @@ func private %create_stor_arg0_root_stor__Evm_hef0af3106e109414_Child_hdfa2e9d62 block0: v4.i256 = call %__Child_init_code_len; v5.i256 = call %__Child_init_code_offset; - v7.i256 = add v4 64.i256; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 64.i256; v8.*i8 = evm_malloc v7; v9.i256 = ptr_to_int v8 i256; evm_code_copy v9 v5 v4; - v10.i256 = add v9 v4; - v12.*i8 = evm_malloc 96.i256; - v13.i256 = ptr_to_int v12 i256; - v14.*@__fe_SolEncoder_2 = bitcast v12 *@__fe_SolEncoder_2; - v15.*i256 = gep v14 0.i256 0.i256; - mstore v15 v10 i256; - v16.*@__fe_SolEncoder_2 = bitcast v12 *@__fe_SolEncoder_2; - v18.*i256 = gep v16 0.i256 1.i256; - mstore v18 v10 i256; - v19.i256 = add v10 64.i256; - v20.*@__fe_SolEncoder_2 = bitcast v12 *@__fe_SolEncoder_2; + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v9 v4; + v11.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 64.i256; + v13.*i8 = evm_malloc 96.i256; + v14.i256 = ptr_to_int v13 i256; + v15.*@__fe_SolEncoder_2 = bitcast v13 *@__fe_SolEncoder_2; + v16.*i256 = gep v15 0.i256 0.i256; + mstore v16 v10 i256; + v17.*@__fe_SolEncoder_2 = bitcast v13 *@__fe_SolEncoder_2; + v19.*i256 = gep v17 0.i256 1.i256; + mstore v19 v10 i256; + v20.*@__fe_SolEncoder_2 = bitcast v13 *@__fe_SolEncoder_2; v22.*i256 = gep v20 0.i256 2.i256; - mstore v22 v19 i256; - call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v13; + mstore v22 v11 i256; + call %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64 v2 v14; v23.i256 = call %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg0_root_stor v0 v1 v9 v7; - v24.i1 = eq v23 0.i256; - v25.i256 = zext v24 i256; - v26.i1 = ne v25 0.i256; - br v26 block1 block2; + v24.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v23 0.i256; + v25.i1 = ne v24 0.i256; + br v25 block1 block2; block1: - v27.i256 = evm_return_data_size; - v28.*i8 = evm_malloc v27; - v29.i256 = ptr_to_int v28 i256; - evm_return_data_copy v29 0.i256 v27; - evm_revert v29 v27; + v26.i256 = evm_return_data_size; + v27.*i8 = evm_malloc v26; + v28.i256 = ptr_to_int v27 i256; + evm_return_data_copy v28 0.i256 v26; + evm_revert v28 v26; block2: return v23; @@ -257,44 +254,42 @@ func private %soldecoder_i__ha12a03fcb5ba844b_abidecoder_h638151350e80a086_read_ v10.i256 = ptr_to_int v9 i256; v12.*i256 = gep v9 0.i256 1.i256; v13.i256 = mload v12 i256; - v15.i256 = add v13 32.i256; + v15.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v13 32.i256; v16.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; v17.*@__fe_Cursor_3 = gep v16 0.i256 0.i256; v18.i256 = ptr_to_int v17 i256; v19.*i256 = gep v17 0.i256 1.i256; v20.i256 = mload v19 i256; - v21.i1 = lt v15 v20; - v22.i256 = zext v21 i256; - v23.i1 = ne v22 0.i256; - br v23 block1 block3; + v21.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v15 v20; + v22.i1 = ne v21 0.i256; + br v22 block1 block3; block1: evm_revert 0.i256 0.i256; block2: - v25.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; - v26.*@__fe_Cursor_3 = gep v25 0.i256 0.i256; - v27.i256 = ptr_to_int v26 i256; - v28.*i256 = gep v26 0.i256 1.i256; - v29.i256 = mload v28 i256; - v30.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; - v31.*@__fe_Cursor_3 = gep v30 0.i256 0.i256; - v32.i256 = ptr_to_int v31 i256; - v33.*@__fe_MemoryBytes_0 = gep v31 0.i256 0.i256; - v34.i256 = ptr_to_int v33 i256; - v35.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v34 v29; - v37.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; - v38.*@__fe_Cursor_3 = gep v37 0.i256 0.i256; - v39.i256 = ptr_to_int v38 i256; - v40.*i256 = gep v38 0.i256 1.i256; - mstore v40 v15 i256; - return v35; + v24.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; + v25.*@__fe_Cursor_3 = gep v24 0.i256 0.i256; + v26.i256 = ptr_to_int v25 i256; + v27.*i256 = gep v25 0.i256 1.i256; + v28.i256 = mload v27 i256; + v29.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; + v30.*@__fe_Cursor_3 = gep v29 0.i256 0.i256; + v31.i256 = ptr_to_int v30 i256; + v32.*@__fe_MemoryBytes_0 = gep v30 0.i256 0.i256; + v33.i256 = ptr_to_int v32 i256; + v34.i256 = call %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at v33 v28; + v36.*@__fe_SolDecoder_4 = int_to_ptr v0 *@__fe_SolDecoder_4; + v37.*@__fe_Cursor_3 = gep v36 0.i256 0.i256; + v38.i256 = ptr_to_int v37 i256; + v39.*i256 = gep v37 0.i256 1.i256; + mstore v39 v15 i256; + return v34; block3: - v43.i1 = gt v15 v7; - v44.i256 = zext v43 i256; - v45.i1 = ne v44 0.i256; - br v45 block1 block2; + v42.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt v15 v7; + v43.i1 = ne v42 0.i256; + br v43 block1 block2; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256) -> i256 { @@ -305,16 +300,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -342,6 +343,19 @@ func private %__Child_init_code_offset() -> i256 { return v1; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %_t0__t1__h61373471174c18a_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_u256_u256_SolEncoder_h1b9228b90dad6928__9e0831f7c11d9f64(v0.i256, v1.i256) { block0: v3.*@__fe_tuple_1 = int_to_ptr v0 *@__fe_tuple_1; @@ -361,6 +375,13 @@ func private %evm_hef0af3106e109414_create_h3f3c4b410ec53b45_create_raw_stor_arg return v5; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %cursor_i__h140a998c67d6d59c_new__MemoryBytes_h1e381015a9b0111b__59e0d528d54cca1b(v0.i256) -> i256 { block0: v3.*i8 = evm_malloc 96.i256; @@ -396,10 +417,29 @@ func private %memorybytes_h1e381015a9b0111b_byteinput_hc4c2cb44299530ae_word_at( v3.*@__fe_MemoryBytes_0 = int_to_ptr v0 *@__fe_MemoryBytes_0; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i256 = add v5 v1; - v7.i256 = add v5 v1; - v8.i256 = mload v7 i256; - return v8; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 v1; + v7.i256 = mload v6 i256; + return v7; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; } func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { @@ -484,7 +524,7 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_wo v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_2 = int_to_ptr v0 *@__fe_SolEncoder_2; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/literal_add.snap b/crates/codegen/tests/fixtures/sonatina_ir/literal_add.snap index 7c3805e357..fc0e07184a 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/literal_add.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/literal_add.snap @@ -13,10 +13,28 @@ func private %main() -> i256 { func private %add(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v0 v1; return v3; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %main; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/literal_sub.snap b/crates/codegen/tests/fixtures/sonatina_ir/literal_sub.snap index 28eb11064c..f6d480f1e9 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/literal_sub.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/literal_sub.snap @@ -7,10 +7,28 @@ target = "evm-ethereum-osaka" func private %literal_sub() -> i256 { block0: - v3.i256 = sub 1.i256 2.i256; + v3.i256 = call %u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub 1.i256 2.i256; return v3; } +func private %u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = sub v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = gt v7 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %literal_sub; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/local_bindings.snap b/crates/codegen/tests/fixtures/sonatina_ir/local_bindings.snap index 193d6dbeea..7ba34b0c3c 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/local_bindings.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/local_bindings.snap @@ -7,10 +7,28 @@ target = "evm-ethereum-osaka" func private %local_bindings() -> i256 { block0: - v3.i256 = add 1.i256 2.i256; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add 1.i256 2.i256; return 3.i256; } +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %local_bindings; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/match_mixed_return.snap b/crates/codegen/tests/fixtures/sonatina_ir/match_mixed_return.snap index 4edbe08bbc..04c9d5e7c7 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/match_mixed_return.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/match_mixed_return.snap @@ -16,7 +16,7 @@ func private %f(v0.i256) -> i256 { jump block3; block3: - v4.i256 = add 1.i256 1.i256; + v4.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add 1.i256 1.i256; return v4; block4: @@ -28,6 +28,19 @@ func private %f(v0.i256) -> i256 { evm_invalid; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %f 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/match_struct.snap b/crates/codegen/tests/fixtures/sonatina_ir/match_struct.snap index df003770db..fe89a2a6c6 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/match_struct.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/match_struct.snap @@ -45,7 +45,7 @@ func private %match_struct_fields(v0.i256) -> i256 { v24.i256 = mload v23 i256; v25.i8 = trunc v24 i8; v26.i256 = zext v25 i256; - v27.i256 = add v26 v21; + v27.i256 = call %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add v26 v21; jump block2; block6: @@ -107,6 +107,24 @@ func private %match_struct_wildcard(v0.i256) -> i256 { br_table v17 block4 (0.i256 block3); } +func private %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i8 = trunc v0 i8; + v4.i8 = trunc v1 i8; + v5.i8 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %match_struct_fields 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/match_tuple_binding.snap b/crates/codegen/tests/fixtures/sonatina_ir/match_tuple_binding.snap index dcfad61e13..1119ccdfb1 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/match_tuple_binding.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/match_tuple_binding.snap @@ -43,7 +43,7 @@ func private %match_tuple_extract(v0.i256) -> i256 { v25.i256 = mload v24 i256; v26.i8 = trunc v25 i8; v27.i256 = zext v26 i256; - v28.i256 = add v22 v27; + v28.i256 = call %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add v22 v27; jump block2; block5: @@ -90,7 +90,7 @@ func private %match_nested_extract(v0.i256) -> i256 { v19.i256 = mload v18 i256; v20.i8 = trunc v19 i8; v21.i256 = zext v20 i256; - v22.i256 = add v21 v16; + v22.i256 = call %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add v21 v16; jump block2; block4: @@ -104,7 +104,7 @@ func private %match_nested_extract(v0.i256) -> i256 { v31.i256 = mload v30 i256; v32.i8 = trunc v31 i8; v33.i256 = zext v32 i256; - v34.i256 = add v28 v33; + v34.i256 = call %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add v28 v33; jump block2; block5: @@ -140,6 +140,24 @@ func private %match_nested_extract(v0.i256) -> i256 { br_table v58 block4 (0.i256 block3); } +func private %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i8 = trunc v0 i8; + v4.i8 = trunc v1 i8; + v5.i8 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %match_tuple_extract 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/math_ops.snap b/crates/codegen/tests/fixtures/sonatina_ir/math_ops.snap index 4ba86ff2f7..16d0ea9068 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/math_ops.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/math_ops.snap @@ -10,10 +10,33 @@ func private %math_ops() -> i256 { v3.i256 = sub 10.i256 3.i256; v5.i256 = mul v3 2.i256; v7.i256 = evm_udiv v5 7.i256; - v8.i256 = evm_umod v7 3.i256; + v8.i256 = call %u64_haee7f05a097ffa16_rem_h890eb23a7e6cfef7_rem v7 3.i256; return v8; } +func private %u64_haee7f05a097ffa16_rem_h890eb23a7e6cfef7_rem(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v1 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v7.i256 = evm_umod v0 v1; + return v7; +} + +func private %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = eq v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %math_ops; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/momo.snap b/crates/codegen/tests/fixtures/sonatina_ir/momo.snap index a364d358f9..63c4e4f168 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/momo.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/momo.snap @@ -19,10 +19,28 @@ func private %read_x(v0.i256) -> i256 { v10.i256 = mload v9 i256; v11.i8 = trunc v10 i8; v12.i256 = zext v11 i256; - v13.i256 = add v6 v12; + v13.i256 = call %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add v6 v12; return v13; } +func private %u8_hbc9d6eeaea22ffb5_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i8 = trunc v0 i8; + v4.i8 = trunc v1 i8; + v5.i8 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %read_x 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/name_collisions.snap b/crates/codegen/tests/fixtures/sonatina_ir/name_collisions.snap index 6e473365d6..4079eeb9a8 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/name_collisions.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/name_collisions.snap @@ -19,7 +19,7 @@ func private %test_module_qualifier_flatten_collision() -> i256 { block0: v1.i256 = call %a_b_h12fd23afeb13a092_flattened_fn; v2.i256 = call %a_b_h948d5ab23860c017_flattened_fn; - v3.i256 = add v1 v2; + v3.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v1 v2; return v3; } @@ -41,14 +41,14 @@ func private %test_trait_method_collision() -> i256 { block0: v2.i256 = call %multitraitimpl_h60cc862fc809464_trait_h79853acec5b2b3ad_same_method 100.i256; v3.i256 = call %multitraitimpl_h60cc862fc809464_trait_ha6da5e54b37dd39c_same_method 100.i256; - v4.i256 = add v2 v3; + v4.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v2 v3; return v4; } func private %param_local_collision(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; - v5.i256 = add v3 2.i256; + v3.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v0 1.i256; + v5.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v3 2.i256; return v5; } @@ -71,7 +71,7 @@ func private %test_cast_shim_collision() -> i256 { func private %ret_param_collision(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; + v3.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v0 1.i256; return v3; } @@ -107,28 +107,46 @@ func private %main() -> i256 { func private %widget_h8588afca9d68e578_process(v0.i256) -> i256 { block0: - v3.i256 = mul v0 2.i256; + v3.i256 = call %u32_h20aa0c10687491ad_mul_h290dcc921ed80777_mul v0 2.i256; return v3; } func private %widget_h6847c0e3e0e4aa1e_process(v0.i256) -> i256 { block0: - v3.i256 = mul v0 3.i256; + v3.i256 = call %u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul v0 3.i256; return v3; } func private %multitraitimpl_h60cc862fc809464_trait_h79853acec5b2b3ad_same_method(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; + v3.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v0 1.i256; return v3; } func private %multitraitimpl_h60cc862fc809464_trait_ha6da5e54b37dd39c_same_method(v0.i256) -> i256 { block0: - v3.i256 = add v0 2.i256; + v3.i256 = call %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add v0 2.i256; return v3; } +func private %u32_h20aa0c10687491ad_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i32 = trunc v0 i32; + v4.i32 = trunc v1 i32; + v5.i32 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %generic_fn__S_h730d9dc564aaaf27__8d32801e7ec9d42b(v0.i256) -> i256 { block0: return v0; @@ -139,6 +157,48 @@ func private %generic_fn__S_h2db58d011b97b333__42a13489a1ec39e8(v0.i256) -> i256 return v0; } +func private %u32_h20aa0c10687491ad_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i32 = trunc v0 i32; + v4.i32 = trunc v1 i32; + v5.i32 = mul v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = ne v6 0.i256; + v10.i256 = evm_udiv v8 v6; + v11.i1 = ne v10 v7; + v12.i1 = and v9 v11; + br v12 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + +func private %u64_haee7f05a097ffa16_mul_h290dcc921ed80777_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = mul v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = ne v6 0.i256; + v10.i256 = evm_udiv v8 v6; + v11.i1 = ne v10 v7; + v12.i1 = and v9 v11; + br v12 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v0.i256 = call %a_b_h12fd23afeb13a092_flattened_fn; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/newtype_field_mut_method_call.snap b/crates/codegen/tests/fixtures/sonatina_ir/newtype_field_mut_method_call.snap index 7686e42b27..08b0363383 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/newtype_field_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/newtype_field_mut_method_call.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/newtype_field_mut_method_call.fe --- @@ -53,7 +52,7 @@ func private %counter_h872958864d1ad471_bump(v0.i256) { v2.*@__fe_Counter_0 = int_to_ptr v0 *@__fe_Counter_0; v3.*i256 = gep v2 0.i256 0.i256; v4.i256 = mload v3 i256; - v6.i256 = add v4 1.i256; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 1.i256; v7.*@__fe_Counter_0 = int_to_ptr v0 *@__fe_Counter_0; v8.*i256 = gep v7 0.i256 0.i256; mstore v8 v6 i256; @@ -65,13 +64,26 @@ func private %wrapcounter_hbcbd3a74a267488b_bump(v0.i256) { v2.*@__fe_Counter_0 = int_to_ptr v0 *@__fe_Counter_0; v3.*i256 = gep v2 0.i256 0.i256; v4.i256 = mload v3 i256; - v6.i256 = add v4 1.i256; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 1.i256; v7.*@__fe_Counter_0 = int_to_ptr v0 *@__fe_Counter_0; v8.*i256 = gep v7 0.i256 0.i256; mstore v8 v6 i256; return; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %newtype_field_mut_method_call 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_byplace_effect_arg.snap b/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_byplace_effect_arg.snap index 60a737439d..1b7b92de9e 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_byplace_effect_arg.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_byplace_effect_arg.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/newtype_storage_byplace_effect_arg.fe --- @@ -18,7 +17,7 @@ type @__fe_SolDecoder_7 = {@__fe_Cursor_6, i256}; func private %bump__StorPtr_Wrap___5036bb3e02939b91(v0.i256) { block0: v2.i256 = evm_sload v0; - v4.i256 = add v2 1.i256; + v4.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v2 1.i256; evm_sstore v0 v4; return; } @@ -32,7 +31,7 @@ func private %__NewtypeByPlaceEffectArg_recv_0_0(v0.i256, v1.i256) -> i256 { block0: call %bump__StorPtr_Wrap___5036bb3e02939b91 v0; v3.i256 = evm_sload v1; - v5.i256 = add v3 1.i256; + v5.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v3 1.i256; evm_sstore v1 v5; v6.i256 = evm_sload v1; return v6; @@ -96,6 +95,19 @@ func private %__NewtypeByPlaceEffectArg_runtime() { evm_invalid; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %init_field__Evm_hef0af3106e109414_u256__3b1b0af5b20737f9(v0.i256, v1.i256) -> i256 { block0: v3.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_field__u256__3271ca15373d4483 v0 v1; @@ -135,19 +147,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -227,16 +238,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -263,31 +280,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -304,16 +320,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -348,6 +364,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -395,13 +424,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_field_mut_method_call.snap b/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_field_mut_method_call.snap index 7a3374a4f9..f10f90c3e1 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_field_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/newtype_storage_field_mut_method_call.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/newtype_storage_field_mut_method_call.fe --- @@ -19,7 +18,7 @@ func private %wrap_haf9e70905fcbd513_bump(v0.i256) { block0: v2.*i256 = int_to_ptr v0 *i256; v3.i256 = mload v2 i256; - v5.i256 = add v3 1.i256; + v5.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v3 1.i256; v6.*i256 = int_to_ptr v0 *i256; mstore v6 v5 i256; return; @@ -96,10 +95,23 @@ func private %__NewtypeStorageFieldMutMethodCall_runtime() { evm_invalid; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %wrap_haf9e70905fcbd513_bump_stor_arg0_root_stor(v0.i256) { block0: v2.i256 = evm_sload v0; - v4.i256 = add v2 1.i256; + v4.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v2 1.i256; evm_sstore v0 v4; return; } @@ -143,19 +155,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -235,16 +246,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -271,31 +288,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %u256_h3271ca15373d4483_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -312,16 +328,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -356,6 +372,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -403,13 +432,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/newtype_word_mut_method_call.snap b/crates/codegen/tests/fixtures/sonatina_ir/newtype_word_mut_method_call.snap index d40bb85930..3983798b32 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/newtype_word_mut_method_call.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/newtype_word_mut_method_call.snap @@ -13,7 +13,20 @@ func private %newtype_word_mut_method_call(v0.i256) -> i256 { func private %wrap_haf9e70905fcbd513_bump(v0.i256) -> i256 { block0: - v3.i256 = add v0 1.i256; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 1.i256; + return v3; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: return v3; } diff --git a/crates/codegen/tests/fixtures/sonatina_ir/range_bounds.snap b/crates/codegen/tests/fixtures/sonatina_ir/range_bounds.snap index d39eeb0d3e..35b046f97a 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/range_bounds.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/range_bounds.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/range_bounds.fe --- @@ -21,7 +20,7 @@ func private %sum_const() -> i256 { block2: v8.i256 = call %range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c 0.i256 v2; - v10.i256 = add v16 v8; + v10.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v16 v8; jump block3; block3: @@ -51,7 +50,7 @@ func private %sum_dynamic_end(v0.i256) -> i256 { block2: v14.i256 = call %range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c v4 v7; - v16.i256 = add v24 v14; + v16.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v24 v14; jump block3; block3: @@ -81,7 +80,7 @@ func private %sum_dynamic_start(v0.i256) -> i256 { block2: v14.i256 = call %range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e v4 v7; - v16.i256 = add v24 v14; + v16.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v24 v14; jump block3; block3: @@ -114,7 +113,7 @@ func private %sum_dynamic(v0.i256, v1.i256) -> i256 { block2: v18.i256 = call %range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e v5 v11; - v20.i256 = add v28 v18; + v20.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v28 v18; jump block3; block3: @@ -127,26 +126,38 @@ func private %sum_dynamic(v0.i256, v1.i256) -> i256 { func private %range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_len__0_4__f9605efabd18106c(v0.i256) -> i256 { block0: - v3.i1 = lt 4.i256 0.i256; - v4.i256 = zext v3 i256; - v5.i1 = ne v4 0.i256; - br v5 block1 block2; + v3.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt 4.i256 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block2; block1: jump block3; block2: - v6.i256 = sub 4.i256 0.i256; + v5.i256 = call %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub 4.i256 0.i256; jump block3; block3: - v7.i256 = phi (0.i256 block1) (v6 block2); - return v7; + v6.i256 = phi (0.i256 block1) (v5 block2); + return v6; } func private %range_known_const_s__usize___known_const_e__usize___hc7c7abc3858dd85e_seq_ha637d2df505bccf2_get__0_4__f9605efabd18106c(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add 0.i256 v1; + v3.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add 0.i256 v1; + return v3; +} + +func private %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: return v3; } @@ -154,53 +165,51 @@ func private %range_known_const_s__usize___unknown__h4e84f6b6b8307914_seq_ha637d block0: v2.*i256 = int_to_ptr v0 *i256; v3.i256 = mload v2 i256; - v4.i1 = lt v3 0.i256; - v5.i256 = zext v4 i256; - v6.i1 = ne v5 0.i256; - br v6 block1 block2; + v4.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt v3 0.i256; + v5.i1 = ne v4 0.i256; + br v5 block1 block2; block1: jump block3; block2: - v8.*i256 = int_to_ptr v0 *i256; - v9.i256 = mload v8 i256; - v10.i256 = sub v9 0.i256; + v7.*i256 = int_to_ptr v0 *i256; + v8.i256 = mload v7 i256; + v9.i256 = call %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub v8 0.i256; jump block3; block3: - v11.i256 = phi (0.i256 block1) (v10 block2); - return v11; + v10.i256 = phi (0.i256 block1) (v9 block2); + return v10; } func private %range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_len__4__f248ae0e02044d7e(v0.i256) -> i256 { block0: v2.*i256 = int_to_ptr v0 *i256; v3.i256 = mload v2 i256; - v5.i1 = lt 4.i256 v3; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt 4.i256 v3; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: jump block3; block2: - v9.*i256 = int_to_ptr v0 *i256; - v10.i256 = mload v9 i256; - v11.i256 = sub 4.i256 v10; + v8.*i256 = int_to_ptr v0 *i256; + v9.i256 = mload v8 i256; + v10.i256 = call %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub 4.i256 v9; jump block3; block3: - v12.i256 = phi (0.i256 block1) (v11 block2); - return v12; + v11.i256 = phi (0.i256 block1) (v10 block2); + return v11; } func private %range_unknown__known_const_e__usize___h7984c64777ae465_seq_ha637d2df505bccf2_get__4__f248ae0e02044d7e(v0.i256, v1.i256) -> i256 { block0: v3.*i256 = int_to_ptr v0 *i256; v4.i256 = mload v3 i256; - v5.i256 = add v4 v1; + v5.i256 = call %usize_ha12462c6d36e68b0_add_h4cebc227a0cfd3c0_add v4 v1; return v5; } @@ -211,26 +220,45 @@ func private %range_unknown__unknown__h1dfb0ca64ed7bf96_seq_ha637d2df505bccf2_le v5.i256 = mload v4 i256; v6.*i256 = int_to_ptr v0 *i256; v7.i256 = mload v6 i256; - v8.i1 = lt v5 v7; - v9.i256 = zext v8 i256; - v10.i1 = ne v9 0.i256; - br v10 block1 block2; + v8.i256 = call %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt v5 v7; + v9.i1 = ne v8 0.i256; + br v9 block1 block2; block1: jump block3; block2: - v12.i256 = add v0 32.i256; - v13.*i256 = int_to_ptr v12 *i256; - v14.i256 = mload v13 i256; - v15.*i256 = int_to_ptr v0 *i256; - v16.i256 = mload v15 i256; - v17.i256 = sub v14 v16; + v11.i256 = add v0 32.i256; + v12.*i256 = int_to_ptr v11 *i256; + v13.i256 = mload v12 i256; + v14.*i256 = int_to_ptr v0 *i256; + v15.i256 = mload v14 i256; + v16.i256 = call %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub v13 v15; jump block3; block3: - v18.i256 = phi (0.i256 block1) (v17 block2); - return v18; + v17.i256 = phi (0.i256 block1) (v16 block2); + return v17; +} + +func private %usize_ha12462c6d36e68b0_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %usize_ha12462c6d36e68b0_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; } func private %__fe_sonatina_entry() { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/ret.snap b/crates/codegen/tests/fixtures/sonatina_ir/ret.snap index cb9ab0d944..c1ee7c2c3c 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/ret.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/ret.snap @@ -14,27 +14,79 @@ func private %retfoo(v0.i256, v1.i256) -> i256 { return 0.i256; block2: - v6.i1 = lt v1 5.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block3 block4; + v6.i256 = call %u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt v1 5.i256; + v7.i1 = ne v6 0.i256; + br v7 block3 block4; block3: return 1.i256; block4: - v11.i256 = sub v1 1.i256; - v13.i1 = eq v11 42.i256; - v14.i256 = zext v13 i256; - v15.i1 = ne v14 0.i256; - br v15 block5 block6; + v10.i256 = call %u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub v1 1.i256; + v12.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v10 42.i256; + v13.i1 = ne v12 0.i256; + br v13 block5 block6; block5: return 2.i256; block6: - v18.i256 = add v11 1.i256; - return v18; + v16.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v10 1.i256; + return v16; +} + +func private %u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = lt v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + +func private %u64_haee7f05a097ffa16_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = sub v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = gt v7 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + +func private %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = eq v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; } func private %__fe_sonatina_entry() { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/storage.snap b/crates/codegen/tests/fixtures/sonatina_ir/storage.snap index 76cd2d628c..74066c11a2 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/storage.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/storage.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/storage.fe --- @@ -141,10 +140,10 @@ func private %total_supply__StorPtr_TotalSupply___2e654c25952f42f9(v0.i256) -> i func private %credit_alice__StorPtr_CoinStore__StorPtr_TotalSupply___c407f5b00af9ba78(v0.i256, v1.i256, v2.i256) -> i256 { block0: v4.i256 = evm_sload v1; - v5.i256 = add v4 v0; + v5.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v4 v0; evm_sstore v1 v5; v6.i256 = evm_sload v2; - v7.i256 = add v6 v0; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v6 v0; evm_sstore v2 v7; v8.i256 = evm_sload v1; return v8; @@ -154,11 +153,11 @@ func private %credit_bob__StorPtr_CoinStore__StorPtr_TotalSupply___c407f5b00af9b block0: v5.i256 = add v1 1.i256; v6.i256 = evm_sload v5; - v7.i256 = add v6 v0; + v7.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v6 v0; v8.i256 = add v1 1.i256; evm_sstore v8 v7; v9.i256 = evm_sload v2; - v10.i256 = add v9 v0; + v10.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v9 v0; evm_sstore v2 v10; v11.i256 = add v1 1.i256; v12.i256 = evm_sload v11; @@ -168,64 +167,62 @@ func private %credit_bob__StorPtr_CoinStore__StorPtr_TotalSupply___c407f5b00af9b func private %transfer_from_alice__StorPtr_CoinStore___ba1c0d0726e89ba2(v0.i256, v1.i256) -> i256 { block0: v3.i256 = evm_sload v1; - v4.i1 = lt v3 v0; - v5.i256 = zext v4 i256; - v6.i1 = ne v5 0.i256; - br v6 block1 block2; + v4.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor v3 v0; + v5.i1 = ne v4 0.i256; + br v5 block1 block2; block1: - v8.*i8 = evm_malloc 32.i256; - v9.i256 = ptr_to_int v8 i256; - v11.*i256 = bitcast v8 *i256; - mstore v11 1.i256 i256; - return v9; + v7.*i8 = evm_malloc 32.i256; + v8.i256 = ptr_to_int v7 i256; + v10.*i256 = bitcast v7 *i256; + mstore v10 1.i256 i256; + return v8; block2: - v13.i256 = evm_sload v1; - v15.i256 = sub v13 v0; - evm_sstore v1 v15; - v16.i256 = add v1 1.i256; - v17.i256 = evm_sload v16; - v18.i256 = add v17 v0; - v19.i256 = add v1 1.i256; - evm_sstore v19 v18; - v20.*i8 = evm_malloc 32.i256; - v21.i256 = ptr_to_int v20 i256; - v22.*i256 = bitcast v20 *i256; - mstore v22 0.i256 i256; - return v21; + v12.i256 = evm_sload v1; + v14.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor v12 v0; + evm_sstore v1 v14; + v15.i256 = add v1 1.i256; + v16.i256 = evm_sload v15; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v16 v0; + v18.i256 = add v1 1.i256; + evm_sstore v18 v17; + v19.*i8 = evm_malloc 32.i256; + v20.i256 = ptr_to_int v19 i256; + v21.*i256 = bitcast v19 *i256; + mstore v21 0.i256 i256; + return v20; } func private %transfer_from_bob__StorPtr_CoinStore___ba1c0d0726e89ba2(v0.i256, v1.i256) -> i256 { block0: v4.i256 = add v1 1.i256; v5.i256 = evm_sload v4; - v6.i1 = lt v5 v0; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor v5 v0; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc 32.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*i256 = bitcast v10 *i256; - mstore v12 1.i256 i256; - return v11; + v9.*i8 = evm_malloc 32.i256; + v10.i256 = ptr_to_int v9 i256; + v11.*i256 = bitcast v9 *i256; + mstore v11 1.i256 i256; + return v10; block2: - v14.i256 = add v1 1.i256; - v15.i256 = evm_sload v14; - v17.i256 = sub v15 v0; - v18.i256 = add v1 1.i256; - evm_sstore v18 v17; - v19.i256 = evm_sload v1; - v20.i256 = add v19 v0; - evm_sstore v1 v20; - v21.*i8 = evm_malloc 32.i256; - v22.i256 = ptr_to_int v21 i256; - v23.*i256 = bitcast v21 *i256; - mstore v23 0.i256 i256; - return v22; + v13.i256 = add v1 1.i256; + v14.i256 = evm_sload v13; + v16.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor v14 v0; + v17.i256 = add v1 1.i256; + evm_sstore v17 v16; + v18.i256 = evm_sload v1; + v19.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor v18 v0; + evm_sstore v1 v19; + v20.*i8 = evm_malloc 32.i256; + v21.i256 = ptr_to_int v20 i256; + v22.*i256 = bitcast v20 *i256; + mstore v22 0.i256 i256; + return v21; } func private %init__StorPtr_Evm___207f35a85ac4062e() { @@ -305,6 +302,39 @@ func private %runtime__StorPtr_Evm___207f35a85ac4062e() { br_table v6 block13 (2877082652.i256 block1) (1818602213.i256 block6) (217554442.i256 block7) (960555502.i256 block12); } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %stor_ptr_stor__Evm_hef0af3106e109414_CoinStore_hd26a92ca525e0e79__b6feb5585dda62f1(v0.i256, v1.i256) -> i256 { block0: v3.i256 = call %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_raw__CoinStore_hd26a92ca525e0e79__a9c0a742c4f0cede v1; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/storage_map_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/storage_map_contract.snap index d458f4a448..aeea1efaab 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/storage_map_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/storage_map_contract.snap @@ -93,20 +93,19 @@ func private %set_balance__0_MemPtr_StorageMap_u256__u256__0____a41b2ecb073da43d func private %transfer__0_MemPtr_StorageMap_u256__u256__0____a41b2ecb073da43d(v0.i256, v1.i256, v2.i256, v3.i256) -> i256 { block0: v5.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971 v3 v0; - v6.i1 = lt v5 v2; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v5 v2; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: return 1.i256; block2: - v12.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971 v3 v1; - v16.i256 = sub v5 v2; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971 v3 v0 v16; - v17.i256 = add v12 v2; - call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971 v3 v1 v17; + v11.i256 = call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971 v3 v1; + v14.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v5 v2; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971 v3 v0 v14; + v16.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v11 v2; + call %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971 v3 v1 v16; return 0.i256; } @@ -136,6 +135,39 @@ func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u25 return; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_1__3c02c0f2b86be0bb(v0.i256, v1.i256) -> i256 { block0: v4.i256 = call %storagemap_get_word_with_salt__u256__3271ca15373d4483 v1 1.i256; @@ -179,12 +211,11 @@ func private %storagemap_storage_slot_with_salt__u256__3271ca15373d4483(v0.i256, v3.*i8 = evm_malloc 0.i256; v4.i256 = ptr_to_int v3 i256; v5.i256 = call %u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key v4 v0; - v6.i256 = add v4 v5; + v6.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v4 v5; mstore v6 v1 i256; - v8.i256 = add v5 32.i256; - v9.i256 = add v5 32.i256; - v10.i256 = evm_keccak256 v4 v9; - return v10; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v5 32.i256; + v9.i256 = evm_keccak256 v4 v8; + return v9; } func private %u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key(v0.i256, v1.i256) -> i256 { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/tstor_ptr_contract.snap b/crates/codegen/tests/fixtures/sonatina_ir/tstor_ptr_contract.snap index 7a8989933e..5b43b0e6ef 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/tstor_ptr_contract.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/tstor_ptr_contract.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/sonatina_ir.rs -assertion_line: 64 expression: output input_file: crates/codegen/tests/fixtures/tstor_ptr_contract.fe --- @@ -26,7 +25,7 @@ func private %__GuardContract_init_contract(v0.i256) { func private %__GuardContract_recv_0_0(v0.i256, v1.i256) -> i256 { block0: v3.i256 = evm_sload v1; - v5.i256 = add v3 1.i256; + v5.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v3 1.i256; evm_sstore v1 v5; v6.i256 = evm_tload v0; v7.i1 = ne v6 0.i256; @@ -97,6 +96,19 @@ func private %__GuardContract_runtime() { evm_invalid; } +func private %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %init_field__Evm_hef0af3106e109414_u256__3b1b0af5b20737f9(v0.i256, v1.i256) -> i256 { block0: v3.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_field__u256__3271ca15373d4483 v0 v1; @@ -129,19 +141,18 @@ func private %runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e block0: v2.i256 = call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input v0; v3.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len v2; - v5.i1 = lt v3 4.i256; - v6.i256 = zext v5 i256; - v7.i1 = ne v6 0.i256; - br v7 block1 block2; + v5.i256 = call %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt v3 4.i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; block1: call %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort v0; evm_invalid; block2: - v10.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; - v11.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v10; - return v11; + v9.i256 = call %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at v2 0.i256; + v10.i256 = call %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix v9; + return v10; } func private %runtime_decoder__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2(v0.i256) -> i256 { @@ -215,16 +226,22 @@ func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input(v0.i256 func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0.i256) -> i256 { block0: v2.i256 = evm_calldata_size; - v3.i256 = sub v2 v0; + v3.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v2 v0; return v3; } +func private %u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = lt v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0.i256, v1.i256) -> i256 { block0: - v3.i256 = add v0 v1; - v4.i256 = add v0 v1; - v5.i256 = evm_calldata_load v4; - return v5; + v3.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v0 v1; + v4.i256 = evm_calldata_load v3; + return v4; } func private %sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v0.i256) -> i256 { @@ -251,31 +268,30 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_ v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v4.*i256 = gep v3 0.i256 0.i256; v5.i256 = mload v4 i256; - v6.i1 = eq v5 0.i256; - v7.i256 = zext v6 i256; - v8.i1 = ne v7 0.i256; - br v8 block1 block2; + v6.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v5 0.i256; + v7.i1 = ne v6 0.i256; + br v7 block1 block2; block1: - v10.*i8 = evm_malloc v1; - v11.i256 = ptr_to_int v10 i256; - v13.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v14.*i256 = gep v13 0.i256 0.i256; - mstore v14 v11 i256; - v15.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v11 i256; - v18.i256 = add v11 v1; - v19.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v21.*i256 = gep v19 0.i256 2.i256; - mstore v21 v18 i256; + v9.*i8 = evm_malloc v1; + v10.i256 = ptr_to_int v9 i256; + v12.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v13.*i256 = gep v12 0.i256 0.i256; + mstore v13 v10 i256; + v14.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v16.*i256 = gep v14 0.i256 1.i256; + mstore v16 v10 i256; + v17.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v10 v1; + v18.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v20.*i256 = gep v18 0.i256 2.i256; + mstore v20 v17 i256; jump block2; block2: - v23.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; - v24.*i256 = gep v23 0.i256 0.i256; - v25.i256 = mload v24 i256; - return v25; + v22.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; + v23.*i256 = gep v22 0.i256 0.i256; + v24.i256 = mload v23 i256; + return v24; } func private %bool_h947c0c03c59c6f07_encode_hab7243eccf2714fb_encode__Sol_hfd482bb803ad8c5f_SolEncoder_h1b9228b90dad6928__1a070c3866d16383(v0.i256, v1.i256) { @@ -303,16 +319,16 @@ func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish(v v5.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v7.*i256 = gep v5 0.i256 2.i256; v8.i256 = mload v7 i256; - v10.*i8 = evm_malloc 64.i256; - v11.i256 = ptr_to_int v10 i256; - v12.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; - v13.*i256 = gep v12 0.i256 0.i256; - mstore v13 v4 i256; - v14.i256 = sub v8 v4; - v15.*@__fe_tuple_1 = bitcast v10 *@__fe_tuple_1; + v9.i256 = call %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub v8 v4; + v11.*i8 = evm_malloc 64.i256; + v12.i256 = ptr_to_int v11 i256; + v13.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; + v14.*i256 = gep v13 0.i256 0.i256; + mstore v14 v4 i256; + v15.*@__fe_tuple_1 = bitcast v11 *@__fe_tuple_1; v17.*i256 = gep v15 0.i256 1.i256; - mstore v17 v14 i256; - return v11; + mstore v17 v9 i256; + return v12; } func private %evm_hef0af3106e109414_contracthost_h57111e7eb283a125_return_bytes(v0.i256, v1.i256, v2.i256) { @@ -347,6 +363,19 @@ func private %storptr_t__hc45dea9607fd5340_effecthandle_hfc52f915596f993a_from_r return v0; } +func private %u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v4.i1 = gt v1 v0; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v3; +} + func private %s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35(v0.i256) -> i256 { block0: v2.i256 = call %u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word v0; @@ -394,13 +423,20 @@ func private %solencoder_h1b9228b90dad6928_new() -> i256 { return v3; } +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + func private %solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word(v0.i256, v1.i256) { block0: v3.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v5.*i256 = gep v3 0.i256 1.i256; v6.i256 = mload v5 i256; mstore v6 v1 i256; - v8.i256 = add v6 32.i256; + v8.i256 = call %u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add v6 32.i256; v9.*@__fe_SolEncoder_4 = int_to_ptr v0 *@__fe_SolEncoder_4; v10.*i256 = gep v9 0.i256 1.i256; mstore v10 v8 i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/tuple_expr.snap b/crates/codegen/tests/fixtures/sonatina_ir/tuple_expr.snap index 59f7d57e1c..684ff0663d 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/tuple_expr.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/tuple_expr.snap @@ -9,22 +9,40 @@ type @__fe_tuple_0 = {i256, i256}; func private %tuple_expr() -> i256 { block0: - v2.*i8 = evm_malloc 64.i256; - v3.i256 = ptr_to_int v2 i256; - v6.i256 = add 1.i256 2.i256; - v7.i64 = trunc v6 i64; + v3.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add 1.i256 2.i256; + v5.*i8 = evm_malloc 64.i256; + v6.i256 = ptr_to_int v5 i256; + v7.i64 = trunc v3 i64; v8.i256 = zext v7 i256; - v9.*@__fe_tuple_0 = bitcast v2 *@__fe_tuple_0; + v9.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; v10.*i256 = gep v9 0.i256 0.i256; mstore v10 v8 i256; v11.i1 = is_zero 0.i256; v12.i256 = zext v11 i256; v13.i1 = ne v12 0.i256; v14.i256 = zext v13 i256; - v15.*@__fe_tuple_0 = bitcast v2 *@__fe_tuple_0; + v15.*@__fe_tuple_0 = bitcast v5 *@__fe_tuple_0; v16.*i256 = gep v15 0.i256 1.i256; mstore v16 v14 i256; - return v3; + return v6; +} + +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; } func private %__fe_sonatina_entry() { diff --git a/crates/codegen/tests/fixtures/sonatina_ir/while_cond_call.snap b/crates/codegen/tests/fixtures/sonatina_ir/while_cond_call.snap index 92b1b7cd88..942e281988 100644 --- a/crates/codegen/tests/fixtures/sonatina_ir/while_cond_call.snap +++ b/crates/codegen/tests/fixtures/sonatina_ir/while_cond_call.snap @@ -7,9 +7,8 @@ target = "evm-ethereum-osaka" func private %lt_ten(v0.i256) -> i256 { block0: - v3.i1 = lt v0 10.i256; - v4.i256 = zext v3 i256; - return v4; + v3.i256 = call %u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt v0 10.i256; + return v3; } func private %while_cond_call() -> i256 { @@ -23,13 +22,40 @@ func private %while_cond_call() -> i256 { br v3 block2 block3; block2: - v6.i256 = add v1 1.i256; + v6.i256 = call %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add v1 1.i256; jump block1; block3: return v1; } +func private %u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = lt v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + +func private %u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i64 = trunc v0 i64; + v4.i64 = trunc v1 i64; + v5.i64 = add v3 v4; + v6.i256 = zext v3 i256; + v7.i256 = zext v4 i256; + v8.i256 = zext v5 i256; + v9.i1 = lt v8 v6; + br v9 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + return v8; +} + func private %__fe_sonatina_entry() { block0: v1.i256 = call %lt_ten 0.i256; diff --git a/crates/codegen/tests/fixtures/sonatina_ir/wrapping_saturating.snap b/crates/codegen/tests/fixtures/sonatina_ir/wrapping_saturating.snap new file mode 100644 index 0000000000..1502c441d4 --- /dev/null +++ b/crates/codegen/tests/fixtures/sonatina_ir/wrapping_saturating.snap @@ -0,0 +1,366 @@ +--- +source: crates/codegen/tests/sonatina_ir.rs +expression: output +input_file: crates/codegen/tests/fixtures/wrapping_saturating.fe +--- +target = "evm-ethereum-osaka" + +type @__fe_tuple_0 = {i256, i256, i256}; +type @__fe_tuple_1 = {i256, i256, i256}; + +func private %wrapping_ops_u64(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add v0 v1; + v4.i256 = call %u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub v0 v1; + v5.i256 = call %u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul v0 v1; + v7.*i8 = evm_malloc 96.i256; + v8.i256 = ptr_to_int v7 i256; + v9.i64 = trunc v3 i64; + v10.i256 = zext v9 i256; + v11.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v12.*i256 = gep v11 0.i256 0.i256; + mstore v12 v10 i256; + v13.i64 = trunc v4 i64; + v14.i256 = zext v13 i256; + v15.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v17.*i256 = gep v15 0.i256 1.i256; + mstore v17 v14 i256; + v18.i64 = trunc v5 i64; + v19.i256 = zext v18 i256; + v20.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v22.*i256 = gep v20 0.i256 2.i256; + mstore v22 v19 i256; + return v8; +} + +func private %saturating_ops_u64(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_saturatingadd_h7ca6e43aca8f23bb_saturating_add v0 v1; + v4.i256 = call %u64_haee7f05a097ffa16_saturatingsub_hd0c1c727e69d9468_saturating_sub v0 v1; + v5.i256 = call %u64_haee7f05a097ffa16_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul v0 v1; + v7.*i8 = evm_malloc 96.i256; + v8.i256 = ptr_to_int v7 i256; + v9.i64 = trunc v3 i64; + v10.i256 = zext v9 i256; + v11.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v12.*i256 = gep v11 0.i256 0.i256; + mstore v12 v10 i256; + v13.i64 = trunc v4 i64; + v14.i256 = zext v13 i256; + v15.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v17.*i256 = gep v15 0.i256 1.i256; + mstore v17 v14 i256; + v18.i64 = trunc v5 i64; + v19.i256 = zext v18 i256; + v20.*@__fe_tuple_0 = bitcast v7 *@__fe_tuple_0; + v22.*i256 = gep v20 0.i256 2.i256; + mstore v22 v19 i256; + return v8; +} + +func private %wrapping_ops_u256(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add v0 v1; + v4.i256 = call %u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub v0 v1; + v5.i256 = call %u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul v0 v1; + v7.*i8 = evm_malloc 96.i256; + v8.i256 = ptr_to_int v7 i256; + v9.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v10.*i256 = gep v9 0.i256 0.i256; + mstore v10 v3 i256; + v11.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v13.*i256 = gep v11 0.i256 1.i256; + mstore v13 v4 i256; + v14.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v16.*i256 = gep v14 0.i256 2.i256; + mstore v16 v5 i256; + return v8; +} + +func private %saturating_ops_u256(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_saturatingadd_h7ca6e43aca8f23bb_saturating_add v0 v1; + v4.i256 = call %u256_h3271ca15373d4483_saturatingsub_hd0c1c727e69d9468_saturating_sub v0 v1; + v5.i256 = call %u256_h3271ca15373d4483_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul v0 v1; + v7.*i8 = evm_malloc 96.i256; + v8.i256 = ptr_to_int v7 i256; + v9.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v10.*i256 = gep v9 0.i256 0.i256; + mstore v10 v3 i256; + v11.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v13.*i256 = gep v11 0.i256 1.i256; + mstore v13 v4 i256; + v14.*@__fe_tuple_1 = bitcast v7 *@__fe_tuple_1; + v16.*i256 = gep v14 0.i256 2.i256; + mstore v16 v5 i256; + return v8; +} + +func private %u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v5.i256 = and v3 18446744073709551615.i256; + return v5; +} + +func private %u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + v5.i256 = and v3 18446744073709551615.i256; + return v5; +} + +func private %u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = mul v0 v1; + v5.i256 = and v3 18446744073709551615.i256; + return v5; +} + +func private %u64_haee7f05a097ffa16_saturatingadd_h7ca6e43aca8f23bb_saturating_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v5.i256 = and v3 18446744073709551615.i256; + v6.i256 = and v5 18446744073709551615.i256; + v7.i256 = and v0 18446744073709551615.i256; + v8.i1 = lt v6 v7; + v9.i256 = zext v8 i256; + v10.i1 = ne v9 0.i256; + br v10 block1 block2; + + block1: + jump block3; + + block2: + jump block3; + + block3: + v12.i256 = phi (18446744073709551615.i256 block1) (v5 block2); + return v12; +} + +func private %u64_haee7f05a097ffa16_saturatingsub_hd0c1c727e69d9468_saturating_sub(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v1 18446744073709551615.i256; + v5.i256 = and v0 18446744073709551615.i256; + v6.i1 = gt v4 v5; + v7.i256 = zext v6 i256; + v8.i1 = ne v7 0.i256; + br v8 block1 block2; + + block1: + jump block3; + + block2: + v11.i256 = sub v0 v1; + v12.i256 = and v11 18446744073709551615.i256; + jump block3; + + block3: + v13.i256 = phi (0.i256 block1) (v12 block2); + return v13; +} + +func private %u64_haee7f05a097ffa16_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v0 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block3; + + block1: + jump block7; + + block2: + v7.i256 = mul v0 v1; + v9.i256 = and v7 18446744073709551615.i256; + v10.i256 = call %u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div v9 v0; + v11.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_ne v10 v1; + v12.i1 = ne v11 0.i256; + br v12 block4 block5; + + block3: + v14.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v1 0.i256; + v15.i1 = ne v14 0.i256; + br v15 block1 block2; + + block4: + jump block6; + + block5: + jump block6; + + block6: + v17.i256 = phi (18446744073709551615.i256 block4) (v9 block5); + jump block7; + + block7: + v18.i256 = phi (0.i256 block1) (v17 block6); + return v18; +} + +func private %u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = sub v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = mul v0 v1; + return v3; +} + +func private %u256_h3271ca15373d4483_saturatingadd_h7ca6e43aca8f23bb_saturating_add(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = add v0 v1; + v4.i1 = lt v3 v0; + v5.i256 = zext v4 i256; + v6.i1 = ne v5 0.i256; + br v6 block1 block2; + + block1: + jump block3; + + block2: + jump block3; + + block3: + v9.i256 = phi (-1.i256 block1) (v3 block2); + return v9; +} + +func private %u256_h3271ca15373d4483_saturatingsub_hd0c1c727e69d9468_saturating_sub(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = gt v1 v0; + v4.i256 = zext v3 i256; + v5.i1 = ne v4 0.i256; + br v5 block1 block2; + + block1: + jump block3; + + block2: + v8.i256 = sub v0 v1; + jump block3; + + block3: + v9.i256 = phi (0.i256 block1) (v8 block2); + return v9; +} + +func private %u256_h3271ca15373d4483_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v0 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block3; + + block1: + jump block7; + + block2: + v7.i256 = mul v0 v1; + v8.i256 = call %u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div v7 v0; + v9.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_ne v8 v1; + v10.i1 = ne v9 0.i256; + br v10 block4 block5; + + block3: + v12.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v1 0.i256; + v13.i1 = ne v12 0.i256; + br v13 block1 block2; + + block4: + jump block6; + + block5: + jump block6; + + block6: + v16.i256 = phi (-1.i256 block4) (v7 block5); + jump block7; + + block7: + v17.i256 = phi (0.i256 block1) (v16 block6); + return v17; +} + +func private %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = eq v4 v5; + v7.i256 = zext v6 i256; + return v7; +} + +func private %u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u64_haee7f05a097ffa16_eq_he50383edd273619f_eq v1 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v7.i256 = evm_udiv v0 v1; + return v7; +} + +func private %u64_haee7f05a097ffa16_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v4.i256 = and v0 18446744073709551615.i256; + v5.i256 = and v1 18446744073709551615.i256; + v6.i1 = eq v4 v5; + v7.i1 = is_zero v6; + v8.i256 = zext v7 i256; + return v8; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i256 = zext v3 i256; + return v4; +} + +func private %u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div(v0.i256, v1.i256) -> i256 { + block0: + v3.i256 = call %u256_h3271ca15373d4483_eq_he50383edd273619f_eq v1 0.i256; + v4.i1 = ne v3 0.i256; + br v4 block1 block2; + + block1: + evm_revert 0.i256 0.i256; + + block2: + v7.i256 = evm_udiv v0 v1; + return v7; +} + +func private %u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v0.i256, v1.i256) -> i256 { + block0: + v3.i1 = eq v0 v1; + v4.i1 = is_zero v3; + v5.i256 = zext v4 i256; + return v5; +} + +func private %__fe_sonatina_entry() { + block0: + v1.i256 = call %wrapping_ops_u64 0.i256 0.i256; + evm_stop; +} + + +object @Contract { + section runtime { + entry %__fe_sonatina_entry; + } +} diff --git a/crates/codegen/tests/fixtures/storage.snap b/crates/codegen/tests/fixtures/storage.snap index e70ae0b4a8..1e4f84a015 100644 --- a/crates/codegen/tests/fixtures/storage.snap +++ b/crates/codegen/tests/fixtures/storage.snap @@ -1,6 +1,5 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/storage.fe --- @@ -36,22 +35,60 @@ object "Coin" { ret := v0 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $credit_alice__StorPtr_CoinStore__StorPtr_TotalSupply___c407f5b00af9ba78($amount, $store, $supply) -> ret { let v0 := sload($store) - sstore($store, add(v0, $amount)) - let v1 := sload($supply) - sstore($supply, add(v1, $amount)) - let v2 := sload($store) - ret := v2 + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0, $amount) + sstore($store, v1) + let v2 := sload($supply) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v2, $amount) + sstore($supply, v3) + let v4 := sload($store) + ret := v4 leave } function $credit_bob__StorPtr_CoinStore__StorPtr_TotalSupply___c407f5b00af9ba78($amount, $store, $supply) -> ret { let v0 := sload(add($store, 1)) - sstore(add($store, 1), add(v0, $amount)) - let v1 := sload($supply) - sstore($supply, add(v1, $amount)) - let v2 := sload(add($store, 1)) - ret := v2 + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v0, $amount) + sstore(add($store, 1), v1) + let v2 := sload($supply) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v2, $amount) + sstore($supply, v3) + let v4 := sload(add($store, 1)) + ret := v4 leave } function $runtime__StorPtr_Evm___207f35a85ac4062e() { @@ -129,57 +166,63 @@ object "Coin" { } function $transfer_from_alice__StorPtr_CoinStore___ba1c0d0726e89ba2($amount, $store) -> ret { let v0 := sload($store) - let v1 := lt(v0, $amount) - if v1 { - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor(v0, $amount) + let v2 := v1 + if v2 { + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 32)) - mstore(v2, 1) - ret := v2 + mstore(0x40, add(v3, 32)) + mstore(v3, 1) + ret := v3 leave } - if iszero(v1) { - let v3 := sload($store) - sstore($store, sub(v3, $amount)) - let v4 := sload(add($store, 1)) - sstore(add($store, 1), add(v4, $amount)) - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 + if iszero(v2) { + let v4 := sload($store) + let v5 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor(v4, $amount) + sstore($store, v5) + let v6 := sload(add($store, 1)) + let v7 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v6, $amount) + sstore(add($store, 1), v7) + let v8 := mload(0x40) + if iszero(v8) { + v8 := 0x80 } - mstore(0x40, add(v5, 32)) - mstore(v5, 0) - ret := v5 + mstore(0x40, add(v8, 32)) + mstore(v8, 0) + ret := v8 leave } } function $transfer_from_bob__StorPtr_CoinStore___ba1c0d0726e89ba2($amount, $store) -> ret { let v0 := sload(add($store, 1)) - let v1 := lt(v0, $amount) - if v1 { - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor(v0, $amount) + let v2 := v1 + if v2 { + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 32)) - mstore(v2, 1) - ret := v2 + mstore(0x40, add(v3, 32)) + mstore(v3, 1) + ret := v3 leave } - if iszero(v1) { - let v3 := sload(add($store, 1)) - sstore(add($store, 1), sub(v3, $amount)) - let v4 := sload($store) - sstore($store, add(v4, $amount)) - let v5 := mload(0x40) - if iszero(v5) { - v5 := 0x80 + if iszero(v2) { + let v4 := sload(add($store, 1)) + let v5 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor(v4, $amount) + sstore(add($store, 1), v5) + let v6 := sload($store) + let v7 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor(v6, $amount) + sstore($store, v7) + let v8 := mload(0x40) + if iszero(v8) { + v8 := 0x80 } - mstore(0x40, add(v5, 32)) - mstore(v5, 0) - ret := v5 + mstore(0x40, add(v8, 32)) + mstore(v8, 0) + ret := v8 leave } } @@ -198,6 +241,45 @@ object "Coin" { ret := v0 leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add_stor($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt_stor_arg0_root_stor($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub_stor($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } $runtime__StorPtr_Evm___207f35a85ac4062e() return(0, 0) } diff --git a/crates/codegen/tests/fixtures/storage_map_contract.snap b/crates/codegen/tests/fixtures/storage_map_contract.snap index 54647e52e8..99891f45f8 100644 --- a/crates/codegen/tests/fixtures/storage_map_contract.snap +++ b/crates/codegen/tests/fixtures/storage_map_contract.snap @@ -21,6 +21,40 @@ object "BalanceMap" { mstore(v0, $value) return(v0, 32) } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $get_allowance__1_MemPtr_StorageMap_u256__u256__1____7c78a7c6cb7770e1($addr, $allowances) -> ret { let v0 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_1__3c02c0f2b86be0bb($allowances, $addr) ret := v0 @@ -127,32 +161,60 @@ object "BalanceMap" { } mstore(64, add(v0, 0)) let v1 := $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key(v0, $key) - mstore(add(v0, v1), $salt) - let v2 := add(v1, 32) - let v3 := keccak256(v0, v2) - ret := v3 + let v2 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, v1) + mstore(v2, $salt) + let v3 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v1, 32) + let v4 := keccak256(v0, v3) + ret := v4 leave } function $transfer__0_MemPtr_StorageMap_u256__u256__0____a41b2ecb073da43d($from, $to, $amount, $balances) -> ret { let v0 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971($balances, $from) - let v1 := lt(v0, $amount) - if v1 { + let v1 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v0, $amount) + let v2 := v1 + if v2 { ret := 1 leave } - if iszero(v1) { - let v2 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971($balances, $to) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971($balances, $from, sub(v0, $amount)) - $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971($balances, $to, add(v2, $amount)) + if iszero(v2) { + let v3 := $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_get__u256_u256_0__6a346ad3c930d971($balances, $to) + let v4 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971($balances, $from, v4) + let v5 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $amount) + $storagemap_k__v__const_salt__u256__h5955888dd44c2a19_set__u256_u256_0__6a346ad3c930d971($balances, $to, v5) ret := 0 leave } } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_storagekey_hf9e3d38a13ff4409_write_key($ptr, $self) -> ret { mstore($ptr, $self) ret := 32 leave } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_wordrepr_h7483d41ac8178d88_from_word($word) -> ret { ret := $word leave @@ -161,6 +223,16 @@ object "BalanceMap" { ret := $self leave } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } $runtime__StorPtr_Evm___207f35a85ac4062e() return(0, 0) } diff --git a/crates/codegen/tests/fixtures/test_output/effect_test.snap b/crates/codegen/tests/fixtures/test_output/effect_test.snap index f77ccfe823..4e436a76ed 100644 --- a/crates/codegen/tests/fixtures/test_output/effect_test.snap +++ b/crates/codegen/tests/fixtures/test_output/effect_test.snap @@ -11,9 +11,46 @@ object "test_test_effect" { object "runtime" { code { + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } function $test_effect__StorPtr_u256___64779554cfbf0358($x) { let v0 := sload($x) - sstore($x, add(v0, 1)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 1) + sstore($x, v1) + leave + } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 leave } $test_effect__StorPtr_u256___64779554cfbf0358(0) diff --git a/crates/codegen/tests/fixtures/tstor_ptr_contract.snap b/crates/codegen/tests/fixtures/tstor_ptr_contract.snap index 8ea4e55533..f5b1407ceb 100644 --- a/crates/codegen/tests/fixtures/tstor_ptr_contract.snap +++ b/crates/codegen/tests/fixtures/tstor_ptr_contract.snap @@ -105,11 +105,12 @@ object "GuardContract" { code { function $__GuardContract_recv_0_0($args, $block_reentrance, $call_count) -> ret { let v0 := sload($call_count) - sstore($call_count, add(v0, 1)) - let v1 := iszero(eq(tload($block_reentrance), 0)) - let v2 := v1 - tstore($block_reentrance, iszero(iszero(iszero(v2)))) - ret := v2 + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 1) + sstore($call_count, v1) + let v2 := iszero(eq(tload($block_reentrance), 0)) + let v3 := v2 + tstore($block_reentrance, iszero(iszero(iszero(v3)))) + ret := v3 leave } function $__GuardContract_runtime() { @@ -139,15 +140,50 @@ object "GuardContract" { } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len($self) -> ret { let v0 := calldatasize() - ret := sub(v0, $self) + let v1 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v0, $self) + ret := v1 leave } function $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at($self, $byte_offset) -> ret { - let v0 := add($self, $byte_offset) + let v0 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $byte_offset) let v1 := calldataload(v0) ret := v1 leave } + function $checked_add_u256($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_add_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) + } + ret := v0 + leave + } + function $checked_sub_u256($a, $b) -> ret { + let v0 := $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) + ret := v0 + leave + } + function $checked_sub_unsigned_impl__u256__3271ca15373d4483($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($b) + let v1 := $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($a) + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt(v0, v1) + let v3 := v2 + if v3 { + revert(0, 0) + } + let v4 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + ret := v4 + leave + } function $cursor_i__h140a998c67d6d59c_fork__CallData_hf71d505b6ff5dc81__e6d5f05c3478f563($self, $pos) -> ret { let v0 := mload($self) let v1 := mload(0x40) @@ -208,13 +244,14 @@ object "GuardContract" { function $runtime_selector__Evm_hef0af3106e109414_Sol_hfd482bb803ad8c5f__e4e3f8d20b3805a2($self) -> ret { let v0 := $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_input($self) let v1 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_len(v0) - let v2 := lt(v1, 4) - if v2 { + let v2 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, 4) + let v3 := v2 + if v3 { $evm_hef0af3106e109414_contracthost_h57111e7eb283a125_abort($self) } - let v3 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) - let v4 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v3) - ret := v4 + let v4 := $calldata_hf71d505b6ff5dc81_byteinput_hc4c2cb44299530ae_word_at(v0, 0) + let v5 := $sol_hfd482bb803ad8c5f_abi_h2da9a2d0b1ddaeb7_selector_from_prefix(v4) + ret := v5 leave } function $s_h33f7c3322e562590_intdowncast_hf946d58b157999e1_downcast_unchecked__u256_u32__6e3637cd3e911b35($self) -> ret { @@ -256,37 +293,41 @@ object "GuardContract" { function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_finish($self) -> ret { let v0 := mload($self) let v1 := mload(add($self, 64)) - let v2 := mload(0x40) - if iszero(v2) { - v2 := 0x80 + let v2 := $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub(v1, v0) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 } - mstore(0x40, add(v2, 64)) - mstore(v2, v0) - mstore(add(v2, 32), sub(v1, v0)) - ret := v2 + mstore(0x40, add(v3, 64)) + mstore(v3, v0) + mstore(add(v3, 32), v2) + ret := v3 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_reserve_head($self, $bytes) -> ret { let v0 := mload($self) - let v1 := eq(v0, 0) - if v1 { - let v2 := mload(64) - if iszero(v2) { - v2 := 0x80 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq(v0, 0) + let v2 := v1 + if v2 { + let v3 := mload(64) + if iszero(v3) { + v3 := 0x80 } - mstore(64, add(v2, $bytes)) - mstore($self, v2) - mstore(add($self, 32), v2) - mstore(add($self, 64), add(v2, $bytes)) + mstore(64, add(v3, $bytes)) + mstore($self, v3) + mstore(add($self, 32), v3) + let v4 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v3, $bytes) + mstore(add($self, 64), v4) } - let v3 := mload($self) - ret := v3 + let v5 := mload($self) + ret := v5 leave } function $solencoder_h1b9228b90dad6928_abiencoder_hffd58d20d4321024_write_word($self, $v) { let v0 := mload(add($self, 32)) mstore(v0, $v) - mstore(add($self, 32), add(v0, 32)) + let v1 := $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add(v0, 32) + mstore(add($self, 32), v1) leave } function $solencoder_h1b9228b90dad6928_new() -> ret { @@ -314,10 +355,45 @@ object "GuardContract" { ret := $raw leave } + function $u256_h3271ca15373d4483_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave + } function $u256_h3271ca15373d4483_intword_h9a147c8c32b1323c_to_word($self) -> ret { ret := $self leave } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_gt($self, $other) -> ret { + let v0 := gt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_sub_h7b686d389c07535e_sub($self, $other) -> ret { + let v0 := $checked_sub_u256($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave + } + function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave + } function $u32_h20aa0c10687491ad_intword_h9a147c8c32b1323c_from_word($word) -> ret { ret := $word leave diff --git a/crates/codegen/tests/fixtures/tuple_expr.snap b/crates/codegen/tests/fixtures/tuple_expr.snap index 4406357601..e60a6c9b60 100644 --- a/crates/codegen/tests/fixtures/tuple_expr.snap +++ b/crates/codegen/tests/fixtures/tuple_expr.snap @@ -1,17 +1,53 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/tuple_expr.fe --- function $tuple_expr() -> ret { - let v0 := mload(0x40) - if iszero(v0) { - v0 := 0x80 + let v0 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(1, 2) + let v1 := mload(0x40) + if iszero(v1) { + v1 := 0x80 + } + mstore(0x40, add(v1, 64)) + mstore(v1, and(v0, 0xffffffffffffffff)) + mstore(add(v1, 32), iszero(iszero(iszero(0)))) + ret := v1 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) } - mstore(0x40, add(v0, 64)) - mstore(v0, and(add(1, 2), 0xffffffffffffffff)) - mstore(add(v0, 32), iszero(iszero(iszero(0)))) ret := v0 leave } +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/while_cond_call.snap b/crates/codegen/tests/fixtures/while_cond_call.snap index e01adb5000..9053b8d43d 100644 --- a/crates/codegen/tests/fixtures/while_cond_call.snap +++ b/crates/codegen/tests/fixtures/while_cond_call.snap @@ -1,11 +1,11 @@ --- source: crates/codegen/tests/yul.rs -assertion_line: 33 expression: output input_file: tests/fixtures/while_cond_call.fe --- function $lt_ten($value) -> ret { - ret := lt($value, 10) + let v0 := $u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt($value, 10) + ret := v0 leave } function $while_cond_call() -> ret { @@ -15,8 +15,50 @@ function $while_cond_call() -> ret { if iszero(v1) { break } - v0 := add(v0, 1) + let v2 := $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add(v0, 1) + v0 := v2 + } + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_add_h4cebc227a0cfd3c0_add($self, $other) -> ret { + let v0 := $checked_add_u64($self, $other) + ret := v0 + leave +} +function $checked_add_u64($a, $b) -> ret { + let v0 := $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) + ret := v0 + leave +} +function $checked_add_unsigned_impl__u64__aee7f05a097ffa16($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word(v0) + let v2 := $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($a) + let v3 := $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt(v1, v2) + let v4 := v3 + if v4 { + revert(0, 0) } ret := v0 leave } +function $u256_h3271ca15373d4483_ord_h264f6d6d75097a_lt($self, $other) -> ret { + let v0 := lt($self, $other) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u8_hbc9d6eeaea22ffb5_intword_h9a147c8c32b1323c_to_word($self) -> ret { + ret := $self + leave +} diff --git a/crates/codegen/tests/fixtures/wrapping_saturating.fe b/crates/codegen/tests/fixtures/wrapping_saturating.fe new file mode 100644 index 0000000000..e912044160 --- /dev/null +++ b/crates/codegen/tests/fixtures/wrapping_saturating.fe @@ -0,0 +1,18 @@ +use core::ops::{WrappingAdd, WrappingSub, WrappingMul} +use core::ops::{SaturatingAdd, SaturatingSub, SaturatingMul} + +pub fn wrapping_ops_u64(a: u64, b: u64) -> (u64, u64, u64) { + (a.wrapping_add(b), a.wrapping_sub(b), a.wrapping_mul(b)) +} + +pub fn saturating_ops_u64(a: u64, b: u64) -> (u64, u64, u64) { + (a.saturating_add(b), a.saturating_sub(b), a.saturating_mul(b)) +} + +pub fn wrapping_ops_u256(a: u256, b: u256) -> (u256, u256, u256) { + (a.wrapping_add(b), a.wrapping_sub(b), a.wrapping_mul(b)) +} + +pub fn saturating_ops_u256(a: u256, b: u256) -> (u256, u256, u256) { + (a.saturating_add(b), a.saturating_sub(b), a.saturating_mul(b)) +} diff --git a/crates/codegen/tests/fixtures/wrapping_saturating.snap b/crates/codegen/tests/fixtures/wrapping_saturating.snap new file mode 100644 index 0000000000..bc137d227a --- /dev/null +++ b/crates/codegen/tests/fixtures/wrapping_saturating.snap @@ -0,0 +1,261 @@ +--- +source: crates/codegen/tests/yul.rs +expression: output +input_file: tests/fixtures/wrapping_saturating.fe +--- +function $wrapping_ops_u64($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + let v2 := $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 + } + mstore(0x40, add(v3, 96)) + mstore(v3, and(v0, 0xffffffffffffffff)) + mstore(add(v3, 32), and(v1, 0xffffffffffffffff)) + mstore(add(v3, 64), and(v2, 0xffffffffffffffff)) + ret := v3 + leave +} +function $saturating_ops_u64($a, $b) -> ret { + let v0 := $u64_haee7f05a097ffa16_saturatingadd_h7ca6e43aca8f23bb_saturating_add($a, $b) + let v1 := $u64_haee7f05a097ffa16_saturatingsub_hd0c1c727e69d9468_saturating_sub($a, $b) + let v2 := $u64_haee7f05a097ffa16_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul($a, $b) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 + } + mstore(0x40, add(v3, 96)) + mstore(v3, and(v0, 0xffffffffffffffff)) + mstore(add(v3, 32), and(v1, 0xffffffffffffffff)) + mstore(add(v3, 64), and(v2, 0xffffffffffffffff)) + ret := v3 + leave +} +function $wrapping_ops_u256($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($a, $b) + let v1 := $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($a, $b) + let v2 := $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($a, $b) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 + } + mstore(0x40, add(v3, 96)) + mstore(v3, v0) + mstore(add(v3, 32), v1) + mstore(add(v3, 64), v2) + ret := v3 + leave +} +function $saturating_ops_u256($a, $b) -> ret { + let v0 := $u256_h3271ca15373d4483_saturatingadd_h7ca6e43aca8f23bb_saturating_add($a, $b) + let v1 := $u256_h3271ca15373d4483_saturatingsub_hd0c1c727e69d9468_saturating_sub($a, $b) + let v2 := $u256_h3271ca15373d4483_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul($a, $b) + let v3 := mload(0x40) + if iszero(v3) { + v3 := 0x80 + } + mstore(0x40, add(v3, 96)) + mstore(v3, v0) + mstore(add(v3, 32), v1) + mstore(add(v3, 64), v2) + ret := v3 + leave +} +function $u64_haee7f05a097ffa16_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := and(sub(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := and(mul(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_saturatingadd_h7ca6e43aca8f23bb_saturating_add($self, $other) -> ret { + let v0 := and(add(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + let v1 := 0 + let v2 := lt(and(v0, 0xffffffffffffffff), and($self, 0xffffffffffffffff)) + let v3 := v2 + if v3 { + v1 := 18446744073709551615 + } + if iszero(v3) { + v1 := v0 + } + ret := v1 + leave +} +function $u64_haee7f05a097ffa16_saturatingsub_hd0c1c727e69d9468_saturating_sub($self, $other) -> ret { + let v0 := 0 + let v1 := gt(and($other, 0xffffffffffffffff), and($self, 0xffffffffffffffff)) + let v2 := v1 + if v2 { + v0 := 0 + } + if iszero(v2) { + let v3 := and(sub(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + v0 := v3 + } + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul($self, $other) -> ret { + let v0 := 0 + let v1 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, 0) + let v2 := v1 + if v2 { + v0 := 0 + ret := v0 + leave + } + if iszero(v2) { + let v3 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($other, 0) + let v4 := v3 + if v4 { + v0 := 0 + ret := v0 + leave + } + if iszero(v4) { + let v5 := and(mul(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + let v6 := 0 + let v7 := $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div(v5, $self) + let v8 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_ne(v7, $other) + let v9 := v8 + if v9 { + v6 := 18446744073709551615 + } + if iszero(v9) { + v6 := v5 + } + v0 := v6 + ret := v0 + leave + } + } +} +function $u256_h3271ca15373d4483_wrappingadd_h14afa79b3047617f_wrapping_add($self, $other) -> ret { + let v0 := add($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingsub_h6880d1ff91f0a556_wrapping_sub($self, $other) -> ret { + let v0 := sub($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_wrappingmul_h64e6b83610cda761_wrapping_mul($self, $other) -> ret { + let v0 := mul($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_saturatingadd_h7ca6e43aca8f23bb_saturating_add($self, $other) -> ret { + let v0 := add($self, $other) + let v1 := 0 + let v2 := lt(v0, $self) + let v3 := v2 + if v3 { + v1 := 115792089237316195423570985008687907853269984665640564039457584007913129639935 + } + if iszero(v3) { + v1 := v0 + } + ret := v1 + leave +} +function $u256_h3271ca15373d4483_saturatingsub_hd0c1c727e69d9468_saturating_sub($self, $other) -> ret { + let v0 := 0 + let v1 := gt($other, $self) + let v2 := v1 + if v2 { + v0 := 0 + } + if iszero(v2) { + let v3 := sub($self, $other) + v0 := v3 + } + ret := v0 + leave +} +function $u256_h3271ca15373d4483_saturatingmul_hf2bc6be7b84ff8f7_saturating_mul($self, $other) -> ret { + let v0 := 0 + let v1 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, 0) + let v2 := v1 + if v2 { + v0 := 0 + ret := v0 + leave + } + if iszero(v2) { + let v3 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($other, 0) + let v4 := v3 + if v4 { + v0 := 0 + ret := v0 + leave + } + if iszero(v4) { + let v5 := mul($self, $other) + let v6 := 0 + let v7 := $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div(v5, $self) + let v8 := $u256_h3271ca15373d4483_eq_he50383edd273619f_ne(v7, $other) + let v9 := v8 + if v9 { + v6 := 115792089237316195423570985008687907853269984665640564039457584007913129639935 + } + if iszero(v9) { + v6 := v5 + } + v0 := v6 + ret := v0 + leave + } + } +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)) + ret := v0 + leave +} +function $u64_haee7f05a097ffa16_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u64_haee7f05a097ffa16_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := and(div(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff)), 0xffffffffffffffff) + ret := v2 + leave +} +function $u64_haee7f05a097ffa16_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq(and($self, 0xffffffffffffffff), and($other, 0xffffffffffffffff))) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($self, $other) -> ret { + let v0 := eq($self, $other) + ret := v0 + leave +} +function $u256_h3271ca15373d4483_div_h14000ca7bc1a1bc4_div($self, $other) -> ret { + let v0 := $u256_h3271ca15373d4483_eq_he50383edd273619f_eq($other, 0) + let v1 := v0 + if v1 { + revert(0, 0) + } + let v2 := div($self, $other) + ret := v2 + leave +} +function $u256_h3271ca15373d4483_eq_he50383edd273619f_ne($self, $other) -> ret { + let v0 := iszero(eq($self, $other)) + ret := v0 + leave +} diff --git a/crates/fe/tests/fixtures/build_foundry/erc20.fe b/crates/fe/tests/fixtures/build_foundry/erc20.fe index 5738c779d2..91225df90a 100644 --- a/crates/fe/tests/fixtures/build_foundry/erc20.fe +++ b/crates/fe/tests/fixtures/build_foundry/erc20.fe @@ -91,7 +91,7 @@ pub contract CoolCoin uses (ctx: Ctx, log: mut Log) { recv Erc20Extended { Mint { to, amount } -> bool uses (mut store, mut log) { - store.total_supply += amount + store.total_supply = store.total_supply + amount store.balances.set(key: to, value: store.balances.get(key: to) + amount) emit_transfer(from: Address::zero(), to: to, value: amount) return true diff --git a/crates/fe/tests/fixtures/fe_test/checked_arithmetic_matrix.fe b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_matrix.fe new file mode 100644 index 0000000000..50127cadfc --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_matrix.fe @@ -0,0 +1,715 @@ +use std::evm::effects::assert + +// ===================================================================== +// u8 / i8 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u8() { + let x: u8 = 255 + let y: u8 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u8() { + let a: u8 = 0 + let b: u8 = 1 + let c: u8 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u8() { + let a: u8 = 16 + let b: u8 = 16 + let c: u8 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u8() { + let a: u8 = 1 + let b: u8 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u8() { + let a: u8 = 1 + let b: u8 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u8() { + let x: u8 = 2 + let y: u8 = x ** 8 +} + +#[test] +fn unsigned_happy_path_u8() { + let a: u8 = 12 + let b: u8 = 10 + let c: u8 = 5 + let p: u8 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i8() { + let x: i8 = 127 + let y: i8 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i8() { + let x: i8 = -128 + let y: i8 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i8() { + let min: i8 = -128 + let y: i8 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i8() { + let x: i8 = -128 + let y: i8 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i8() { + let a: i8 = 1 + let b: i8 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i8() { + let min: i8 = -128 + let y: i8 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i8() { + let a: i8 = 1 + let b: i8 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i8() { + let x: i8 = 2 + let y: i8 = x ** 7 +} + +#[test] +fn signed_happy_path_i8() { + let a: i8 = -12 + let b: i8 = 10 + let c: i8 = 5 + let p: i8 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} + +// ===================================================================== +// u16 / i16 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u16() { + let x: u16 = 65535 + let y: u16 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u16() { + let a: u16 = 0 + let b: u16 = 1 + let c: u16 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u16() { + let a: u16 = 256 + let b: u16 = 256 + let c: u16 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u16() { + let a: u16 = 1 + let b: u16 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u16() { + let a: u16 = 1 + let b: u16 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u16() { + let x: u16 = 2 + let y: u16 = x ** 16 +} + +#[test] +fn unsigned_happy_path_u16() { + let a: u16 = 12 + let b: u16 = 10 + let c: u16 = 5 + let p: u16 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i16() { + let x: i16 = 32767 + let y: i16 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i16() { + let x: i16 = -32768 + let y: i16 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i16() { + let min: i16 = -32768 + let y: i16 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i16() { + let x: i16 = -32768 + let y: i16 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i16() { + let a: i16 = 1 + let b: i16 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i16() { + let min: i16 = -32768 + let y: i16 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i16() { + let a: i16 = 1 + let b: i16 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i16() { + let x: i16 = 2 + let y: i16 = x ** 15 +} + +#[test] +fn signed_happy_path_i16() { + let a: i16 = -12 + let b: i16 = 10 + let c: i16 = 5 + let p: i16 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} + +// ===================================================================== +// u32 / i32 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u32() { + let x: u32 = 4294967295 + let y: u32 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u32() { + let a: u32 = 0 + let b: u32 = 1 + let c: u32 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u32() { + let a: u32 = 65536 + let b: u32 = 65536 + let c: u32 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u32() { + let a: u32 = 1 + let b: u32 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u32() { + let a: u32 = 1 + let b: u32 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u32() { + let x: u32 = 2 + let y: u32 = x ** 32 +} + +#[test] +fn unsigned_happy_path_u32() { + let a: u32 = 12 + let b: u32 = 10 + let c: u32 = 5 + let p: u32 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i32() { + let x: i32 = 2147483647 + let y: i32 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i32() { + let x: i32 = -2147483648 + let y: i32 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i32() { + let min: i32 = -2147483648 + let y: i32 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i32() { + let x: i32 = -2147483648 + let y: i32 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i32() { + let a: i32 = 1 + let b: i32 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i32() { + let min: i32 = -2147483648 + let y: i32 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i32() { + let a: i32 = 1 + let b: i32 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i32() { + let x: i32 = 2 + let y: i32 = x ** 31 +} + +#[test] +fn signed_happy_path_i32() { + let a: i32 = -12 + let b: i32 = 10 + let c: i32 = 5 + let p: i32 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} + +// ===================================================================== +// u64 / i64 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u64() { + let x: u64 = 18446744073709551615 + let y: u64 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u64() { + let a: u64 = 0 + let b: u64 = 1 + let c: u64 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u64() { + let a: u64 = 4294967296 + let b: u64 = 4294967296 + let c: u64 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u64() { + let a: u64 = 1 + let b: u64 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u64() { + let a: u64 = 1 + let b: u64 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u64() { + let x: u64 = 2 + let y: u64 = x ** 64 +} + +#[test] +fn unsigned_happy_path_u64() { + let a: u64 = 12 + let b: u64 = 10 + let c: u64 = 5 + let p: u64 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i64() { + let x: i64 = 9223372036854775807 + let y: i64 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i64() { + let x: i64 = -9223372036854775808 + let y: i64 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i64() { + let min: i64 = -9223372036854775808 + let y: i64 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i64() { + let x: i64 = -9223372036854775808 + let y: i64 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i64() { + let a: i64 = 1 + let b: i64 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i64() { + let min: i64 = -9223372036854775808 + let y: i64 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i64() { + let a: i64 = 1 + let b: i64 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i64() { + let x: i64 = 2 + let y: i64 = x ** 63 +} + +#[test] +fn signed_happy_path_i64() { + let a: i64 = -12 + let b: i64 = 10 + let c: i64 = 5 + let p: i64 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} + +// ===================================================================== +// u128 / i128 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u128() { + let x: u128 = 340282366920938463463374607431768211455 + let y: u128 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u128() { + let a: u128 = 0 + let b: u128 = 1 + let c: u128 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u128() { + let a: u128 = 18446744073709551616 + let b: u128 = 18446744073709551616 + let c: u128 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u128() { + let a: u128 = 1 + let b: u128 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u128() { + let a: u128 = 1 + let b: u128 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u128() { + let x: u128 = 2 + let y: u128 = x ** 128 +} + +#[test] +fn unsigned_happy_path_u128() { + let a: u128 = 12 + let b: u128 = 10 + let c: u128 = 5 + let p: u128 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i128() { + let x: i128 = 170141183460469231731687303715884105727 + let y: i128 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i128() { + let x: i128 = -170141183460469231731687303715884105728 + let y: i128 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i128() { + let min: i128 = -170141183460469231731687303715884105728 + let y: i128 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i128() { + let x: i128 = -170141183460469231731687303715884105728 + let y: i128 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i128() { + let a: i128 = 1 + let b: i128 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i128() { + let min: i128 = -170141183460469231731687303715884105728 + let y: i128 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i128() { + let a: i128 = 1 + let b: i128 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i128() { + let x: i128 = 2 + let y: i128 = x ** 127 +} + +#[test] +fn signed_happy_path_i128() { + let a: i128 = -12 + let b: i128 = 10 + let c: i128 = 5 + let p: i128 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} + +// ===================================================================== +// u256 / i256 +// ===================================================================== + +#[test(should_revert)] +fn unsigned_add_overflow_u256() { + let x: u256 = 115792089237316195423570985008687907853269984665640564039457584007913129639935 + let y: u256 = x + 1 +} + +#[test(should_revert)] +fn unsigned_sub_underflow_u256() { + let a: u256 = 0 + let b: u256 = 1 + let c: u256 = a - b +} + +#[test(should_revert)] +fn unsigned_mul_overflow_u256() { + let a: u256 = 340282366920938463463374607431768211456 + let b: u256 = 340282366920938463463374607431768211456 + let c: u256 = a * b +} + +#[test(should_revert)] +fn unsigned_div_by_zero_u256() { + let a: u256 = 1 + let b: u256 = a / 0 +} + +#[test(should_revert)] +fn unsigned_rem_by_zero_u256() { + let a: u256 = 1 + let b: u256 = a % 0 +} + +#[test(should_revert)] +fn unsigned_pow_overflow_u256() { + let x: u256 = 2 + let y: u256 = x ** 256 +} + +#[test] +fn unsigned_happy_path_u256() { + let a: u256 = 12 + let b: u256 = 10 + let c: u256 = 5 + let p: u256 = 3 + assert(a + b == 22) + assert(a - b == 2) + assert(a * b == 120) + assert(a / c == 2) + assert(a % c == 2) + assert(p ** 4 == 81) +} + +#[test(should_revert)] +fn signed_add_overflow_i256() { + let x: i256 = 57896044618658097711785492504343953926634992332820282019728792003956564819967 + let y: i256 = x + 1 +} + +#[test(should_revert)] +fn signed_sub_overflow_i256() { + let x: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968 + let y: i256 = x - 1 +} + +#[test(should_revert)] +fn signed_mul_overflow_min_neg1_i256() { + let min: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968 + let y: i256 = min * -1 +} + +#[test(should_revert)] +fn signed_neg_overflow_i256() { + let x: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968 + let y: i256 = -x +} + +#[test(should_revert)] +fn signed_div_by_zero_i256() { + let a: i256 = 1 + let b: i256 = a / 0 +} + +#[test(should_revert)] +fn signed_div_overflow_min_neg1_i256() { + let min: i256 = -57896044618658097711785492504343953926634992332820282019728792003956564819968 + let y: i256 = min / -1 +} + +#[test(should_revert)] +fn signed_rem_by_zero_i256() { + let a: i256 = 1 + let b: i256 = a % 0 +} + +#[test(should_revert)] +fn signed_pow_overflow_i256() { + let x: i256 = 2 + let y: i256 = x ** 255 +} + +#[test] +fn signed_happy_path_i256() { + let a: i256 = -12 + let b: i256 = 10 + let c: i256 = 5 + let p: i256 = 3 + assert(a + b == -2) + assert(a - b == -22) + assert(a * b == -120) + assert(a / c == -2) + assert(a % c == -2) + assert(-a == 12) + assert(p ** 4 == 81) +} diff --git a/crates/fe/tests/fixtures/fe_test/checked_arithmetic_methods.fe b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_methods.fe new file mode 100644 index 0000000000..46a3a9d36e --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_methods.fe @@ -0,0 +1,56 @@ +use std::evm::effects::assert +use core::ops::{ + SaturatingAdd, SaturatingMul, SaturatingSub, WrappingAdd, WrappingMul, WrappingSub, +} + +// ===================================================================== +// Unsigned wrapping and saturating methods +// ===================================================================== + +#[test] +fn wrapping_unsigned_u8() { + let max: u8 = 255 + let zero: u8 = 0 + let sixteen: u8 = 16 + + assert(max.wrapping_add(1) == 0) + assert(zero.wrapping_sub(1) == 255) + assert(sixteen.wrapping_mul(sixteen) == 0) +} + +#[test] +fn saturating_unsigned_u8() { + let max: u8 = 255 + let zero: u8 = 0 + let sixteen: u8 = 16 + + assert(max.saturating_add(1) == 255) + assert(zero.saturating_sub(1) == 0) + assert(sixteen.saturating_mul(sixteen) == 255) +} + +// ===================================================================== +// Signed wrapping and saturating methods +// ===================================================================== + +#[test] +fn wrapping_signed_i8() { + let max: i8 = 127 + let min: i8 = -128 + let sixty_four: i8 = 64 + + assert(max.wrapping_add(1) == -128) + assert(min.wrapping_sub(1) == 127) + assert(sixty_four.wrapping_mul(4) == 0) +} + +#[test] +fn saturating_signed_i8() { + let max: i8 = 127 + let min: i8 = -128 + let sixty_four: i8 = 64 + + assert(max.saturating_add(1) == 127) + assert(min.saturating_sub(1) == -128) + assert(sixty_four.saturating_mul(4) == 127) +} diff --git a/crates/fe/tests/fixtures/fe_test/checked_arithmetic_regressions.fe b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_regressions.fe new file mode 100644 index 0000000000..4cec3c8e37 --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test/checked_arithmetic_regressions.fe @@ -0,0 +1,113 @@ +use std::evm::effects::assert + +fn add_assign_overflow_u8(v: mut u8) { + v += 1 +} + +fn sub_assign_underflow_u8(v: mut u8) { + v -= 1 +} + +fn mul_assign_overflow_u8(v: mut u8) { + v *= 16 +} + +fn div_assign_zero_u8(v: mut u8) { + v /= 0 +} + +fn rem_assign_zero_u8(v: mut u8) { + v %= 0 +} + +fn pow_assign_overflow_u8(v: mut u8) { + v **= 8 +} + +// ===================================================================== +// Assignment operator regressions +// ===================================================================== + +#[test(should_revert)] +fn add_assign_overflow_u8_reverts() { + let mut x: u8 = 255 + add_assign_overflow_u8(mut x) +} + +#[test(should_revert)] +fn sub_assign_underflow_u8_reverts() { + let mut x: u8 = 0 + sub_assign_underflow_u8(mut x) +} + +#[test(should_revert)] +fn mul_assign_overflow_u8_reverts() { + let mut x: u8 = 16 + mul_assign_overflow_u8(mut x) +} + +#[test(should_revert)] +fn div_assign_zero_u8_reverts() { + let mut x: u8 = 1 + div_assign_zero_u8(mut x) +} + +#[test(should_revert)] +fn rem_assign_zero_u8_reverts() { + let mut x: u8 = 1 + rem_assign_zero_u8(mut x) +} + +#[test(should_revert)] +fn pow_assign_overflow_u8_reverts() { + let mut x: u8 = 2 + pow_assign_overflow_u8(mut x) +} + +// ===================================================================== +// Expression-shape regressions +// ===================================================================== + +#[test(should_revert)] +fn signed_add_neg_overflow_i8() { + let a: i8 = -100 + let b: i8 = -100 + let c: i8 = a + b +} + +#[test(should_revert)] +fn signed_sub_pos_overflow_i8() { + let a: i8 = 100 + let b: i8 = -100 + let c: i8 = a - b +} + +#[test(should_revert)] +fn signed_mul_overflow_i8_literal_literal() { + let x: i8 = -1 * -128 +} + +#[test(should_revert)] +fn signed_mul_overflow_i8_lhs_literal() { + let min: i8 = -128 + let y: i8 = -1 * min +} + +#[test(should_revert)] +fn signed_mul_overflow_i8_rhs_literal() { + let min: i8 = -128 + let y: i8 = min * -1 +} + +#[test(should_revert)] +fn signed_pow_negative_exp_i8() { + let x: i8 = 2 + let y: i8 = x ** -1 +} + +#[test] +fn signed_mul_no_overflow_i8_neg_neg() { + let a: i8 = -6 + let b: i8 = -3 + assert(a * b == 18) +} diff --git a/crates/fe/tests/fixtures/fe_test/signed_arithmetic.fe b/crates/fe/tests/fixtures/fe_test/signed_arithmetic.fe new file mode 100644 index 0000000000..1bae24816b --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test/signed_arithmetic.fe @@ -0,0 +1,100 @@ +use std::evm::effects::assert + +// ===================================================================== +// Division and remainder semantics +// ===================================================================== + +#[test] +fn signed_div_i8_neg_by_pos() { + let a: i8 = -6 + let b: i8 = 3 + assert(a / b == -2) +} + +#[test] +fn signed_div_i8_pos_by_neg() { + let a: i8 = 6 + let b: i8 = -3 + assert(a / b == -2) +} + +#[test] +fn signed_div_i8_neg_by_neg() { + let a: i8 = -6 + let b: i8 = -3 + assert(a / b == 2) +} + +#[test] +fn signed_rem_i8_neg_by_pos() { + let a: i8 = -7 + let b: i8 = 3 + assert(a % b == -1) +} + +#[test] +fn signed_rem_i8_pos_by_neg() { + let a: i8 = 7 + let b: i8 = -3 + assert(a % b == 1) +} + +#[test] +fn signed_rem_i8_neg_by_neg() { + let a: i8 = -7 + let b: i8 = -3 + assert(a % b == -1) +} + +// ===================================================================== +// Comparisons +// ===================================================================== + +#[test] +fn signed_cmp_i8_uses_signed_order() { + let a: i8 = -1 + let b: i8 = 1 + assert(a < b) + assert((a > b) == false) + assert((a <= b) == true) + assert((a >= b) == false) +} + +#[test] +fn signed_cmp_i256_uses_signed_order() { + let a: i256 = -1 + let b: i256 = 1 + assert(a < b) + assert((a > b) == false) + assert((a <= b) == true) + assert((a >= b) == false) +} + +// ===================================================================== +// Right shift semantics +// ===================================================================== + +fn signed_shr_assign_i8(v: mut i8) { + v >>= 2 + assert(v == -4) +} + +#[test] +fn signed_shr_i8_negative() { + let a: i8 = -16 + let b: i8 = 2 + assert(a >> b == -4) +} + +#[test] +fn signed_shr_i8_minus_one() { + let a: i8 = -1 + let b: i8 = 4 + assert(a >> b == -1) +} + +#[test] +fn signed_shr_assign_i8_is_arithmetic() { + let mut x: i8 = -16 + signed_shr_assign_i8(mut x) +} diff --git a/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.fe b/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.fe new file mode 100644 index 0000000000..8022ab3ac4 --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.fe @@ -0,0 +1,47 @@ +#[test] +fn test_add_overflow_u8() { + let x: u8 = 255 + let y: u8 = x + 1 +} + +#[test] +fn test_aug_assign_overflow_u8() { + let mut x: u8 = 255 + x += 1 +} + +#[test] +fn test_div_by_zero_u8() { + let x: u8 = 1 + let y: u8 = x / 0 +} + +#[test] +fn test_rem_by_zero_u8() { + let x: u8 = 1 + let y: u8 = x % 0 +} + +#[test] +fn test_pow_overflow_u8() { + let x: u8 = 2 + let y: u8 = x ** 8 +} + +#[test] +fn test_neg_overflow_i8() { + let x: i8 = -128 + let y: i8 = -x +} + +#[test] +fn test_div_overflow_i8() { + let x: i8 = -128 + let y: i8 = x / -1 +} + +#[test] +fn test_pow_negative_exp_i8() { + let x: i8 = 2 + let y: i8 = x ** -1 +} diff --git a/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.snap b/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.snap new file mode 100644 index 0000000000..2d47c5889d --- /dev/null +++ b/crates/fe/tests/fixtures/fe_test_runner/checked_arithmetic_reverts.snap @@ -0,0 +1,37 @@ +--- +source: crates/fe/tests/cli_output.rs +assertion_line: 922 +expression: output +input_file: tests/fixtures/fe_test_runner/checked_arithmetic_reverts.fe +--- +=== STDOUT === +FAIL [