solidity
solidity copied to clipboard
yul optimizer: Expand rules for subtraction simplification
The previous rules would create awkward negative constants, turning all instances of sub(x, 1) into add(x, not(0)) for example. This change expands the four (A+X)+B type rules from ruleset 7 into 24 combinations of addition/subtraction with constants.
It improves code size and quality in most test cases (diff in a comment below), except where there is a code-size regression, because it tries too hard to hold small constants on the stack (e.g., 4 where previously it would materialize a new not(3) each time instead), and the code ends up with a bunch of extra pop instructions at the end. I assume this could be improved elsewhere in the optimizer.
These rules were generated by expanding the ones used for addition, handling the sign correctly in each case. I wrote a utility to double-check correctness and auto-generate the C++ code to prevent manual transcription errors: https://gist.github.com/a1k0n/74c46ee8821a71a5ea0d1005515653e8
Ah, looks like I need to update the --enforce-gas-cost tests...
I have no idea why the legacy optimizer is changed at all...?
| File name | IR-optimized (%) | Legacy-Optimized (%) | Legacy (%) |
|---|---|---|---|
| constructor_inheritance_init_order.sol | -0.355389 | 0 | 0 |
| constructor_inheritance_init_order_2.sol | -0.355389 | 0 | 0 |
| constructor_with_params.sol | -0.417266 | 0 | 0 |
| constructor_with_params_diamond_inheritance.sol | -0.419782 | 0 | 0 |
| constructor_with_params_inheritance.sol | -0.348438 | 0 | 0 |
| byte_array_to_storage_cleanup.sol | -0.62071 | 0 | 0 |
| abiEncoderV1/abi_decode_v2_storage.sol | -0.00344536 | 0 | 0 |
| abiEncoderV1/abi_encode_calldata_slice.sol | -0.0312448 | 0.790129 | 0 |
| abiEncoderV1/struct/struct_storage_ptr.sol | 0.00660561 | 0 | 0 |
| libraries/using_library_mappings_public.sol | 0.0100285 | 0 | 0 |
| libraries/using_library_mappings_return.sol | 0.00332585 | 0 | 0 |
| libraries/internal_types_in_library.sol | -0.0080156 | 0.0527426 | 0 |
| immutable/multi_creation.sol | -0.322903 | 0 | 0 |
| immutable/use_scratch.sol | -0.344286 | 0 | 0 |
| smoke/constructor.sol | -0.60559 | 0 | 0 |
| userDefinedValueType/erc20.sol | -0.395058 | 0 | 0 |
| userDefinedValueType/calldata.sol | -0.00491521 | 0.0146148 | 0 |
| functionCall/creation_function_call_with_salt.sol | -0.221061 | 0 | 0 |
| functionCall/external_call_to_nonexisting.sol | -0.1596 | 0 | 0 |
| functionCall/failed_create.sol | 3.67711 | 0.117054 | 0 |
| functionCall/creation_function_call_with_args.sol | -0.221246 | 0 | 0 |
| functionCall/gas_and_value_brace_syntax.sol | -0.741617 | 0 | 0 |
| functionCall/external_call_to_nonexisting_debugstrings.sol | -0.102408 | 0 | 0 |
| functionCall/gas_and_value_basic.sol | -0.741617 | 0 | 0 |
| functionCall/mapping_array_internal_argument.sol | -0.00268651 | 0 | 0 |
| externalContracts/deposit_contract.sol | -0.160283 | -0.0974623 | 0 |
| externalContracts/strings.sol | -0.294947 | 0.832174 | 0 |
| externalContracts/prbmath_signed.sol | -0.174763 | -0.0702974 | 0 |
| externalContracts/FixedFeeRegistrar.sol | -0.886485 | 0 | 0 |
| externalContracts/base64.sol | -0.273642 | 0.393186 | 0 |
| externalContracts/prbmath_unsigned.sol | -0.16234 | -0.0747815 | 0 |
| externalContracts/ramanujan_pi.sol | -0.145168 | 0.0449773 | 0 |
| inheritance/inherited_function_calldata_memory_interface.sol | 0.401491 | 0 | 0 |
| inheritance/value_for_constructor.sol | -0.241301 | 0 | 0 |
| various/value_complex.sol | -0.122575 | 0 | 0 |
| various/swap_in_storage_overwrite.sol | 0.00182325 | 0 | 0 |
| various/destructuring_assignment.sol | 0.00334602 | 0 | 0 |
| various/address_code.sol | 0.263652 | 0 | 0 |
| various/contract_binary_dependencies.sol | -0.427456 | 0 | 0 |
| various/erc20.sol | -0.483879 | 0 | 0 |
| various/staticcall_for_view_and_pure.sol | -3.04758e-06 | 0 | 0 |
| various/senders_balance.sol | -0.253184 | 0 | 0 |
| various/skip_dynamic_types_for_structs.sol | 0.00391856 | 0 | 0 |
| various/value_insane.sol | 0.36593 | 0 | 0 |
| array/create_memory_array.sol | -0.00238421 | 0 | 0 |
| array/bytes_length_member.sol | -0.00271734 | 0 | 0 |
| array/fixed_arrays_in_constructors.sol | -0.336742 | 0 | 0 |
| array/arrays_complex_from_and_to_storage.sol | -0.00160629 | 0 | 0 |
| array/function_array_cross_calls.sol | -0.159507 | -0.0712418 | 0 |
| array/byte_array_transitional_2.sol | -0.00890585 | -0.0049091 | 0 |
| array/constant_var_as_array_length.sol | -0.152563 | 0 | 0 |
| array/fixed_arrays_as_return_type.sol | -0.178918 | 0 | 0 |
| array/fixed_array_cleanup.sol | -0.000644551 | 0.012837 | 0 |
| array/dynamic_array_cleanup.sol | -0.000577349 | 0.0121875 | 0 |
| array/reusing_memory.sol | -0.185121 | 0 | 0 |
| array/dynamic_multi_array_cleanup.sol | 0.0016257 | 0 | 0 |
| array/dynamic_arrays_in_storage.sol | -0.00269179 | 0 | 0 |
| array/pop/array_pop_uint24_transition.sol | -0.000632875 | 0.117708 | 0 |
| array/pop/byte_array_pop_long_storage_empty.sol | -0.0681293 | 0.0200322 | 0 |
| array/pop/byte_array_pop_copy_long.sol | 0 | 0.0826286 | 0 |
| array/pop/byte_array_pop_masking_long.sol | -0.0157195 | 0.0758676 | 0 |
| array/pop/array_pop_uint16_transition.sol | -0.00643901 | 0.0807655 | 0 |
| array/pop/array_pop_array_transition.sol | 0.0164464 | 0.0127331 | 0 |
| array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol | 0.409425 | -0.0510999 | 0 |
| array/delete/bytes_delete_element.sol | -0.00144281 | 0.121254 | 0 |
| array/push/array_push_struct.sol | -0.00221887 | 0 | 0 |
| array/push/nested_bytes_push.sol | -0.00167436 | 0 | 0 |
| array/push/array_push.sol | -0.00269184 | 0 | 0 |
| array/push/push_no_args_bytes.sol | -0.0016341 | 0.117176 | 0 |
| array/push/byte_array_push_transition.sol | -0.136481 | 0 | 0 |
| array/push/push_no_args_2d.sol | -0.00786878 | 0.126487 | 0 |
| array/push/array_push_nested_from_calldata.sol | -0.00265882 | 0 | 0 |
| array/push/array_push_struct_from_calldata.sol | -0.00218831 | -0.00217355 | 0 |
| array/copying/array_copy_storage_storage_dynamic_dynamic.sol | -0.0010991 | 0 | 0 |
| array/copying/storage_memory_nested_struct.sol | -0.00103033 | 0 | 0 |
| array/copying/cleanup_during_multi_element_per_slot_copy.sol | -0.0910045 | 0 | 0 |
| array/copying/array_copy_storage_storage_struct.sol | -0.00125685 | 0.0227695 | 0 |
| array/copying/storage_memory_nested.sol | -0.00145642 | 0.00567478 | 0 |
| array/copying/array_nested_calldata_to_storage.sol | -0.00616198 | 0 | 0 |
| array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol | -0.0283711 | 0 | 0 |
| array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol | -0.0134244 | 0 | 0 |
| array/copying/array_of_struct_calldata_to_storage.sol | -0.00250543 | 0 | 0 |
| array/copying/copy_byte_array_to_storage.sol | -0.0025087 | 0 | 0 |
| array/copying/copy_removes_bytes_data.sol | -0.00169123 | 0 | 0 |
| array/copying/array_of_struct_memory_to_storage.sol | -0.00253391 | 0 | 0 |
| array/copying/array_copy_target_leftover.sol | -0.00240467 | 0.133992 | 0 |
| array/copying/array_of_function_external_storage_to_storage_dynamic.sol | -0.0133824 | 0 | 0 |
| array/copying/array_of_structs_containing_arrays_memory_to_storage.sol | -0.00164621 | 0 | 0 |
| array/copying/copy_byte_array_in_struct_to_storage.sol | -0.00208993 | 0 | 0 |
| array/copying/memory_dyn_2d_bytes_to_storage.sol | -0.0023406 | 0.0301988 | 0 |
| array/copying/storage_memory_nested_bytes.sol | -0.152745 | -0.000491553 | 0 |
| array/copying/copy_function_internal_storage_array.sol | -0.00979728 | 0 | 0 |
| array/copying/array_copy_storage_storage_different_base_nested.sol | -0.00158153 | 0 | 0 |
| array/copying/storage_memory_nested_from_pointer.sol | -0.00145642 | 0.00567464 | 0 |
| array/copying/array_copy_storage_storage_dyn_dyn.sol | -0.00269363 | 0 | 0 |
| array/copying/array_copy_target_simple.sol | -0.00102173 | 0.00894203 | 0 |
| array/copying/array_nested_memory_to_storage.sol | -0.000277818 | 0 | 0 |
| array/copying/bytes_storage_to_storage.sol | 1.20549 | 0.27568 | 0 |
| array/copying/array_copy_target_simple_2.sol | -0.00109819 | 0.00762497 | 0 |
| array/copying/array_copy_clear_storage.sol | -0.00223272 | 0 | 0 |
| array/copying/array_storage_multi_items_per_slot.sol | -0.00227388 | 0 | 0 |
| array/copying/bytes_inside_mappings.sol | 0.00347098 | 0 | 0 |
| array/copying/storage_memory_packed_dyn.sol | -0.00272393 | 0.0820188 | 0 |
| array/copying/copying_bytes_multiassign.sol | 0.0126324 | 0 | 0 |
| array/copying/array_copy_including_array.sol | -0.000525905 | 0.00117571 | 0 |
| array/copying/array_copy_storage_storage_static_static.sol | -0.00127076 | 0 | 0 |
| array/copying/function_type_array_to_storage.sol | -0.00954424 | -0.00512632 | 0 |
| array/copying/array_copy_storage_storage_different_base.sol | -0.00133317 | 0 | 0 |
| array/copying/array_copy_cleanup_uint40.sol | 0.00340284 | 0 | 0 |
| array/copying/array_copy_nested_array.sol | -0.000434929 | 0 | 0 |
| array/copying/calldata_array_dynamic_to_storage.sol | 0.00180227 | 0 | 0 |
| array/copying/array_copy_storage_storage_static_dynamic.sol | -0.00243619 | 0 | 0 |
| array/copying/array_copy_different_packing.sol | -0.00288255 | 0.0122349 | 0 |
| array/copying/array_copy_storage_to_memory_nested.sol | -0.00432694 | -0.000625176 | 0 |
| array/copying/array_copy_calldata_storage.sol | -0.000462732 | 0 | 0 |
| viaYul/array_storage_length_access.sol | -0.000246336 | 0 | 0 |
| viaYul/array_storage_index_zeroed_test.sol | -0.0136761 | 0.0387834 | 0 |
| viaYul/array_storage_push_empty_length_address.sol | -0.000308728 | 0 | 0 |
| viaYul/array_storage_push_empty.sol | -0.000546533 | 0.106111 | 0 |
| viaYul/copy_struct_invalid_ir_bug.sol | -0.00796467 | 0 | 0 |
| viaYul/array_storage_index_access.sol | -0.0237519 | 0.0347565 | 0 |
| viaYul/array_memory_index_access.sol | -0.0044255 | 1.02288 | 0 |
| viaYul/array_storage_index_boundary_test.sol | -0.00215987 | 0 | 0 |
| viaYul/array_storage_push_pop.sol | -0.191071 | 0 | 0 |
| calldata/copy_from_calldata_removes_bytes_data.sol | 0.00386703 | 0 | 0 |
| state/blockhash_basic.sol | -0.586404 | 0 | 0 |
| abiEncoderV2/calldata_array.sol | -0.0117098 | 0.807773 | 0 |
| abiEncoderV2/abi_encode_v2.sol | -0.00797731 | 0 | 0 |
| abiEncoderV2/storage_array_encoding.sol | -0.00886649 | 0 | 0 |
| abiEncoderV2/abi_encode_calldata_slice.sol | -0.0312448 | 0.790129 | 0 |
| abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol | -0.176417 | 0 | 0 |
| isoltestTesting/balance_other_contract.sol | -0.249558 | 0 | 0 |
| abiencodedecode/abi_decode_simple_storage.sol | -0.00220934 | 0 | 0 |
| structs/structs.sol | -0.00223159 | 0 | 0 |
| structs/struct_memory_to_storage_function_ptr.sol | -0.00271766 | 0 | 0 |
| structs/memory_structs_nested_load.sol | 0.00634478 | 0 | 0 |
| structs/struct_delete_storage_nested_small.sol | -0.00256189 | 0 | 0 |
| structs/struct_delete_storage_with_array.sol | -0.00246589 | 0 | 0 |
| structs/struct_delete_storage_with_arrays_small.sol | -0.00268832 | 0 | 0 |
| structs/struct_copy_via_local.sol | -0.00273438 | 0 | 0 |
| structs/struct_containing_bytes_copy_and_delete.sol | -0.00374254 | 0 | 0 |
| structs/struct_copy.sol | 0.00524875 | 0 | 0 |
| structs/copy_struct_array_from_storage.sol | -0.00199783 | 0 | 0 |
| structs/conversion/recursive_storage_memory.sol | -0.00154834 | 0 | 0 |
| structs/calldata/calldata_struct_with_nested_array_to_storage.sol | -0.0118321 | -0.0103138 | 0 |
| constructor/no_callvalue_check.sol | -0.00249892 | 0 | 0 |
| constructor/bytes_in_constructors_unpacker.sol | -0.158045 | 0 | 0 |
| constructor/arrays_in_constructors.sol | -0.23343 | 0 | 0 |
| constructor/constructor_static_array_argument.sol | -0.249786 | 0 | 0 |
| constructor/bytes_in_constructors_packer.sol | -0.355527 | 0 | 0 |
| constructor/constructor_arguments_external.sol | -0.405459 | 0 | 0 |
| events/event_dynamic_array_storage.sol | -0.00264278 | 0 | 0 |
| events/event_dynamic_array_storage_v2.sol | -0.00264278 | 0 | 0 |
| events/event_dynamic_nested_array_storage_v2.sol | 0.00432094 | -0.00162557 | 0 |
| events/event_indexed_string.sol | -0.000899607 | 0.0721075 | 0 |
| events/event_emit_from_other_contract.sol | -0.257244 | 0 | 0 |
| salted_create/salted_create_with_value.sol | -0.237942 | 0 | 0 |
| storage/packed_storage_structs_bytes.sol | -0.00226405 | 0 | 0 |
Diving into functionCall/failed_create.sol which is apparently 3% gassier...
Apparently it's just because of all the stack shuffling attempting to preserve a 4 on the stack in slot _2.
@@ -18,47 +18,48 @@
/// @src 0:40:335 "contract C {..."
let _1 := memoryguard(0x80)
mstore(64, _1)
- if iszero(lt(calldatasize(), 4))
+ let _2 := 4
+ if iszero(lt(calldatasize(), _2))
{
- let _2 := 0
- switch shr(224, calldataload(_2))
+ let _3 := 0
+ switch shr(224, calldataload(_3))
case 0x0c55699c {
- if callvalue() { revert(_2, _2) }
- if slt(add(calldatasize(), not(3)), _2) { revert(_2, _2) }
- mstore(_1, sload(_2))
+ if callvalue() { revert(_3, _3) }
+ if slt(sub(calldatasize(), _2), _3) { revert(_3, _3) }
+ mstore(_1, sload(_3))
return(_1, 32)
}
case 0xb3de648b {
- if callvalue() { revert(_2, _2) }
- if slt(add(calldatasize(), not(3)), 32) { revert(_2, _2) }
- let _3 := sload(_2)
- if eq(_3, not(0))
- {
- mstore(_2, shl(224, 0x4e487b71))
- mstore(4, 0x11)
- revert(_2, 0x24)
+ if callvalue() { revert(_3, _3) }
+ if slt(sub(calldatasize(), _2), 32) { revert(_3, _3) }
+ let _4 := sload(_3)
+ if eq(_4, not(0))
+ {
+ mstore(_3, shl(224, 0x4e487b71))
+ mstore(_2, 0x11)
+ revert(_3, 0x24)
}
- sstore(_2, add(_3, 1))
+ sstore(_3, add(_4, 1))
/// @src 0:157:181 "(new D){value: amount}()"
- let _4 := /** @src 0:40:335 "contract C {..." */ mload(64)
+ let _5 := /** @src 0:40:335 "contract C {..." */ mload(64)
/// @src 0:157:181 "(new D){value: amount}()"
- let _5 := datasize("D_5")
- let _6 := add(_4, _5)
- if or(gt(_6, 0xffffffffffffffff), lt(_6, _4))
+ let _6 := datasize("D_5")
+ let _7 := add(_5, _6)
+ if or(gt(_7, 0xffffffffffffffff), lt(_7, _5))
{
/// @src 0:40:335 "contract C {..."
- mstore(_2, shl(224, 0x4e487b71))
- mstore(4, 0x41)
- revert(_2, 0x24)
+ mstore(_3, shl(224, 0x4e487b71))
+ mstore(_2, 0x41)
+ revert(_3, 0x24)
}
/// @src 0:157:181 "(new D){value: amount}()"
- datacopy(_4, dataoffset("D_5"), _5)
- let expr_address := create(/** @src 0:40:335 "contract C {..." */ calldataload(4), /** @src 0:157:181 "(new D){value: amount}()" */ _4, sub(_6, _4))
+ datacopy(_5, dataoffset("D_5"), _6)
+ let expr_address := create(/** @src 0:40:335 "contract C {..." */ calldataload(_2), /** @src 0:157:181 "(new D){value: amount}()" */ _5, sub(_7, _5))
if iszero(expr_address)
{
/// @src 0:40:335 "contract C {..."
let pos := mload(64)
- returndatacopy(pos, _2, returndatasize())
+ returndatacopy(pos, _3, returndatasize())
revert(pos, returndatasize())
}
let memPos := mload(64)
@@ -67,8 +68,8 @@
return(memPos, 32)
}
case 0xdc9031c4 {
- if slt(add(calldatasize(), not(3)), 32) { revert(_2, _2) }
- let ret := fun_stack(calldataload(4))
+ if slt(sub(calldatasize(), _2), 32) { revert(_3, _3) }
+ let ret := fun_stack(calldataload(_2))
let memPos_1 := mload(64)
mstore(memPos_1, and(ret, sub(shl(160, /** @src 0:157:181 "(new D){value: amount}()" */ 1), 1)))
/// @src 0:40:335 "contract C {..."
@@ -136,7 +137,7 @@
let _6 := /** @src 0:40:335 "contract C {..." */ mload(64)
/// @src 0:276:297 "this.stack(depth - 1)"
mstore(_6, /** @src 0:40:335 "contract C {..." */ shl(226, 0x37240c71))
- mstore(/** @src 0:276:297 "this.stack(depth - 1)" */ add(_6, 4), /** @src 0:40:335 "contract C {..." */ add(var_depth, not(0)))
+ mstore(/** @src 0:276:297 "this.stack(depth - 1)" */ add(_6, 4), /** @src 0:40:335 "contract C {..." */ sub(var_depth, /** @src 0:295:296 "1" */ 0x01))
/// @src 0:263:264 "0"
let _7 := 0x00
/// @src 0:276:297 "this.stack(depth - 1)"
Rebased
Updated diffstats
| File name | IR-optimized (%) | Legacy-Optimized (%) | Legacy (%) |
|---|---|---|---|
| constructor_inheritance_init_order.sol | -0.355389 | 0 | 0 |
| constructor_inheritance_init_order_2.sol | -0.355389 | 0 | 0 |
| constructor_with_params.sol | -0.417266 | 0 | 0 |
| constructor_with_params_diamond_inheritance.sol | -0.419877 | 0 | 0 |
| constructor_with_params_inheritance.sol | -0.348483 | 0 | 0 |
| byte_array_to_storage_cleanup.sol | -0.62071 | 0 | 0 |
| abiEncoderV1/abi_decode_v2_storage.sol | -0.00344536 | 0 | 0 |
| abiEncoderV1/abi_encode_calldata_slice.sol | -0.0312448 | 0.790129 | 0 |
| abiEncoderV1/struct/struct_storage_ptr.sol | 0.00660561 | 0 | 0 |
| libraries/using_library_mappings_public.sol | 0.0100285 | 0 | 0 |
| libraries/using_library_mappings_return.sol | 0.00332585 | 0 | 0 |
| libraries/internal_types_in_library.sol | -0.0080156 | 0.0527426 | 0 |
| immutable/multi_creation.sol | -0.322903 | 0 | 0 |
| immutable/use_scratch.sol | -0.344286 | 0 | 0 |
| smoke/constructor.sol | -0.60559 | 0 | 0 |
| userDefinedValueType/erc20.sol | 0.97444 | 0 | 0 |
| userDefinedValueType/calldata.sol | -0.00491521 | 0.0146148 | 0 |
| functionCall/creation_function_call_with_salt.sol | -0.221061 | 0 | 0 |
| functionCall/external_call_to_nonexisting.sol | -0.155297 | 0 | 0 |
| functionCall/failed_create.sol | 3.68142 | 0.117629 | 0 |
| functionCall/creation_function_call_with_args.sol | -0.221246 | 0 | 0 |
| functionCall/gas_and_value_brace_syntax.sol | -0.741617 | 0 | 0 |
| functionCall/external_call_to_nonexisting_debugstrings.sol | -0.10083 | 0 | 0 |
| functionCall/gas_and_value_basic.sol | -0.741617 | 0 | 0 |
| functionCall/mapping_array_internal_argument.sol | -0.00268651 | 0 | 0 |
| externalContracts/deposit_contract.sol | -0.137585 | -0.0978375 | 0 |
| externalContracts/strings.sol | -0.188338 | 0.818732 | 0 |
| externalContracts/prbmath_signed.sol | -0.174984 | -0.0703374 | 0 |
| externalContracts/FixedFeeRegistrar.sol | -0.886485 | 0 | 0 |
| externalContracts/base64.sol | -0.275046 | 0.391323 | 0 |
| externalContracts/prbmath_unsigned.sol | -0.162481 | -0.0748272 | 0 |
| externalContracts/ramanujan_pi.sol | -0.153277 | 0.0454888 | 0 |
| inheritance/inherited_function_calldata_memory_interface.sol | 0.401491 | 0 | 0 |
| inheritance/value_for_constructor.sol | -0.241301 | 0 | 0 |
| various/value_complex.sol | -0.122725 | 0 | 0 |
| various/swap_in_storage_overwrite.sol | 0.00182325 | 0 | 0 |
| various/destructuring_assignment.sol | 0.00334602 | 0 | 0 |
| various/address_code.sol | 0.263652 | 0 | 0 |
| various/contract_binary_dependencies.sol | -0.427456 | 0 | 0 |
| various/erc20.sol | -0.483024 | 0 | 0 |
| various/staticcall_for_view_and_pure.sol | -3.04758e-06 | 0 | 0 |
| various/senders_balance.sol | -0.253184 | 0 | 0 |
| various/skip_dynamic_types_for_structs.sol | 0.00391856 | 0 | 0 |
| various/value_insane.sol | 0.366377 | 0 | 0 |
| array/create_memory_array.sol | -0.00238421 | 0 | 0 |
| array/bytes_length_member.sol | -0.00271734 | 0 | 0 |
| array/fixed_arrays_in_constructors.sol | -0.336742 | 0 | 0 |
| array/arrays_complex_from_and_to_storage.sol | -0.00160629 | 0 | 0 |
| array/function_array_cross_calls.sol | -0.159507 | -0.0712418 | 0 |
| array/byte_array_transitional_2.sol | -0.00890585 | -0.0049091 | 0 |
| array/constant_var_as_array_length.sol | -0.152563 | 0 | 0 |
| array/fixed_arrays_as_return_type.sol | -0.178918 | 0 | 0 |
| array/fixed_array_cleanup.sol | -0.000644634 | 0.0128342 | 0 |
| array/dynamic_array_cleanup.sol | -0.000577489 | 0.0121851 | 0 |
| array/reusing_memory.sol | -0.185121 | 0 | 0 |
| array/dynamic_multi_array_cleanup.sol | 0.0016257 | 0 | 0 |
| array/dynamic_arrays_in_storage.sol | -0.00269179 | 0 | 0 |
| array/pop/array_pop_uint24_transition.sol | -0.00379699 | 0.117696 | 0 |
| array/pop/byte_array_pop_long_storage_empty.sol | -0.0698423 | 0.0204726 | 0 |
| array/pop/byte_array_pop_copy_long.sol | 0 | 0.0826286 | 0 |
| array/pop/byte_array_pop_masking_long.sol | -0.0157195 | 0.0758676 | 0 |
| array/pop/array_pop_uint16_transition.sol | -0.0048291 | 0.0807546 | 0 |
| array/pop/array_pop_array_transition.sol | 0.0161832 | 0.012733 | 0 |
| array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol | 0.409425 | -0.0510999 | 0 |
| array/delete/bytes_delete_element.sol | -0.00144281 | 0.121254 | 0 |
| array/push/array_push_struct.sol | -0.00221887 | 0 | 0 |
| array/push/nested_bytes_push.sol | -0.00167436 | 0 | 0 |
| array/push/array_push.sol | -0.00269184 | 0 | 0 |
| array/push/push_no_args_bytes.sol | -0.0016341 | 0.117176 | 0 |
| array/push/byte_array_push_transition.sol | -0.136108 | 0 | 0 |
| array/push/push_no_args_2d.sol | -0.00786878 | 0.126487 | 0 |
| array/push/array_push_nested_from_calldata.sol | -0.00265882 | 0 | 0 |
| array/push/array_push_struct_from_calldata.sol | -0.00218831 | -0.00217355 | 0 |
| array/copying/array_copy_storage_storage_dynamic_dynamic.sol | -0.0010991 | 0 | 0 |
| array/copying/storage_memory_nested_struct.sol | -0.00103033 | 0 | 0 |
| array/copying/cleanup_during_multi_element_per_slot_copy.sol | -0.0910045 | 0 | 0 |
| array/copying/array_copy_storage_storage_struct.sol | -0.00125685 | 0.0227695 | 0 |
| array/copying/storage_memory_nested.sol | -0.00145642 | 0.00567478 | 0 |
| array/copying/array_nested_calldata_to_storage.sol | -0.00616185 | 0 | 0 |
| array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol | -0.0283711 | 0 | 0 |
| array/copying/array_of_function_external_storage_to_storage_dynamic_different_mutability.sol | -0.0134244 | 0 | 0 |
| array/copying/array_of_struct_calldata_to_storage.sol | -0.00250543 | 0 | 0 |
| array/copying/copy_byte_array_to_storage.sol | -0.0025087 | 0 | 0 |
| array/copying/copy_removes_bytes_data.sol | -0.00169123 | 0 | 0 |
| array/copying/array_of_struct_memory_to_storage.sol | -0.00253391 | 0 | 0 |
| array/copying/array_copy_target_leftover.sol | -0.00240352 | 0.133984 | 0 |
| array/copying/array_of_function_external_storage_to_storage_dynamic.sol | -0.0133824 | 0 | 0 |
| array/copying/array_of_structs_containing_arrays_memory_to_storage.sol | -0.00164621 | 0 | 0 |
| array/copying/copy_byte_array_in_struct_to_storage.sol | -0.00208993 | 0 | 0 |
| array/copying/memory_dyn_2d_bytes_to_storage.sol | -0.0023406 | 0.0301988 | 0 |
| array/copying/storage_memory_nested_bytes.sol | -0.152745 | -0.000491553 | 0 |
| array/copying/copy_function_internal_storage_array.sol | -0.00979728 | 0 | 0 |
| array/copying/array_copy_storage_storage_different_base_nested.sol | -0.00158153 | 0 | 0 |
| array/copying/storage_memory_nested_from_pointer.sol | -0.00145642 | 0.00567464 | 0 |
| array/copying/array_copy_storage_storage_dyn_dyn.sol | -0.00269363 | 0 | 0 |
| array/copying/array_copy_target_simple.sol | -0.00102173 | 0.00894203 | 0 |
| array/copying/array_nested_memory_to_storage.sol | -0.000277809 | 0 | 0 |
| array/copying/bytes_storage_to_storage.sol | 1.20549 | 0.27568 | 0 |
| array/copying/array_copy_target_simple_2.sol | -0.00109819 | 0.00762497 | 0 |
| array/copying/array_copy_clear_storage.sol | -0.00223272 | 0 | 0 |
| array/copying/array_storage_multi_items_per_slot.sol | -0.00227388 | 0 | 0 |
| array/copying/bytes_inside_mappings.sol | 0.00347098 | 0 | 0 |
| array/copying/storage_memory_packed_dyn.sol | -0.00272393 | 0.0820188 | 0 |
| array/copying/copying_bytes_multiassign.sol | 0.0126324 | 0 | 0 |
| array/copying/array_copy_including_array.sol | -0.000525905 | 0.00117571 | 0 |
| array/copying/array_copy_storage_storage_static_static.sol | -0.00127076 | 0 | 0 |
| array/copying/function_type_array_to_storage.sol | -0.00954424 | -0.00512632 | 0 |
| array/copying/array_copy_storage_storage_different_base.sol | -0.00133317 | 0 | 0 |
| array/copying/array_copy_cleanup_uint40.sol | 0.00340284 | 0 | 0 |
| array/copying/array_copy_nested_array.sol | -0.000434929 | 0 | 0 |
| array/copying/calldata_array_dynamic_to_storage.sol | 0.00180227 | 0 | 0 |
| array/copying/array_copy_storage_storage_static_dynamic.sol | -0.00243619 | 0 | 0 |
| array/copying/array_copy_different_packing.sol | -0.00288255 | 0.0122349 | 0 |
| array/copying/array_copy_storage_to_memory_nested.sol | -0.00432694 | -0.000625176 | 0 |
| array/copying/array_copy_calldata_storage.sol | -0.000462732 | 0 | 0 |
| viaYul/array_storage_length_access.sol | -0.000246336 | 0 | 0 |
| viaYul/array_storage_index_zeroed_test.sol | -0.0136779 | 0.0387749 | 0 |
| viaYul/array_storage_push_empty_length_address.sol | -0.000308728 | 0 | 0 |
| viaYul/array_storage_push_empty.sol | -0.000546533 | 0.106111 | 0 |
| viaYul/copy_struct_invalid_ir_bug.sol | -0.00796467 | 0 | 0 |
| viaYul/array_storage_index_access.sol | -0.0237519 | 0.0347364 | 0 |
| viaYul/array_memory_index_access.sol | -0.0044253 | 1.00573 | 0 |
| viaYul/array_storage_index_boundary_test.sol | -0.00215987 | 0 | 0 |
| viaYul/array_storage_push_pop.sol | -0.191071 | 0 | 0 |
| calldata/copy_from_calldata_removes_bytes_data.sol | 0.00386703 | 0 | 0 |
| state/blockhash_basic.sol | -0.586404 | 0 | 0 |
| abiEncoderV2/calldata_array.sol | -0.0117098 | 0.807773 | 0 |
| abiEncoderV2/abi_encode_v2.sol | -0.00797731 | 0 | 0 |
| abiEncoderV2/storage_array_encoding.sol | -0.00886649 | 0 | 0 |
| abiEncoderV2/abi_encode_calldata_slice.sol | -0.0312448 | 0.790129 | 0 |
| abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol | -0.176417 | 0 | 0 |
| isoltestTesting/balance_other_contract.sol | -0.249558 | 0 | 0 |
| abiencodedecode/abi_decode_simple_storage.sol | -0.00220934 | 0 | 0 |
| structs/structs.sol | -0.00223159 | 0 | 0 |
| structs/struct_memory_to_storage_function_ptr.sol | -0.00271766 | 0 | 0 |
| structs/memory_structs_nested_load.sol | 0.00634478 | 0 | 0 |
| structs/struct_delete_storage_nested_small.sol | -0.00256189 | 0 | 0 |
| structs/struct_delete_storage_with_array.sol | -0.00246589 | 0 | 0 |
| structs/struct_delete_storage_with_arrays_small.sol | -0.00268832 | 0 | 0 |
| structs/struct_copy_via_local.sol | -0.00273438 | 0 | 0 |
| structs/struct_containing_bytes_copy_and_delete.sol | -0.00374254 | 0 | 0 |
| structs/struct_copy.sol | 0.00524875 | 0 | 0 |
| structs/copy_struct_array_from_storage.sol | -0.00199783 | 0 | 0 |
| structs/conversion/recursive_storage_memory.sol | -0.00154834 | 0 | 0 |
| structs/calldata/calldata_struct_with_nested_array_to_storage.sol | -0.0118321 | -0.0103138 | 0 |
| constructor/no_callvalue_check.sol | -0.00249892 | 0 | 0 |
| constructor/bytes_in_constructors_unpacker.sol | -0.158045 | 0 | 0 |
| constructor/arrays_in_constructors.sol | -0.23343 | 0 | 0 |
| constructor/constructor_static_array_argument.sol | -0.249786 | 0 | 0 |
| constructor/bytes_in_constructors_packer.sol | -0.355527 | 0 | 0 |
| constructor/constructor_arguments_external.sol | -0.405459 | 0 | 0 |
| events/event_dynamic_array_storage.sol | -0.00264285 | 0 | 0 |
| events/event_dynamic_array_storage_v2.sol | -0.00264285 | 0 | 0 |
| events/event_dynamic_nested_array_storage_v2.sol | 0.00108023 | -0.00162543 | 0 |
| events/event_indexed_string.sol | -0.000899607 | 0.0721075 | 0 |
| events/event_emit_from_other_contract.sol | -0.257244 | 0 | 0 |
| salted_create/salted_create_with_value.sol | -0.22781 | 0 | 0 |
| storage/packed_storage_structs_bytes.sol | -0.00226405 | 0 | 0 |
The regressions on the byte array loops appear to be due to a coincidence that loops have a built-in let loopEnd := and(newLen, not(31)) and the not(31) was previously being materalized from a array_allocation_size_bytes(value) - 32 expression; it would add not(31) to dataSize instead of subtracting 32 from it, and then was able to re-ise that not(31).
Huh, I guess this actually does break chainlink somehow, too.
I have no idea why the legacy optimizer is changed at all...?
Some bits in the legacy codegen are implemented by inserting Yul code compiled with the new pipeline. Most prominently the ABI encoding/decoding but also some cases of copying to storage. So this is normal.
Huh, I guess this actually does break chainlink somehow, too.
I think it's an upstream change. I mean, changes in the optimizer could break it but I just saw the same failure in another PR so I strongly suspect that it's not it.
The main idea of the restricted rules was to eliminate subtraction to bring all arithmetics into a normal form that uses as little subtraction as possible.
It would be nice if the rules here could be either be (1) simpler, (2) auto-generated or (3) auto-checked (as part of the CI).
It would be nice if the rules here could be either be (1) simpler, (2) auto-generated or (3) auto-checked (as part of the CI).
Agreed. I'll see what I can do.
Thank you for the PR! Unfortunately review has shown that the PR actually does the opposite of what the compiler is trying to do by design. Therefore, I'm closing it for now. Please don't hesitate and reopen it (or a new one) if it does something different.