diff --git a/libsolutil/CommonData.h b/libsolutil/CommonData.h index b33231a32..48f715171 100644 --- a/libsolutil/CommonData.h +++ b/libsolutil/CommonData.h @@ -52,6 +52,21 @@ template std::vector& operator+=(std::vector& _a, U&& _ std::move(_b.begin(), _b.end(), std::back_inserter(_a)); return _a; } + +/// Concatenate the contents of a container onto a list +template std::list& operator+=(std::list& _a, U& _b) +{ + for (auto const& i: _b) + _a.push_back(T(i)); + return _a; +} +/// Concatenate the contents of a container onto a list, move variant. +template std::list& operator+=(std::list& _a, U&& _b) +{ + std::move(_b.begin(), _b.end(), std::back_inserter(_a)); + return _a; +} + /// Concatenate the contents of a container onto a multiset template std::multiset& operator+=(std::multiset& _a, U& _b) { @@ -295,6 +310,50 @@ decltype(auto) mapTuple(Callable&& _callable) return detail::MapTuple{std::forward(_callable)}; } +namespace detail +{ + +template +auto findOffset(Container&& _container, Value&& _value, int) +-> decltype(_container.find(_value) == _container.end(), std::optional()) +{ + auto it = _container.find(std::forward(_value)); + auto end = _container.end(); + if (it == end) + return std::nullopt; + return std::distance(it, end); +} +template +auto findOffset(Range&& _range, Value&& _value, void*) +-> decltype(std::find(std::begin(_range), std::end(_range), std::forward(_value)) == std::end(_range), std::optional()) +{ + auto begin = std::begin(_range); + auto end = std::end(_range); + auto it = std::find(begin, end, std::forward(_value)); + if (it == end) + return std::nullopt; + return std::distance(begin, it); +} + +} + +template +auto findOffset(Range&& _range, std::remove_reference_t const& _value) +-> decltype(detail::findOffset(std::forward(_range), _value, 0)) +{ + return detail::findOffset(std::forward(_range), _value, 0); +} + +template +std::optional findOffsetPred(Range&& _range, Pred _pred) +{ + auto begin = std::begin(_range); + auto end = std::end(_range); + auto it = std::find_if(begin, end, _pred); + if (it == end) + return std::nullopt; + return std::distance(begin, it); +} // String conversion functions, mainly to/from hex/nibble/byte representations. diff --git a/libsolutil/Permutations.h b/libsolutil/Permutations.h new file mode 100644 index 000000000..b3455ddf1 --- /dev/null +++ b/libsolutil/Permutations.h @@ -0,0 +1,228 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +#pragma once +#include +#include +#include +#include + +namespace solidity::util +{ + +// TODO: This is currently only used for permuteDup as special case handling, which is not the best way to do things. +// Not worth spending time reviewing this. +template +void permute(unsigned _n, GetTargetPosition _getTargetPosition, Swap _swap, Pop _pop) +{ + static_assert( + std::is_same_v, int>, + "_getTargetPosition needs to have the signature int(unsigned)" + ); + static_assert( + std::is_same_v, void>, + "_swap needs to have the signature void(unsigned)" + ); + static_assert( + std::is_same_v, void>, + "_pop needs to have the signature void()" + ); + if (_n == 0) return; + int targetPositionTop = _getTargetPosition(_n - 1); + + if (targetPositionTop < 0) + { + // The last element should not be kept. + // Pop it and recurse. + _pop(); + permute(_n - 1, _getTargetPosition, _swap, _pop); + return; + } + // TODO: exception? + // assertThrow(static_cast(targetPositionTop) < _n, langutil::InternalCompilerError, "Invalid permutation."); + if (static_cast(targetPositionTop) == _n - 1) + { + // The last element is in position. + // Search for the deepest element that is not in position. + // If there is none, we are done. Otherwise swap it up and recurse. + for (int i = 0; i < static_cast(_n - 1); ++i) + if (_getTargetPosition(static_cast(i)) != i) + { + _swap(_n - static_cast(i) - 1); + permute(_n, _getTargetPosition, _swap, _pop); + return; + } + } + else + { + // The last element is not in position. + // Move it to its position and recurse. + _swap(_n - static_cast(targetPositionTop) - 1); + permute(_n, _getTargetPosition, _swap, _pop); + } +} + +// TODO: This is now only used in StackLayoutGenerator.cpp in ``createIdealLayout`` and that usage is actually abuse, +// since it provides "invalid" target positions (it works, but it's not soundly specified). +// Hence ``createIdealLayout`` should rather be rewritten properly and it does not make much sense to review +// this in detail. +template +void permuteDup(unsigned _n, GetTargetPositions _getTargetPositions, Swap _swap, Dup _dup, Push _push, Pop _pop, bool _debug = false) +{ + static_assert( + std::is_same_v, std::set>, + "_getTargetPosition needs to have the signature std::vector(unsigned)" + ); + static_assert( + std::is_same_v, void>, + "_swap needs to have the signature void(unsigned)" + ); + static_assert( + std::is_same_v, void>, + "_dup needs to have the signature void(unsigned)" + ); + static_assert( + std::is_same_v, void>, + "_push needs to have the signature void()" + ); + static_assert( + std::is_same_v, void>, + "_pop needs to have the signature void()" + ); + if (_n == 0) return; + + if (_debug) + { + for (auto offset: ranges::views::iota(0u, _n)) + { + auto targetPositions = _getTargetPositions(offset); + std::cout << "{ "; + for (auto pos: targetPositions) + std::cout << pos << " "; + std::cout << "} "; + } + std::cout << std::endl; + } + + std::set targetPositionsTop = _getTargetPositions(_n - 1); + + if (targetPositionsTop.empty()) + { + // The last element should not be kept. + // Pop it and recurse. + _pop(); + permuteDup(_n - 1, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + } + if (targetPositionsTop.count(_n - 1)) + { + if (_debug) + std::cout << "Top position should stay" << std::endl; + // The last element should remain at the top (but potentially also be dupped). + /*if (targetPositionsTop.size() > 1) + { + std::cout << "TOP targets: { "; + for (auto i: targetPositionsTop) + std::cout << i << " "; + std::cout << "}" << std::endl; + // The last element should remain at the top and be dupped. Dup it and recurse. + _dup(1); + permuteDup(_n + 1, _getTargetPositions, _swap, _dup, _push, _pop); + return; + } + else*/ + { + if (_debug) + std::cout << "Look for deeper element to be dupped." << std::endl; + // The last element should *only* exist at the current top. + // Look for the deepest element that should still be dupped. + for (auto offset: ranges::views::iota(0u, _n)) + { + auto targetPositions = _getTargetPositions(offset); + if (targetPositions.size() > 1) + { + if (_debug) + std::cout << "DUP element " << offset << " (DUP" << (_n - offset) << ")" << std::endl; + // Dup it, adjust the target positions and recurse. + // The next recursion will move the duplicate in place. + _dup(_n - offset); + permuteDup(_n + 1, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + } + } + // There is no more dupping requested, so we can switch to the non-dupping version. + permute(_n, [&](unsigned _i) -> int { + auto const& targetPositions = _getTargetPositions(_i); + if (targetPositions.empty()) + return -1; + else + { + assertThrow(targetPositions.size() == 1, langutil::InternalCompilerError, ""); + return static_cast(*targetPositions.begin()); + } + }, _swap, _pop); + return; + } + } + else + { + // The last element should end up at *some* position that isn't its current one. + auto topTargetPos = *targetPositionsTop.begin(); + if (_debug) + std::cout << "Top target pos: " << topTargetPos << std::endl; + if (topTargetPos < _n - 1) + { + // If the element is supposed to exist anywhere deeper than the current top, swap it there and recurse. + _swap(_n - static_cast(topTargetPos) - 1); + permuteDup(_n, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + } + else + { + // If there is an element that is supposed to be dupped to the current top position. Find it, dup it and recurse. + for (auto offset: ranges::views::iota(0u, _n)) + { + auto targetPositions = _getTargetPositions(offset); + if (targetPositions.size() > 1 && targetPositions.count(static_cast(_n))) + { + _dup(static_cast(targetPositions.size() - offset)); + permuteDup(_n + 1, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + } + } + // If there is any other element that is supposed to be dupped. Find it, dup it and recurse. + for (auto offset: ranges::views::iota(0u, _n)) + { + auto targetPositions = _getTargetPositions(offset); + if (targetPositions.size() > 1) + { + _dup(static_cast(targetPositions.size() - offset)); + permuteDup(_n + 1, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + } + } + // There must be a new element requested. Request it to be pushed and recurse. + _push(); + permuteDup(_n + 1, _getTargetPositions, _swap, _dup, _push, _pop, _debug); + return; + + assertThrow(false, langutil::InternalCompilerError, "Invalid permutation."); + } + } +} + +} diff --git a/libsolutil/cxx20.h b/libsolutil/cxx20.h index c65b0454b..b67f1a868 100644 --- a/libsolutil/cxx20.h +++ b/libsolutil/cxx20.h @@ -49,6 +49,32 @@ erase_if(std::unordered_map& _c, Pred _pred) return old_size - _c.size(); } +// Taken from https://en.cppreference.com/w/cpp/container/set/erase_if +template +typename std::set::size_type +erase_if(std::set& c, Pred pred) +{ + auto old_size = c.size(); + for (auto i = c.begin(), last = c.end(); i != last;) + if (pred(*i)) + i = c.erase(i); + else + ++i; + return static_cast::size_type>(old_size - c.size()); +} + + +// Taken from https://en.cppreference.com/w/cpp/container/deque/erase2 +template +typename std::deque::size_type +erase_if(std::deque& c, Pred pred) +{ + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = std::distance(it, c.end()); + c.erase(it, c.end()); + return static_cast::size_type>(r); +} + // Taken from https://en.cppreference.com/w/cpp/container/vector/erase2 template constexpr typename std::vector::size_type diff --git a/libyul/AST.h b/libyul/AST.h index 54d44f6ae..486e11faa 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -83,18 +83,16 @@ struct Continue { std::shared_ptr debugData; }; /// Leave statement (valid within function) struct Leave { std::shared_ptr debugData; }; -struct LocationExtractor -{ - template langutil::SourceLocation operator()(T const& _node) const - { - return _node.debugData ? _node.debugData->location : langutil::SourceLocation{}; - } -}; - /// Extracts the source location from a Yul node. template inline langutil::SourceLocation locationOf(T const& _node) { - return std::visit(LocationExtractor(), _node); + return _node.debugData ? _node.debugData->location : langutil::SourceLocation{}; +} + +/// Extracts the source location from a Yul node. +template inline langutil::SourceLocation locationOf(std::variant const& _node) +{ + return std::visit([](auto const& _arg) { return locationOf(_arg); }, _node); } struct DebugDataExtractor diff --git a/libyul/AssemblyStack.h b/libyul/AssemblyStack.h index 9b9f5b406..1cfdfcc1d 100644 --- a/libyul/AssemblyStack.h +++ b/libyul/AssemblyStack.h @@ -113,9 +113,9 @@ public: private: bool analyzeParsed(); bool analyzeParsed(yul::Object& _object); - +public: void compileEVM(yul::AbstractAssembly& _assembly, bool _optimize) const; - +private: void optimize(yul::Object& _object, bool _isCreation); Language m_language = Language::Assembly; diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt index c72f105f9..403c208a1 100644 --- a/libyul/CMakeLists.txt +++ b/libyul/CMakeLists.txt @@ -68,6 +68,11 @@ add_library(yul backends/evm/EVMMetrics.h backends/evm/NoOutputAssembly.h backends/evm/NoOutputAssembly.cpp + backends/evm/OptimizedEVMCodeTransform.cpp + backends/evm/OptimizedEVMCodeTransform.h + backends/evm/StackHelpers.h + backends/evm/StackLayoutGenerator.cpp + backends/evm/StackLayoutGenerator.h backends/evm/VariableReferenceCounter.h backends/evm/VariableReferenceCounter.cpp backends/wasm/EVMToEwasmTranslator.cpp diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index 90e5b2815..7985ae939 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -55,7 +55,7 @@ void visitArguments( for (auto const& arg: _call.arguments | ranges::views::reverse) _visitExpression(arg); - _assembly.setSourceLocation(_call.debugData->location); + _assembly.setSourceLocation(locationOf(_call)); } diff --git a/libyul/backends/evm/EVMObjectCompiler.cpp b/libyul/backends/evm/EVMObjectCompiler.cpp index 2b9808387..eeb57a549 100644 --- a/libyul/backends/evm/EVMObjectCompiler.cpp +++ b/libyul/backends/evm/EVMObjectCompiler.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -58,10 +59,15 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize) yulAssert(_object.analysisInfo, "No analysis info."); yulAssert(_object.code, "No code."); - // We do not catch and re-throw the stack too deep exception here because it is a YulException, - // which should be native to this part of the code. - CodeTransform transform{m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context, _optimize}; - transform(*_object.code); - if (!transform.stackErrors().empty()) - BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + if (_optimize && m_dialect.evmVersion() > langutil::EVMVersion::homestead()) + OptimizedEVMCodeTransform::run(m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context); + else + { + // We do not catch and re-throw the stack too deep exception here because it is a YulException, + // which should be native to this part of the code. + CodeTransform transform{m_assembly, *_object.analysisInfo, *_object.code, m_dialect, context, _optimize}; + transform(*_object.code); + if (!transform.stackErrors().empty()) + BOOST_THROW_EXCEPTION(transform.stackErrors().front()); + } } diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.cpp b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp new file mode 100644 index 000000000..76ac8ff76 --- /dev/null +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.cpp @@ -0,0 +1,458 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace solidity; +using namespace solidity::yul; +using namespace std; + +OptimizedEVMCodeTransform::OptimizedEVMCodeTransform( + AbstractAssembly& _assembly, + BuiltinContext& _builtinContext, + bool _useNamedLabelsForFunctions, + CFG const& _dfg, + StackLayout const& _stackLayout +): +m_assembly(_assembly), +m_builtinContext(_builtinContext), +m_useNamedLabelsForFunctions(_useNamedLabelsForFunctions), +m_dfg(_dfg), +m_stackLayout(_stackLayout) +{ +} + +void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack) +{ + for (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack)) + yulAssert(holds_alternative(desiredSlot) || currentSlot == desiredSlot, ""); +} + +AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function) +{ + CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(&_function); + if (!m_functionLabels.count(&functionInfo)) + { + m_functionLabels[&functionInfo] = m_useNamedLabelsForFunctions ? + m_assembly.namedLabel( + functionInfo.function.name.str(), + functionInfo.function.arguments.size(), + functionInfo.function.returns.size(), + {} + ) : m_assembly.newLabelId(); + } + return m_functionLabels[&functionInfo]; +} + +void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression const& _expression) +{ + std::visit(util::GenericVisitor{ + [&](yul::Literal const& _literal) { + auto* literalSlot = get_if(&_slot); + yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, ""); + }, + [&](yul::Identifier const& _identifier) { + auto* variableSlot = get_if(&_slot); + yulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, ""); + }, + [&](yul::FunctionCall const& _call) { + auto* temporarySlot = get_if(&_slot); + yulAssert(temporarySlot && &temporarySlot->call.get() == &_call, ""); + } + }, _expression); +} + +void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInfo) +{ + yulAssert(!m_currentFunctionInfo, ""); + m_currentFunctionInfo = &_functionInfo; + + Stack const& entryLayout = m_stackLayout.blockInfos.at(_functionInfo.entry).entryLayout; + + m_stack.clear(); + m_stack.emplace_back(FunctionReturnLabelSlot{}); + for (auto const& param: _functionInfo.parameters | ranges::views::reverse) + m_stack.emplace_back(param); + m_assembly.setStackHeight(static_cast(m_stack.size())); + m_assembly.setSourceLocation(locationOf(_functionInfo)); + if (!m_functionLabels.count(&_functionInfo)) + m_functionLabels[&_functionInfo] = m_assembly.newLabelId(); + + m_assembly.appendLabel(getFunctionLabel(_functionInfo.function)); + createStackLayout(entryLayout); + + (*this)(*_functionInfo.entry); + + m_currentFunctionInfo = nullptr; + m_stack.clear(); + m_assembly.setStackHeight(0); +} + +void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call) +{ + yulAssert(m_stack.size() >= _call.function.get().arguments.size() + 1, ""); + auto returnLabel = m_returnLabels.at(&_call.functionCall.get()); + + // Assert that we got a correct arguments on stack for the call. + for (auto&& [arg, slot]: ranges::zip_view( + _call.functionCall.get().arguments | ranges::views::reverse, + m_stack | ranges::views::take_last(_call.functionCall.get().arguments.size()) + )) + validateSlot(slot, arg); + // Assert that we got the correct return label on stack. + auto* returnLabelSlot = get_if(&m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1)); + yulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), ""); + + m_assembly.setSourceLocation(locationOf(_call)); + m_assembly.appendJumpTo( + getFunctionLabel(_call.function), + static_cast(_call.function.get().returns.size() - _call.function.get().arguments.size()) - 1, + AbstractAssembly::JumpType::IntoFunction + ); + m_assembly.appendLabel(returnLabel); + // Remove arguments and return label from m_stack. + for (size_t i = 0; i < _call.function.get().arguments.size() + 1; ++i) + m_stack.pop_back(); + // Push return values to m_stack. + ranges::actions::push_back( + m_stack, + ranges::views::iota(0u, _call.function.get().returns.size()) | + ranges::views::transform([&](size_t _i) -> StackSlot { return TemporarySlot{_call.functionCall, _i}; }) + ); + yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); +} + +void OptimizedEVMCodeTransform::operator()(CFG::BuiltinCall const& _call) +{ + yulAssert(m_stack.size() >= _call.arguments, ""); + // Assert that we got a correct stack for the call. + for (auto&& [arg, slot]: ranges::zip_view( + _call.functionCall.get().arguments | ranges::views::enumerate | + ranges::views::filter(util::mapTuple([&](size_t idx, auto&) -> bool { return !_call.builtin.get().literalArgument(idx); })) | + ranges::views::reverse | ranges::views::values, + m_stack | ranges::views::take_last(_call.arguments) + )) + validateSlot(slot, arg); + + m_assembly.setSourceLocation(locationOf(_call)); + static_cast(_call.builtin.get()).generateCode(_call.functionCall, m_assembly, m_builtinContext, [](auto&&){}); + // Remove arguments from m_stack. + for (size_t i = 0; i < _call.arguments; ++i) + m_stack.pop_back(); + // Push return values to m_stack. + ranges::actions::push_back( + m_stack, + ranges::views::iota(0u, _call.builtin.get().returns.size()) | + ranges::views::transform([&](size_t _i) -> StackSlot { return TemporarySlot{_call.functionCall, _i};}) + ); + yulAssert(m_assembly.stackHeight() == static_cast(m_stack.size()), ""); +} + +void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment) +{ + for (auto& currentSlot: m_stack) + if (VariableSlot const* varSlot = get_if(¤tSlot)) + if (util::findOffset(_assignment.variables, *varSlot)) + currentSlot = JunkSlot{}; + + for (auto&& [currentSlot, varSlot]: ranges::zip_view(m_stack | ranges::views::take_last(_assignment.variables.size()), _assignment.variables)) + currentSlot = varSlot; +} + +void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block) +{ + if (!m_generated.insert(&_block).second) + return; + + auto&& [entryLayout, exitLayout] = m_stackLayout.blockInfos.at(&_block); + + if (auto label = util::valueOrNullptr(m_blockLabels, &_block)) + m_assembly.appendLabel(*label); + + assertLayoutCompatibility(m_stack, entryLayout); + m_stack = entryLayout; + yulAssert(static_cast(m_stack.size()) == m_assembly.stackHeight(), ""); + + for (auto const& operation: _block.operations) + { + createStackLayout(m_stackLayout.operationEntryLayout.at(&operation)); + std::visit(*this, operation.operation); + } + createStackLayout(exitLayout); + + std::visit(util::GenericVisitor{ + [&](CFG::BasicBlock::MainExit const&) + { + m_assembly.appendInstruction(evmasm::Instruction::STOP); + m_assembly.setStackHeight(0); + m_stack.clear(); + }, + [&](CFG::BasicBlock::Jump const& _jump) + { + Stack const& entryLayout = m_stackLayout.blockInfos.at(_jump.target).entryLayout; + createStackLayout(entryLayout); + + if (!m_blockLabels.count(_jump.target) && _jump.target->entries.size() == 1) + { + yulAssert(!_jump.backwards, ""); + (*this)(*_jump.target); + } + else + { + if (!m_blockLabels.count(_jump.target)) + m_blockLabels[_jump.target] = m_assembly.newLabelId(); + + m_assembly.appendJumpTo(m_blockLabels[_jump.target]); + if (!m_generated.count(_jump.target)) + (*this)(*_jump.target); + } + }, + [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + if (!m_blockLabels.count(_conditionalJump.nonZero)) + m_blockLabels[_conditionalJump.nonZero] = m_assembly.newLabelId(); + m_assembly.appendJumpToIf(m_blockLabels[_conditionalJump.nonZero]); + m_stack.pop_back(); + + assertLayoutCompatibility(m_stack, m_stackLayout.blockInfos.at(_conditionalJump.nonZero).entryLayout); + assertLayoutCompatibility(m_stack, m_stackLayout.blockInfos.at(_conditionalJump.zero).entryLayout); + + { + ScopedSaveAndRestore stackRestore(m_stack, Stack{m_stack}); + + if (!m_blockLabels.count(_conditionalJump.zero)) + m_blockLabels[_conditionalJump.zero] = m_assembly.newLabelId(); + if (m_generated.count(_conditionalJump.zero)) + m_assembly.appendJumpTo(m_blockLabels[_conditionalJump.zero]); + else + (*this)(*_conditionalJump.zero); + } + + if (!m_generated.count(_conditionalJump.nonZero)) + { + m_assembly.setStackHeight(static_cast(m_stack.size())); + (*this)(*_conditionalJump.nonZero); + } + }, + [&](CFG::BasicBlock::FunctionReturn const& _functionReturn) + { + yulAssert(m_currentFunctionInfo, ""); + yulAssert(m_currentFunctionInfo == _functionReturn.info, ""); + + Stack exitStack = m_currentFunctionInfo->returnVariables | ranges::views::transform([](auto const& _varSlot){ + return StackSlot{_varSlot}; + }) | ranges::to; + exitStack.emplace_back(FunctionReturnLabelSlot{}); + + createStackLayout(exitStack); + m_assembly.setSourceLocation(locationOf(*m_currentFunctionInfo)); + m_assembly.appendJump(0, AbstractAssembly::JumpType::OutOfFunction); // TODO: stack height diff. + m_assembly.setStackHeight(0); + m_stack.clear(); + + }, + [&](CFG::BasicBlock::Terminated const&) + { + m_assembly.setStackHeight(0); + m_stack.clear(); + } + }, _block.exit); +} + +// TODO: It may or may not be nicer to merge this with createStackLayout (e.g. by adding an option to it that +// disables actually emitting assembly output). +Stack OptimizedEVMCodeTransform::tryCreateStackLayout(Stack const& _currentStack, Stack _targetStack) +{ + Stack unreachable; + Stack commonPrefix; + for (auto&& [slot1, slot2]: ranges::zip_view(_currentStack, _targetStack)) + { + if (!(slot1 == slot2)) + break; + commonPrefix.emplace_back(slot1); + } + Stack temporaryStack = _currentStack | ranges::views::drop(commonPrefix.size()) | ranges::to; + + ::createStackLayout(temporaryStack, _targetStack | ranges::views::drop(commonPrefix.size()) | ranges::to, [&](unsigned _i) { + if (_i > 16) + { + if (!util::findOffset(unreachable, temporaryStack.at(temporaryStack.size() - _i - 1))) + unreachable.emplace_back(temporaryStack.at(temporaryStack.size() - _i - 1)); + } + }, [&](unsigned _i) { + if (_i > 16) + { + if (!util::findOffset(unreachable, temporaryStack.at(temporaryStack.size() - _i - 1))) + unreachable.emplace_back(temporaryStack.at(temporaryStack.size() - _i - 1)); + } + }, [&](StackSlot const& _slot) { + Stack currentFullStack = commonPrefix; + for (auto slot: temporaryStack) + currentFullStack.emplace_back(slot); + if (auto depth = util::findOffset(currentFullStack | ranges::views::reverse, _slot)) + { + if (*depth + 1 > 16) + { + if (!util::findOffset(unreachable, _slot)) + unreachable.emplace_back(_slot); + } + return; + } + }, [&]() {}); + return unreachable; +} + +void OptimizedEVMCodeTransform::createStackLayout(Stack _targetStack) +{ + Stack commonPrefix; + for (auto&& [currentSlot, targetSlot]: ranges::zip_view(m_stack, _targetStack)) + { + if (!(currentSlot == targetSlot) || holds_alternative(targetSlot)) + break; + commonPrefix.emplace_back(targetSlot); + } + + Stack temporaryStack = m_stack | ranges::views::drop(commonPrefix.size()) | ranges::to; + + if (!tryCreateStackLayout(m_stack, _targetStack).empty()) + { + yulAssert(false, "Stack too deep."); // Make this a hard failure now to focus on avoiding it earlier. + // TODO: check if we can do better. + // Maybe switching to a general "fix everything deep first" algorithm. + // Or we just let these cases, that weren't fixed in the StackLayoutGenerator go through and report the + // need for stack limit evasion for these cases instead. + std::map slotsByDepth; + for (auto slot: _targetStack | ranges::views::take_last(_targetStack.size() - commonPrefix.size())) + if (auto offset = util::findOffset(m_stack | ranges::views::reverse | ranges::to, slot)) + slotsByDepth.insert(std::make_pair(*offset, slot)); + for (auto slot: slotsByDepth | ranges::views::reverse | ranges::views::values) + if (!util::findOffset(temporaryStack, slot)) + { + auto offset = util::findOffset(m_stack | ranges::views::reverse | ranges::to, slot); + m_stack.emplace_back(slot); + m_assembly.appendInstruction(evmasm::dupInstruction(static_cast(*offset + 1))); + } + + temporaryStack = m_stack | ranges::views::drop(commonPrefix.size()) | ranges::to; + } + + + ::createStackLayout(temporaryStack, _targetStack | ranges::views::drop(commonPrefix.size()) | ranges::to, [&](unsigned _i) { + m_assembly.appendInstruction(evmasm::swapInstruction(_i)); + }, [&](unsigned _i) { + m_assembly.appendInstruction(evmasm::dupInstruction(_i)); + }, [&](StackSlot const& _slot) { + Stack currentFullStack = commonPrefix; + for (auto slot: temporaryStack) + currentFullStack.emplace_back(slot); + if (auto depth = util::findOffset(currentFullStack | ranges::views::reverse, _slot)) + { + m_assembly.appendInstruction(evmasm::dupInstruction(static_cast(*depth + 1))); + return; + } + std::visit(util::GenericVisitor{ + [&](LiteralSlot const& _literal) + { + m_assembly.setSourceLocation(locationOf(_literal)); + m_assembly.appendConstant(_literal.value); + }, + [&](FunctionReturnLabelSlot const&) + { + yulAssert(false, "Cannot produce function return label."); + }, + [&](FunctionCallReturnLabelSlot const& _returnLabel) + { + if (!m_returnLabels.count(&_returnLabel.call.get())) + m_returnLabels[&_returnLabel.call.get()] = m_assembly.newLabelId(); + m_assembly.appendLabelReference(m_returnLabels.at(&_returnLabel.call.get())); + }, + [&](VariableSlot const& _variable) + { + if (m_currentFunctionInfo) + if (util::contains(m_currentFunctionInfo->returnVariables, _variable)) + { + // TODO: maybe track uninitialized return variables. + m_assembly.appendConstant(0); + return; + } + yulAssert(false, "Variable not found on stack."); + }, + [&](TemporarySlot const&) + { + yulAssert(false, "Function call result requested, but not found on stack."); + }, + [&](JunkSlot const&) + { + // Note: this will always be popped, so we can push anything. + // TODO: discuss if PC is in fact a good choice here. + // Advantages: + // - costs only 2 gas + // - deterministic value (in case it is in fact used due to some bug) + // - hard to exploit in case of a bug + // - distinctive, since it is not generated elsewhere + // Disadvantages: + // - static analysis might get confused until it realizes that these are always popped + // Alternatives: + // - any other opcode with cost 2 + // - unless the stack is empty: DUP1 + // - the constant 0 + // Note: it might even make sense to introduce a specific assembly item for this, s.t. + // the peephole optimizer can deal with this (e.g. POP PUSHJUNK can be removed). + m_assembly.appendInstruction(evmasm::Instruction::PC); + } + }, _slot); + }, [&]() { m_assembly.appendInstruction(evmasm::Instruction::POP); }); + m_stack = commonPrefix; + for (auto slot: temporaryStack) + m_stack.emplace_back(slot); +} + +void OptimizedEVMCodeTransform::run( + AbstractAssembly& _assembly, + AsmAnalysisInfo& _analysisInfo, + Block const& _block, + EVMDialect const& _dialect, + BuiltinContext& _builtinContext, + ExternalIdentifierAccess const&, + bool _useNamedLabelsForFunctions +) +{ + std::unique_ptr dfg = ControlFlowGraphBuilder::build(_analysisInfo, _dialect, _block); + StackLayout stackLayout = StackLayoutGenerator::run(*dfg); + OptimizedEVMCodeTransform optimizedCodeTransform(_assembly, _builtinContext, _useNamedLabelsForFunctions, *dfg, stackLayout); + optimizedCodeTransform(*dfg->entry); + for (Scope::Function const* function: dfg->functions) + optimizedCodeTransform(dfg->functionInfo.at(function)); +} diff --git a/libyul/backends/evm/OptimizedEVMCodeTransform.h b/libyul/backends/evm/OptimizedEVMCodeTransform.h new file mode 100644 index 000000000..e28ed8024 --- /dev/null +++ b/libyul/backends/evm/OptimizedEVMCodeTransform.h @@ -0,0 +1,110 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Code generator for translating Yul / inline assembly to EVM. + */ + +#pragma once + +#include +#include +#include +#include + +#include +#include + +namespace solidity::langutil +{ +class ErrorReporter; +} + +namespace solidity::yul +{ +struct AsmAnalysisInfo; +struct StackLayout; + +class OptimizedEVMCodeTransform +{ +public: + static void run( + AbstractAssembly& _assembly, + AsmAnalysisInfo& _analysisInfo, + Block const& _block, + EVMDialect const& _dialect, + BuiltinContext& _builtinContext, + ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess(), + bool _useNamedLabelsForFunctions = false + ); +private: + OptimizedEVMCodeTransform( + AbstractAssembly& _assembly, + BuiltinContext& _builtinContext, + bool _useNamedLabelsForFunctions, + CFG const& _dfg, + StackLayout const& _stackLayout + ); + + AbstractAssembly::LabelID getFunctionLabel(Scope::Function const& _function); + + /// Shuffles m_stack to the desired @a _targetStack while emitting the shuffling code to m_assembly. + void createStackLayout(Stack _targetStack); + + /// Generate code for the given block @a _block. + /// Expects the current stack layout m_stack to be a stack layout that is compatible with the + /// entry layout expected by the block. + void operator()(CFG::BasicBlock const& _block); + + /// Generate code for the given function. + /// Resets m_stack. + void operator()(CFG::FunctionInfo const& _functionInfo); +public: + /// Generate code for the function call @a _call. + void operator()(CFG::FunctionCall const& _call); + /// Generate code for the builtin call @a _call. + void operator()(CFG::BuiltinCall const& _call); + /// Generate code for the assignment @a _assignment. + void operator()(CFG::Assignment const& _assignment); + + /// @returns the stack slots that would become unreachable when createStackLayout was called with + /// @a _targetStack as argument while m_stack was @a _stack. + static Stack tryCreateStackLayout(Stack const& _stack, Stack _targetStack); + +private: + /// Assert that @a _slot contains the value of @a _expression. + static void validateSlot(StackSlot const& _slot, Expression const& _expression); + /// Assert that it is valid to transition from @a _currentStack to @a _desiredStack. + /// That is @a _currentStack matches each slot in @a _desiredStack that is not a JunkSlot exactly. + static void assertLayoutCompatibility(Stack const& _currentStack, Stack const& _desiredStack); + + AbstractAssembly& m_assembly; + BuiltinContext& m_builtinContext; + bool m_useNamedLabelsForFunctions = true; + CFG const& m_dfg; + StackLayout const& m_stackLayout; + Stack m_stack; + std::map m_returnLabels; + std::map m_blockLabels; + std::map m_functionLabels; + /// Set of blocks already generated. If any of the contained blocks is ever jumped to, m_blockLabels should + /// contain a jump label for it. + std::set m_generated; + CFG::FunctionInfo const* m_currentFunctionInfo = nullptr; +}; + +} diff --git a/libyul/backends/evm/StackHelpers.h b/libyul/backends/evm/StackHelpers.h new file mode 100644 index 000000000..a656e73dc --- /dev/null +++ b/libyul/backends/evm/StackHelpers.h @@ -0,0 +1,188 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 + +#pragma once + +#include +#include + +#include + +#include +#include + +namespace solidity::yul +{ + +inline std::string stackSlotToString(StackSlot const& _slot) +{ + return std::visit(util::GenericVisitor{ + [](FunctionCallReturnLabelSlot const& _ret) -> std::string { return "RET[" + _ret.call.get().functionName.name.str() + "]"; }, + [](FunctionReturnLabelSlot const&) -> std::string { return "RET"; }, + [](VariableSlot const& _var) { return _var.variable.get().name.str(); }, + [](LiteralSlot const& _lit) { return util::toCompactHexWithPrefix(_lit.value); }, + [](TemporarySlot const& _tmp) -> std::string { return "TMP[" + _tmp.call.get().functionName.name.str() + ", " + std::to_string(_tmp.index) + "]"; }, + [](JunkSlot const&) -> std::string { return "JUNK"; } + }, _slot); +} + +inline std::string stackToString(Stack const& _stack) +{ + std::string result("[ "); + for (auto const& slot: _stack) + result += stackSlotToString(slot) + ' '; + result += ']'; + return result; +} +template +std::set findAllOffsets(Range&& _range, Value&& _value) +{ + std::set result; + auto begin = std::begin(_range); + auto end = std::end(_range); + auto it = begin; + while (it != end) + { + it = std::find(it, end, std::forward(_value)); + if (it == end) + return result; + result.emplace(static_cast(std::distance(begin, it))); + ++it; + } + return result; +} + +template +void createStackLayout(Stack& _currentStack, Stack const& _targetStack, Swap _swap, Dup _dup, PushSlot _push, Pop _pop) +{ + if (_currentStack == _targetStack) + return; + + if (_currentStack.empty()) + { + while (_currentStack.size() < _targetStack.size()) + { + StackSlot newSlot = _targetStack.at(_currentStack.size()); + _push(newSlot); + _currentStack.emplace_back(newSlot); + } + yulAssert(_currentStack == _targetStack, ""); + return; + } + + auto topTargets = findAllOffsets(_targetStack, _currentStack.back()); + if (topTargets.size() < findAllOffsets(_currentStack, _currentStack.back()).size()) + { + _pop(); + _currentStack.pop_back(); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + else if (_targetStack.size() >= _currentStack.size() && _targetStack.at(_currentStack.size() - 1) == _currentStack.back()) + { + // Current top is in place. + // Dup deepest one to be dupped (TODO: choose optimal). + for (auto&& [offset, slot]: _currentStack | ranges::views::enumerate) + { + if (findAllOffsets(_currentStack, slot).size() < findAllOffsets(_targetStack, slot).size()) + { + auto leastDeepOccurrence = util::findOffset(_currentStack | ranges::views::reverse, slot); + yulAssert(leastDeepOccurrence, ""); + _dup(static_cast(*leastDeepOccurrence + 1)); + + _currentStack.emplace_back(_currentStack.at(offset)); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + // Nothing to dup. Find anything to be pushed and push it. + for (auto const& slot: _targetStack) + { + if (!util::findOffset(_currentStack, slot)) + { + _push(slot); + _currentStack.emplace_back(slot); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + // Nothing to push or dup. + // Swap the deepest one that's not in place up. + for (auto&& [offset, slot]: _currentStack | ranges::views::enumerate) + { + if (!(slot == _targetStack.at(offset)) && !(slot == _currentStack.back())) + { + _swap(static_cast(_currentStack.size() - offset - 1)); + std::swap(_currentStack.back(), _currentStack.at(offset)); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + // Nothing to push or dup and nothing out of place => done. + yulAssert(_currentStack == _targetStack, ""); + return; + } + else + { + for (unsigned deepestTopTarget: topTargets) + { + if (deepestTopTarget >= _currentStack.size()) + break; + if (!(_currentStack.at(deepestTopTarget) == _targetStack.at(deepestTopTarget))) + { + // Move top into place. + _swap(static_cast(_currentStack.size() - deepestTopTarget - 1)); + std::swap(_currentStack.back(), _currentStack.at(deepestTopTarget)); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + + // There needs to be something to dup or push. Try dupping. (TODO: suboptimal) + for (auto&& [offset, slot]: _currentStack | ranges::views::enumerate) + { + if (findAllOffsets(_currentStack, slot).size() < findAllOffsets(_targetStack, slot).size()) + { + auto leastDeepOccurrence = util::findOffset(_currentStack | ranges::views::reverse, slot); + yulAssert(leastDeepOccurrence, ""); + _dup(static_cast(*leastDeepOccurrence + 1)); + // _dup(static_cast(_currentStack.size() - offset)); + + _currentStack.emplace_back(_currentStack.at(offset)); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + // Nothing to dup. Find anything to be pushed and push it. + for (auto const& slot: _targetStack) + { + if (!util::findOffset(_currentStack, slot)) + { + _push(slot); + _currentStack.emplace_back(slot); + createStackLayout(_currentStack, _targetStack, _swap, _dup, _push, _pop); + return; + } + } + yulAssert(false, ""); + } + + yulAssert(_currentStack == _targetStack, ""); +} + +} diff --git a/libyul/backends/evm/StackLayoutGenerator.cpp b/libyul/backends/evm/StackLayoutGenerator.cpp new file mode 100644 index 000000000..189b50c51 --- /dev/null +++ b/libyul/backends/evm/StackLayoutGenerator.cpp @@ -0,0 +1,567 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Stack layout generator for Yul to EVM code generation. + */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace solidity; +using namespace solidity::yul; +using namespace std; + +StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout): m_layout(_layout) +{ +} + +namespace +{ +struct PreviousSlot { size_t slot; }; + +// TODO: Rewrite this as custom algorithm matching createStackLayout exactly and make it work +// for all cases, including duplicates and removals of slots that can be generated on the fly, etc. +// After that the util::permute* functions can be removed. +Stack createIdealLayout(Stack const& _post, vector>> layout) +{ + util::permuteDup(static_cast(layout.size()), [&](unsigned _i) -> set { + // For call return values the target position is known. + if (set* pos = get_if>(&layout.at(_i))) + return *pos; + // Previous arguments can stay where they are. + return {_i}; + }, [&](unsigned _i) { + std::swap(layout.back(), layout.at(layout.size() - _i - 1)); + }, [&](unsigned _i) { + auto positions = get_if>(&layout.at(layout.size() - _i)); + yulAssert(positions, ""); + if (positions->count(static_cast(layout.size()))) + { + positions->erase(static_cast(layout.size())); + layout.emplace_back(set{static_cast(layout.size())}); + } + else + { + optional duppingOffset; + for (unsigned pos: *positions) + { + if (pos != layout.size() - _i) + { + duppingOffset = pos; + break; + } + } + yulAssert(duppingOffset, ""); + positions->erase(*duppingOffset); + layout.emplace_back(set{*duppingOffset}); + } + }, [&]() { + yulAssert(false, ""); + }, [&]() { + layout.pop_back(); + }); + + // Now we can construct the ideal layout before the operation. + // "layout" has the declared variables in the desired position and + // for any PreviousSlot{x}, x yields the ideal place of the slot before the declaration. + vector> idealLayout(_post.size(), nullopt); + for (auto const& [slot, idealPosition]: ranges::zip_view(_post, layout)) + if (PreviousSlot* previousSlot = std::get_if(&idealPosition)) + idealLayout.at(previousSlot->slot) = slot; + + while (!idealLayout.empty() && !idealLayout.back()) + idealLayout.pop_back(); + + return idealLayout | ranges::views::transform([](optional s) { + yulAssert(s, ""); + return *s; + }) | ranges::to; +} +} + +Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation) +{ + Stack& stack = _exitStack; + + vector> targetPositions(_operation.output.size(), set{}); + size_t numToKeep = 0; + for (size_t idx: ranges::views::iota(0u, targetPositions.size())) + for (unsigned offset: findAllOffsets(stack, _operation.output.at(idx))) + { + targetPositions[idx].emplace(offset); + ++numToKeep; + } + + auto layout = ranges::views::iota(0u, stack.size() - numToKeep) | + ranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) | + ranges::to>>>; + // The call produces values with known target positions. + layout += targetPositions; + + stack = createIdealLayout(stack, layout); + + if (auto const* assignment = get_if(&_operation.operation)) + for (auto& stackSlot: stack) + if (auto const* varSlot = get_if(&stackSlot)) + if (util::findOffset(assignment->variables, *varSlot)) + stackSlot = JunkSlot{}; + + for (StackSlot const& input: _operation.input) + stack.emplace_back(input); + + m_layout.operationEntryLayout[&_operation] = stack; + + // TODO: We will potentially accumulate a lot of return labels here. + // Removing them naively has huge implications on both code size and runtime gas cost (both positive and negative): + // cxx20::erase_if(*m_stack, [](StackSlot const& _slot) { return holds_alternative(_slot); }); + // Consider removing them properly while accounting for the induced backwards stack shuffling. + + // Remove anything from the stack top that can be freely generated or dupped from deeper on the stack. + while (!stack.empty() && ( + canBeFreelyGenerated(stack.back()) || + util::findOffset(stack | ranges::views::drop_last(1), stack.back()) + )) + stack.pop_back(); + + // TODO: suboptimal. Should account for induced stack shuffling. + // TODO: consider if we want this kind of compression at all, resp. whether stack.size() > 12 is a good condition. + if (stack.size() > 12) + stack = stack | ranges::views::enumerate | ranges::views::filter(util::mapTuple([&](size_t _index, StackSlot const& _slot) { + // Filter out slots that can be freely generated or are already present on the stack. + return !canBeFreelyGenerated(_slot) && !util::findOffset(stack | ranges::views::take(_index), _slot); + })) | ranges::views::values | ranges::to; + return stack; +} + +Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::BasicBlock const& _block) +{ + Stack stack = std::move(_exitStack); + for (auto& operation: _block.operations | ranges::views::reverse) + stack = propagateStackThroughOperation(stack, operation); + return stack; +} + +void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry) +{ + std::list toVisit{&_entry}; + std::set visited; + + while (!toVisit.empty()) + { + // TODO: calculate backwardsJumps only once. + std::list> backwardsJumps; + while (!toVisit.empty()) + { + CFG::BasicBlock const *block = *toVisit.begin(); + toVisit.pop_front(); + + if (visited.count(block)) + continue; + + if (std::optional exitLayout = std::visit(util::GenericVisitor{ + [&](CFG::BasicBlock::MainExit const&) -> std::optional + { + visited.emplace(block); + return Stack{}; + }, + [&](CFG::BasicBlock::Jump const& _jump) -> std::optional + { + if (_jump.backwards) + { + visited.emplace(block); + backwardsJumps.emplace_back(block, _jump.target); + if (auto* info = util::valueOrNullptr(m_layout.blockInfos, _jump.target)) + return info->entryLayout; + return Stack{}; + } + if (visited.count(_jump.target)) + { + visited.emplace(block); + return m_layout.blockInfos.at(_jump.target).entryLayout; + } + toVisit.emplace_front(_jump.target); + return nullopt; + }, + [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional + { + bool zeroVisited = visited.count(_conditionalJump.zero); + bool nonZeroVisited = visited.count(_conditionalJump.nonZero); + if (zeroVisited && nonZeroVisited) + { + Stack stack = combineStack( + m_layout.blockInfos.at(_conditionalJump.zero).entryLayout, + m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout + ); + stack.emplace_back(_conditionalJump.condition); + visited.emplace(block); + return stack; + } + if (!zeroVisited) + toVisit.emplace_front(_conditionalJump.zero); + if (!nonZeroVisited) + toVisit.emplace_front(_conditionalJump.nonZero); + return nullopt; + }, + [&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional + { + visited.emplace(block); + yulAssert(_functionReturn.info, ""); + Stack stack = _functionReturn.info->returnVariables | ranges::views::transform([](auto const& _varSlot){ + return StackSlot{_varSlot}; + }) | ranges::to; + stack.emplace_back(FunctionReturnLabelSlot{}); + return stack; + }, + [&](CFG::BasicBlock::Terminated const&) -> std::optional + { + visited.emplace(block); + return Stack{}; + }, + }, block->exit)) + { + // We can skip the visit, if we have seen this precise exit layout already last time. + // Note: if the entire graph is revisited in the backwards jump check below, doing + // this seems to break things; not sure why. + // Note: since I don't quite understand why doing this can break things, I comment + // it out for now, since not aborting in those cases should always be safe. + // if (auto* previousInfo = util::valueOrNullptr(m_layout.blockInfos, block)) + // if (previousInfo->exitLayout == *exitLayout) + // continue; + auto& info = m_layout.blockInfos[block]; + info.exitLayout = *exitLayout; + info.entryLayout = propagateStackThroughBlock(info.exitLayout, *block); + + for (auto entry: block->entries) + toVisit.emplace_back(entry); + } + else + continue; + } + + for (auto [block, target]: backwardsJumps) + if (ranges::any_of( + m_layout.blockInfos[target].entryLayout, + [exitLayout = m_layout.blockInfos[block].exitLayout](StackSlot const& _slot) { + return !util::findOffset(exitLayout, _slot); + } + )) + { + // This block jumps backwards, but does not provide all slots required by the jump target on exit. + // Therefore we need to visit the subgraph between ``target`` and ``block`` again. + // In particular we can visit backwards starting from ``block`` and mark all entries to-be-visited- + // again until we hit ``target``. + toVisit.emplace_front(block); + util::BreadthFirstSearch{{block}}.run( + [&visited, target = target](CFG::BasicBlock const* _block, auto _addChild) { + visited.erase(_block); + if (_block == target) + return; + for (auto const* entry: _block->entries) + _addChild(entry); + } + ); + // TODO: while the above is enough, the layout of ``target`` might change in the process. + // While the shuffled layout for ``target`` will be compatible, it can be worthwhile propagating + // it further up once more. + // This would mean not stopping at _block == target above or even doing visited.clear() here, revisiting the entire graph. + // This is a tradeoff between the runtime of this process and the optimality of the result. + // Also note that while visiting the entire graph again *can* be helpful, it can also be detrimental. + // Also note that for some reason using visited.clear() is incompatible with skipping the revisit + // of already seen exit layouts above, I'm not sure yet why. + } + } + + stitchConditionalJumps(_entry); + fixStackTooDeep(_entry); +} + +Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _stack2) +{ + if (_stack1.empty()) + return _stack2; + if (_stack2.empty()) + return _stack1; + + // TODO: there is probably a better way than brute-forcing. This has n! complexity or worse, so + // we can't keep it like this. + + Stack commonPrefix; + for (auto&& [slot1, slot2]: ranges::zip_view(_stack1, _stack2)) + { + if (!(slot1 == slot2)) + break; + commonPrefix.emplace_back(slot1); + } + Stack stack1Tail = _stack1 | ranges::views::drop(commonPrefix.size()) | ranges::to; + Stack stack2Tail = _stack2 | ranges::views::drop(commonPrefix.size()) | ranges::to; + + Stack candidate; + for (auto slot: stack1Tail) + if (!util::findOffset(candidate, slot)) + candidate.emplace_back(slot); + for (auto slot: stack2Tail) + if (!util::findOffset(candidate, slot)) + candidate.emplace_back(slot); + cxx20::erase_if(candidate, [](StackSlot const& slot) { + return holds_alternative(slot) || holds_alternative(slot); + }); + + std::map sortedCandidates; + + // TODO: surprisingly this works for rather comparably large candidate size, but we should probably + // set up some limit, since this will quickly explode otherwise. + // Ideally we would then have a better fallback mechanism - although returning any naive union of both stacks + // like ``candidate`` itself may just be fine. + // if (candidate.size() > 8) + // return candidate; + + auto evaluate = [&](Stack const& _candidate) -> size_t { + size_t numOps = 0; + Stack testStack = _candidate; + auto swap = [&](unsigned _swapDepth) { ++numOps; if (_swapDepth > 16) numOps += 1000; }; + auto dup = [&](unsigned _dupDepth) { ++numOps; if (_dupDepth > 16) numOps += 1000; }; + auto push = [&](StackSlot const& _slot) { + if (!canBeFreelyGenerated(_slot)) + { + auto offsetInPrefix = util::findOffset(commonPrefix, _slot); + yulAssert(offsetInPrefix, ""); + // Effectively this is a dup. + ++numOps; + // TODO: Verify that this is correct. The idea is to penalize dupping stuff up that's too deep in + // the prefix at this point. + if (commonPrefix.size() + testStack.size() - *offsetInPrefix > 16) + numOps += 1000; + } + }; + createStackLayout(testStack, stack1Tail, swap, dup, push, [&](){} ); + testStack = _candidate; + createStackLayout(testStack, stack2Tail, swap, dup, push, [&](){}); + return numOps; + }; + + // See https://en.wikipedia.org/wiki/Heap's_algorithm + size_t n = candidate.size(); + sortedCandidates.insert(std::make_pair(evaluate(candidate), candidate)); + std::vector c(n, 0); + size_t i = 1; + while (i < n) + { + if (c[i] < i) + { + if (i & 1) + std::swap(candidate.front(), candidate[i]); + else + std::swap(candidate[c[i]], candidate[i]); + sortedCandidates.insert(std::make_pair(evaluate(candidate), candidate)); + ++c[i]; + ++i; + } + else + { + c[i] = 0; + ++i; + } + } + + return commonPrefix + sortedCandidates.begin()->second; +} + +void StackLayoutGenerator::stitchConditionalJumps(CFG::BasicBlock const& _block) +{ + util::BreadthFirstSearch breadthFirstSearch{{&_block}}; + breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) { + auto& info = m_layout.blockInfos.at(_block); + std::visit(util::GenericVisitor{ + [&](CFG::BasicBlock::MainExit const&) {}, + [&](CFG::BasicBlock::Jump const& _jump) + { + if (!_jump.backwards) + _addChild(_jump.target); + }, + [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + auto& zeroTargetInfo = m_layout.blockInfos.at(_conditionalJump.zero); + auto& nonZeroTargetInfo = m_layout.blockInfos.at(_conditionalJump.nonZero); + Stack exitLayout = info.exitLayout; + + // The last block must have produced the condition at the stack top. + yulAssert(!exitLayout.empty(), ""); + yulAssert(exitLayout.back() == _conditionalJump.condition, ""); + // The condition is consumed by the jump. + exitLayout.pop_back(); + + auto fixJumpTargetEntry = [&](Stack const& _originalEntryLayout) -> Stack { + Stack newEntryLayout = exitLayout; + // Whatever the block being jumped to does not actually require, can be marked as junk. + for (auto& slot: newEntryLayout) + if (!util::findOffset(_originalEntryLayout, slot)) + slot = JunkSlot{}; + // Make sure everything the block being jumped to requires is actually present or can be generated. + for (auto const& slot: _originalEntryLayout) + yulAssert(canBeFreelyGenerated(slot) || util::findOffset(newEntryLayout, slot), ""); + return newEntryLayout; + }; + zeroTargetInfo.entryLayout = fixJumpTargetEntry(zeroTargetInfo.entryLayout); + nonZeroTargetInfo.entryLayout = fixJumpTargetEntry(nonZeroTargetInfo.entryLayout); + _addChild(_conditionalJump.zero); + _addChild(_conditionalJump.nonZero); + }, + [&](CFG::BasicBlock::FunctionReturn const&) {}, + [&](CFG::BasicBlock::Terminated const&) { }, + }, _block->exit); + }); +} + +void StackLayoutGenerator::fixStackTooDeep(CFG::BasicBlock const& _block) +{ + // This is just an initial proof of concept. Doing this in a clever way and in all cases will take some doing. + // It might be enough to keep it at fixing inner-block issues and leave inter-block issues to the stack limit + // evader. + // TODO: make sure this really always terminates. + util::BreadthFirstSearch breadthFirstSearch{{&_block}}; + breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) { + Stack stack; + stack = m_layout.blockInfos.at(_block).entryLayout; + + size_t cursor = 1; + + while (cursor < _block->operations.size()) + { + Stack& operationEntry = cursor < _block->operations.size() ? + m_layout.operationEntryLayout.at(&_block->operations.at(cursor)) : + m_layout.blockInfos.at(_block).exitLayout; + + auto unreachable = OptimizedEVMCodeTransform::tryCreateStackLayout(stack, operationEntry); + if (unreachable.empty()) + { + stack = operationEntry; + if (cursor < _block->operations.size()) + { + CFG::Operation const& operation = _block->operations.at(cursor); + for (size_t i = 0; i < operation.input.size(); i++) + stack.pop_back(); + stack += operation.output; + } + ++cursor; + } + else + { + CFG::Operation const& previousOperation = _block->operations.at(cursor - 1); + if (auto const* assignment = get_if(&previousOperation.operation)) + { + for (auto& slot: unreachable) + if (VariableSlot const* varSlot = get_if(&slot)) + if (util::findOffset(assignment->variables, *varSlot)) + { + // TODO: proper warning + std::cout << "Unreachable slot after assignment." << std::endl; + std::cout << "CANNOT FIX YET" << std::endl; + return; + } + } + Stack& previousEntry = m_layout.operationEntryLayout.at(&previousOperation); + Stack newStack = ranges::concat_view( + previousEntry | ranges::views::take(previousEntry.size() - previousOperation.input.size()), + unreachable, + previousEntry | ranges::views::take_last(previousOperation.input.size()) + ) | ranges::to; + previousEntry = newStack; + --cursor; + if (cursor > 0) + { + CFG::Operation const& ancestorOperation = _block->operations.at(cursor - 1); + Stack& ancestorEntry = m_layout.operationEntryLayout.at(&ancestorOperation); + stack = ancestorEntry | ranges::views::take(ancestorEntry.size() - ancestorOperation.input.size()) | ranges::to; + stack += ancestorOperation.output; + } + else + // Stop at block entry, hope for the best and continue downwards again. + ++cursor; + } + } + stack = m_layout.blockInfos.at(_block).exitLayout; + + std::visit(util::GenericVisitor{ + [&](CFG::BasicBlock::MainExit const&) {}, + [&](CFG::BasicBlock::Jump const& _jump) + { + auto unreachable = OptimizedEVMCodeTransform::tryCreateStackLayout(stack, m_layout.blockInfos.at(_jump.target).entryLayout); + if (!unreachable.empty()) + // TODO: proper warning + std::cout << "UNREACHABLE SLOTS AT JUMP: " << stackToString(unreachable) << std::endl + << "CANNOT FIX YET" << std::endl; + + if (!_jump.backwards) + _addChild(_jump.target); + }, + [&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) + { + auto unreachable = OptimizedEVMCodeTransform::tryCreateStackLayout(stack, m_layout.blockInfos.at(_conditionalJump.zero).entryLayout); + if (!unreachable.empty()) + // TODO: proper warning + std::cout + << "UNREACHABLE SLOTS AT CONDITIONAL JUMP: " << stackToString(unreachable) << std::endl + << "CANNOT FIX YET" << std::endl; + unreachable = OptimizedEVMCodeTransform::tryCreateStackLayout(stack, m_layout.blockInfos.at(_conditionalJump.nonZero).entryLayout); + if (!unreachable.empty()) + // TODO: proper warning + std::cout + << "UNREACHABLE SLOTS AT CONDITIONAL JUMP: " << stackToString(unreachable) << std::endl + << "CANNOT FIX YET" << std::endl; + + _addChild(_conditionalJump.zero); + _addChild(_conditionalJump.nonZero); + }, + [&](CFG::BasicBlock::FunctionReturn const&) {}, + [&](CFG::BasicBlock::Terminated const&) { }, + }, _block->exit); + + }); +} + +StackLayout StackLayoutGenerator::run(CFG const& _dfg) +{ + StackLayout stackLayout; + StackLayoutGenerator stackLayoutGenerator{stackLayout}; + + stackLayoutGenerator.processEntryPoint(*_dfg.entry); + for (auto& functionInfo: _dfg.functionInfo | ranges::views::values) + stackLayoutGenerator.processEntryPoint(*functionInfo.entry); + + return stackLayout; +} diff --git a/libyul/backends/evm/StackLayoutGenerator.h b/libyul/backends/evm/StackLayoutGenerator.h new file mode 100644 index 000000000..0fcc78962 --- /dev/null +++ b/libyul/backends/evm/StackLayoutGenerator.h @@ -0,0 +1,84 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see . +*/ +// SPDX-License-Identifier: GPL-3.0 +/** + * Stack layout generator for Yul to EVM code generation. + */ + +#pragma once + +#include + +#include + +namespace solidity::yul +{ + +struct StackLayout +{ + struct BlockInfo + { + /// Complete stack layout that is required for entering a block. + Stack entryLayout; + /// The resulting stack layout after executing the block. + Stack exitLayout; + }; + std::map blockInfos; + /// For each operation the complete stack layout that: + /// - has the slots required for the operation at the stack top. + /// - will have the operation result in a layout that makes it easy to achieve the next desired layout. + std::map operationEntryLayout; +}; + +class StackLayoutGenerator +{ +public: + static StackLayout run(CFG const& _dfg); + +private: + StackLayoutGenerator(StackLayout& _context); + + /// @returns the optimal entry stack layout, s.t. @a _operation can be applied to it and + /// the result can be transformed to @a _exitStack with minimal stack shuffling. + Stack propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation); + + /// @returns the desired stack layout at the entry of @a _block, assuming the layout after + /// executing the block should be @a _exitStack. + Stack propagateStackThroughBlock(Stack _exitStack, CFG::BasicBlock const& _block); + + /// Main algorithm walking the graph from entry to exit and propagating back the stack layouts to the entries. + /// Iteratively reruns itself along backwards jumps until the layout is stabilized. + void processEntryPoint(CFG::BasicBlock const& _entry); + + /// After the main algorithms, layouts at conditional jumps are merely compatible, i.e. the exit layout of the + /// jumping block is a superset of the entry layout of the target block. This function modifies the entry layouts + /// of conditional jump targets, s.t. the entry layout of target blocks match the exit layout of the jumping block + /// exactly, except that slots not required after the jump are marked as `JunkSlot`s. + void stitchConditionalJumps(CFG::BasicBlock const& _block); + + /// Calculates the ideal stack layout, s.t. both @a _stack1 and @a _stack2 can be achieved with minimal + /// stack shuffling when starting from the returned layout. + static Stack combineStack(Stack const& _stack1, Stack const& _stack2); + + /// Tries to detect stack layout transitions that are bound to cause stack too deep errors and + /// attempts to reorganize the layout to avoid those cases. + void fixStackTooDeep(CFG::BasicBlock const& _entry); + + StackLayout& m_layout; +}; + +} diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 61e2800b8..355cbe527 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -178,8 +179,17 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite) return false; // Do not inline into already big functions. - if (m_functionSizes.at(_callSite) > 45) - return false; + if ( + auto evmDialect = dynamic_cast(&m_dialect); + !evmDialect || !evmDialect->providesObjectAccess() || evmDialect->evmVersion() <= langutil::EVMVersion::homestead() + ) + { + if (m_functionSizes.at(_callSite) > 45) + return false; + } + else + if (m_functionSizes.at(_callSite) > 350) + return false; if (m_singleUse.count(calledFunction->name)) return true; diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index 96f2ec391..1f014cfee 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -19,96 +19,81 @@ object "C_59" { object "C_59_deployed" { code { { - mstore(64, 128) + let _1 := 64 + mstore(_1, 128) if iszero(lt(calldatasize(), 4)) { - let _1 := 0 - if eq(0xf8eddcc6, shr(224, calldataload(_1))) + let _2 := 0 + if eq(0xf8eddcc6, shr(224, calldataload(_2))) { - if callvalue() { revert(_1, _1) } - let _2 := 32 - if slt(add(calldatasize(), not(3)), _2) { revert(_1, _1) } + if callvalue() { revert(_2, _2) } + let _3 := 32 + if slt(add(calldatasize(), not(3)), _3) { revert(_2, _2) } let offset := calldataload(4) - let _3 := 0xffffffffffffffff - if gt(offset, _3) { revert(_1, _1) } - if iszero(slt(add(offset, 35), calldatasize())) { revert(_1, _1) } - let _4 := calldataload(add(4, offset)) - if gt(_4, _3) { panic_error_0x41() } - let _5 := shl(5, _4) - let dst := allocate_memory(add(_5, _2)) + let _4 := 0xffffffffffffffff + if gt(offset, _4) { revert(_2, _2) } + if iszero(slt(add(offset, 35), calldatasize())) { revert(_2, _2) } + let _5 := calldataload(add(4, offset)) + if gt(_5, _4) { panic_error_0x41() } + let _6 := shl(5, _5) + let memPtr := mload(_1) + let _7 := not(31) + let newFreePtr := add(memPtr, and(add(_6, 63), _7)) + if or(gt(newFreePtr, _4), lt(newFreePtr, memPtr)) { panic_error_0x41() } + mstore(_1, newFreePtr) + let dst := memPtr + mstore(memPtr, _5) + dst := add(memPtr, _3) let dst_1 := dst - mstore(dst, _4) - dst := add(dst, _2) let src := add(offset, 36) - if gt(add(add(offset, _5), 36), calldatasize()) { revert(_1, _1) } - let i := _1 - for { } lt(i, _4) { i := add(i, 1) } + if gt(add(add(offset, _6), 36), calldatasize()) { revert(_2, _2) } + let i := _2 + for { } lt(i, _5) { i := add(i, 1) } { - if slt(sub(calldatasize(), src), _2) { revert(_1, _1) } - let value := allocate_memory_1228() - mstore(value, calldataload(src)) - mstore(dst, value) - dst := add(dst, _2) - src := add(src, _2) + if slt(sub(calldatasize(), src), _3) { revert(_2, _2) } + let memPtr_1 := mload(_1) + let newFreePtr_1 := add(memPtr_1, _3) + if or(gt(newFreePtr_1, _4), lt(newFreePtr_1, memPtr_1)) { panic_error_0x41() } + mstore(_1, newFreePtr_1) + mstore(memPtr_1, calldataload(src)) + mstore(dst, memPtr_1) + dst := add(dst, _3) + src := add(src, _3) } - let ret, ret_1 := fun_sumArray(dst_1) - let memPos := mload(64) - return(memPos, sub(abi_encode_uint256_string(memPos, ret, ret_1), memPos)) + if iszero(mload(memPtr)) { panic_error_0x32() } + sstore(_2, mload(mload(dst_1))) + if iszero(lt(1, mload(memPtr))) { panic_error_0x32() } + let _8 := mload(mload(add(memPtr, _1))) + sstore(0x02, _8) + let memPtr_2 := mload(_1) + let newFreePtr_2 := add(memPtr_2, 160) + if or(gt(newFreePtr_2, _4), lt(newFreePtr_2, memPtr_2)) { panic_error_0x41() } + mstore(_1, newFreePtr_2) + mstore(memPtr_2, 100) + mstore(add(memPtr_2, _3), "longstringlongstringlongstringlo") + mstore(add(memPtr_2, _1), "ngstringlongstringlongstringlong") + let _9 := 96 + mstore(add(memPtr_2, _9), "stringlongstringlongstringlongst") + mstore(add(memPtr_2, 128), "ring") + let memPos := mload(_1) + mstore(memPos, _8) + mstore(add(memPos, _3), _1) + let length := mload(memPtr_2) + mstore(add(memPos, _1), length) + let i_1 := _2 + for { } lt(i_1, length) { i_1 := add(i_1, _3) } + { + mstore(add(add(memPos, i_1), _9), mload(add(add(memPtr_2, i_1), _3))) + } + if gt(i_1, length) + { + mstore(add(add(memPos, length), _9), _2) + } + return(memPos, add(sub(add(memPos, and(add(length, 31), _7)), memPos), _9)) } } revert(0, 0) } - function abi_encode_uint256_string(headStart, value0, value1) -> tail - { - mstore(headStart, value0) - let _1 := 32 - mstore(add(headStart, _1), 64) - let length := mload(value1) - mstore(add(headStart, 64), length) - let i := 0 - for { } lt(i, length) { i := add(i, _1) } - { - mstore(add(add(headStart, i), 96), mload(add(add(value1, i), _1))) - } - if gt(i, length) - { - mstore(add(add(headStart, length), 96), 0) - } - tail := add(add(headStart, and(add(length, 31), not(31))), 96) - } - function allocate_memory_1228() -> memPtr - { - memPtr := mload(64) - let newFreePtr := add(memPtr, 32) - if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } - mstore(64, newFreePtr) - } - function allocate_memory(size) -> memPtr - { - memPtr := mload(64) - let newFreePtr := add(memPtr, and(add(size, 31), not(31))) - if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } - mstore(64, newFreePtr) - } - function fun_sumArray(var_s_mpos) -> var, var_mpos - { - if iszero(mload(var_s_mpos)) { panic_error_0x32() } - sstore(0x00, mload(mload(add(var_s_mpos, 32)))) - if iszero(lt(1, mload(var_s_mpos))) { panic_error_0x32() } - let _1 := mload(mload(add(var_s_mpos, 64))) - sstore(0x02, _1) - var := _1 - let memPtr := mload(64) - let newFreePtr := add(memPtr, 160) - if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { panic_error_0x41() } - mstore(64, newFreePtr) - mstore(memPtr, 100) - mstore(add(memPtr, 32), "longstringlongstringlongstringlo") - mstore(add(memPtr, 64), "ngstringlongstringlongstringlong") - mstore(add(memPtr, 96), "stringlongstringlongstringlongst") - mstore(add(memPtr, 128), "ring") - var_mpos := memPtr - } function panic_error_0x32() { mstore(0, shl(224, 0x4e487b71)) diff --git a/test/cmdlineTests/object_compiler/output b/test/cmdlineTests/object_compiler/output index 66ad61fb7..acc25c6a0 100644 --- a/test/cmdlineTests/object_compiler/output +++ b/test/cmdlineTests/object_compiler/output @@ -23,7 +23,7 @@ object "MyContract" { Binary representation: -33600055600b806012600039806000f350fe60005460005260206000f3 +33600055600b8060106000396000f3fe60005460005260206000f3 Text representation: /* "object_compiler/input.yul":128:136 */ @@ -32,21 +32,19 @@ Text representation: 0x00 /* "object_compiler/input.yul":118:137 */ sstore - dataSize(sub_0) /* "object_compiler/input.yul":240:259 */ + dataSize(sub_0) dup1 + /* "object_compiler/input.yul":217:238 */ dataOffset(sub_0) /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":205:260 */ codecopy - /* "object_compiler/input.yul":275:294 */ - dup1 /* "object_compiler/input.yul":125:126 */ 0x00 /* "object_compiler/input.yul":265:295 */ return - pop stop sub_0: assembly { diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index f5a3cf77d..08df927f7 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -43,16 +43,12 @@ object "Arraysum_34" { var_sum := add(var_sum, _3) } let memPos := mload(64) - return(memPos, sub(abi_encode_uint256(memPos, var_sum), memPos)) + mstore(memPos, var_sum) + return(memPos, 32) } } revert(0, 0) } - function abi_encode_uint256(headStart, value0) -> tail - { - tail := add(headStart, 32) - mstore(headStart, value0) - } function panic_error_0x11() { mstore(0, shl(224, 0x4e487b71)) diff --git a/test/cmdlineTests/standard_yul_optimiserSteps/output.json b/test/cmdlineTests/standard_yul_optimiserSteps/output.json index de08a24b7..a6c43eb8e 100644 --- a/test/cmdlineTests/standard_yul_optimiserSteps/output.json +++ b/test/cmdlineTests/standard_yul_optimiserSteps/output.json @@ -1,18 +1,14 @@ -{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ +{"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":38:39 */ 0x00 + dup1 + dup1 /* \"A\":11:19 */ mload - /* \"A\":38:39 */ - 0x00 - /* \"A\":34:35 */ - 0x00 - /* \"A\":31:32 */ - dup3 /* \"A\":27:36 */ add /* \"A\":20:40 */ sstore - pop + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/standard_yul_optimized/output.json b/test/cmdlineTests/standard_yul_optimized/output.json index 2aa40d5b7..fc59275ff 100644 --- a/test/cmdlineTests/standard_yul_optimized/output.json +++ b/test/cmdlineTests/standard_yul_optimized/output.json @@ -1,10 +1,11 @@ {"contracts":{"A":{"object":{"evm":{"assembly":" /* \"A\":17:18 */ 0x00 - 0x00 + dup1 /* \"A\":11:19 */ mload /* \"A\":20:40 */ sstore + stop ","bytecode":{"functionDebugData":{},"generatedSources":[],"linkReferences":{},"object":"","opcodes":"","sourceMap":""}},"ir":"object \"object\" { code { let x := mload(0) diff --git a/test/cmdlineTests/strict_asm_optimizer_steps/output b/test/cmdlineTests/strict_asm_optimizer_steps/output index 369be348c..09f0438e0 100644 --- a/test/cmdlineTests/strict_asm_optimizer_steps/output +++ b/test/cmdlineTests/strict_asm_optimizer_steps/output @@ -24,7 +24,7 @@ object "C_6" { Binary representation: -60806040523415600f5760006000fd5b6010601d60003960106000f3fe608060405260043610155060006000fd +6080604052346016575b600f601c600039600f6000f35b600080fdfe6080604052600436101550600080fd Text representation: /* "strict_asm_optimizer_steps/input.yul":45:48 */ @@ -34,32 +34,28 @@ Text representation: /* "strict_asm_optimizer_steps/input.yul":34:49 */ mstore /* "strict_asm_optimizer_steps/input.yul":61:72 */ - callvalue - /* "strict_asm_optimizer_steps/input.yul":58:60 */ - iszero - tag_1 - jumpi - /* "strict_asm_optimizer_steps/input.yul":85:86 */ - 0x00 - /* "strict_asm_optimizer_steps/input.yul":82:83 */ - 0x00 - /* "strict_asm_optimizer_steps/input.yul":75:87 */ - revert - /* "strict_asm_optimizer_steps/input.yul":58:60 */ -tag_1: - /* "strict_asm_optimizer_steps/input.yul":98:163 */ + jumpi(tag_1, callvalue) +tag_2: + /* "strict_asm_optimizer_steps/input.yul":138:162 */ dataSize(sub_0) + /* "strict_asm_optimizer_steps/input.yul":110:136 */ dataOffset(sub_0) /* "strict_asm_optimizer_steps/input.yul":107:108 */ 0x00 /* "strict_asm_optimizer_steps/input.yul":98:163 */ codecopy - /* "strict_asm_optimizer_steps/input.yul":172:207 */ + /* "strict_asm_optimizer_steps/input.yul":182:206 */ dataSize(sub_0) /* "strict_asm_optimizer_steps/input.yul":179:180 */ 0x00 /* "strict_asm_optimizer_steps/input.yul":172:207 */ return +tag_1: + /* "strict_asm_optimizer_steps/input.yul":85:86 */ + 0x00 + dup1 + /* "strict_asm_optimizer_steps/input.yul":75:87 */ + revert stop sub_0: assembly { @@ -81,8 +77,7 @@ sub_0: assembly { pop /* "strict_asm_optimizer_steps/input.yul":570:571 */ 0x00 - /* "strict_asm_optimizer_steps/input.yul":567:568 */ - 0x00 + dup1 /* "strict_asm_optimizer_steps/input.yul":560:572 */ revert } diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index 3847e7df6..7e5c481d4 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -1,9 +1,9 @@ ======= viair_subobjects/input.sol:C ======= Binary: -60806040523415600f5760006000fd5b600a80601e608039806080f350fe608060405260006000fd +6080604052346015575b600980601b6080396080f35b600080fdfe6080604052600080fd Binary of the runtime part: -608060405260006000fd +6080604052600080fd Optimized IR: /******************************************************* * WARNING * @@ -35,9 +35,9 @@ object "C_3" { ======= viair_subobjects/input.sol:D ======= Binary: -608060405234156100105760006000fd5b60ba80610020608039806080f350fe6080604052600436101515608b576000803560e01c6326121ff0141560895734156027578081fd5b80600319360112156036578081fd5b6028806080016080811067ffffffffffffffff82111715606457634e487b7160e01b83526041600452602483fd5b508061009260803980608083f015156082576040513d83823e3d81fd505b5080604051f35b505b60006000fdfe60806040523415600f5760006000fd5b600a80601e608039806080f350fe608060405260006000fd +608060405234610017575b60ba8061001d6080396080f35b600080fdfe60806040526004361015610013575b600080fd5b6000803560e01c6326121ff01461002b575b5061000e565b34610092575b8060031936011261008f575b60248060800167ffffffffffffffff6080821091111761007a575b80610096608039608082f01561006e575b604051f35b604051903d90823e3d90fd5b50602490634e487b7160e01b81526041600452fd5b80fd5b80fdfe6080604052346015575b600980601b6080396080f35b600080fdfe6080604052600080fd Binary of the runtime part: -6080604052600436101515608b576000803560e01c6326121ff0141560895734156027578081fd5b80600319360112156036578081fd5b6028806080016080811067ffffffffffffffff82111715606457634e487b7160e01b83526041600452602483fd5b508061009260803980608083f015156082576040513d83823e3d81fd505b5080604051f35b505b60006000fdfe60806040523415600f5760006000fd5b600a80601e608039806080f350fe608060405260006000fd +60806040526004361015610013575b600080fd5b6000803560e01c6326121ff01461002b575b5061000e565b34610092575b8060031936011261008f575b60248060800167ffffffffffffffff6080821091111761007a575b80610096608039608082f01561006e575b604051f35b604051903d90823e3d90fd5b50602490634e487b7160e01b81526041600452fd5b80fd5b80fdfe6080604052346015575b600980601b6080396080f35b600080fdfe6080604052600080fd Optimized IR: /******************************************************* * WARNING * diff --git a/test/cmdlineTests/yul_stack_opt/output b/test/cmdlineTests/yul_stack_opt/output index 7c0e8ca66..1cc66b9b3 100644 --- a/test/cmdlineTests/yul_stack_opt/output +++ b/test/cmdlineTests/yul_stack_opt/output @@ -39,167 +39,140 @@ object "object" { Binary representation: -6001808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55808155806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d5580815550 +6001808055806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55808055806002558060035580600455806005558060065580600755806008558060095580600a5580600b5580600c5580600d55805500 Text representation: /* "yul_stack_opt/input.yul":98:99 */ 0x01 dup1 - dup2 + dup1 /* "yul_stack_opt/input.yul":129:141 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":151:160 */ 0x02 /* "yul_stack_opt/input.yul":144:164 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":174:183 */ 0x03 /* "yul_stack_opt/input.yul":167:187 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":197:206 */ 0x04 /* "yul_stack_opt/input.yul":190:210 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":220:229 */ 0x05 /* "yul_stack_opt/input.yul":213:233 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":243:252 */ 0x06 /* "yul_stack_opt/input.yul":236:256 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":266:275 */ 0x07 /* "yul_stack_opt/input.yul":259:279 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":289:298 */ 0x08 /* "yul_stack_opt/input.yul":282:302 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":312:321 */ 0x09 /* "yul_stack_opt/input.yul":305:325 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":335:344 */ 0x0a /* "yul_stack_opt/input.yul":328:348 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":358:368 */ 0x0b /* "yul_stack_opt/input.yul":351:372 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":382:392 */ 0x0c /* "yul_stack_opt/input.yul":375:396 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":406:416 */ 0x0d /* "yul_stack_opt/input.yul":399:420 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 - dup2 + dup1 /* "yul_stack_opt/input.yul":129:141 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":151:160 */ 0x02 /* "yul_stack_opt/input.yul":144:164 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":174:183 */ 0x03 /* "yul_stack_opt/input.yul":167:187 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":197:206 */ 0x04 /* "yul_stack_opt/input.yul":190:210 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":220:229 */ 0x05 /* "yul_stack_opt/input.yul":213:233 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":243:252 */ 0x06 /* "yul_stack_opt/input.yul":236:256 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":266:275 */ 0x07 /* "yul_stack_opt/input.yul":259:279 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":289:298 */ 0x08 /* "yul_stack_opt/input.yul":282:302 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":312:321 */ 0x09 /* "yul_stack_opt/input.yul":305:325 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":335:344 */ 0x0a /* "yul_stack_opt/input.yul":328:348 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":358:368 */ 0x0b /* "yul_stack_opt/input.yul":351:372 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":382:392 */ 0x0c /* "yul_stack_opt/input.yul":375:396 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 /* "yul_stack_opt/input.yul":406:416 */ 0x0d /* "yul_stack_opt/input.yul":399:420 */ sstore - /* "yul_stack_opt/input.yul":98:99 */ dup1 - dup2 /* "yul_stack_opt/input.yul":729:743 */ sstore - pop + stop diff --git a/test/cmdlineTests/yul_verbatim_msize/output b/test/cmdlineTests/yul_verbatim_msize/output index 5f67aa85e..38df1351f 100644 --- a/test/cmdlineTests/yul_verbatim_msize/output +++ b/test/cmdlineTests/yul_verbatim_msize/output @@ -14,7 +14,7 @@ object "object" { Binary representation: -612000515061616002600055 +61200051506161600260005500 Text representation: /* "yul_verbatim_msize/input.yul":125:131 */ @@ -30,3 +30,4 @@ Text representation: 0x00 /* "yul_verbatim_msize/input.yul":162:174 */ sstore + stop diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol index 8fb1e41c0..db23d78d3 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_decode_v2_storage.sol @@ -24,6 +24,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb -// gas irOptimized: 203921 +// gas irOptimized: 204081 // gas legacy: 206126 // gas legacyOptimized: 203105 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol index b4d533ce0..c6f6c8ff0 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/abi_encode_calldata_slice.sol @@ -60,10 +60,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 465417 +// gas irOptimized: 390740 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 661059 +// gas irOptimized: 546333 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol index 6dfcb1cde..5dbc6f44b 100644 --- a/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol +++ b/test/libsolidity/semanticTests/abiEncoderV1/struct/struct_storage_ptr.sol @@ -26,6 +26,6 @@ contract C { // ---- // library: L // f() -> 8, 7, 1, 2, 7, 12 -// gas irOptimized: 168199 +// gas irOptimized: 166704 // gas legacy: 169475 // gas legacyOptimized: 167397 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol index d5687aac7..90a0518c3 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_calldata_slice.sol @@ -61,10 +61,10 @@ contract C { // compileViaYul: also // ---- // test_bytes() -> -// gas irOptimized: 465417 +// gas irOptimized: 390740 // gas legacy: 423563 // gas legacyOptimized: 331391 // test_uint256() -> -// gas irOptimized: 661059 +// gas irOptimized: 546333 // gas legacy: 591392 // gas legacyOptimized: 456137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol index 6e21e0174..fc62b43bb 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2.sol @@ -53,6 +53,6 @@ contract C { // f2() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f3() -> 0x20, 0xa0, 0x1, 0x60, 0x2, 0x3, "abc" // f4() -> 0x20, 0x160, 0x1, 0x80, 0xc0, 0x2, 0x3, "abc", 0x7, 0x40, 0x2, 0x2, 0x3 -// gas irOptimized: 113683 +// gas irOptimized: 113098 // gas legacy: 114728 // gas legacyOptimized: 112606 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol index 2e9e6af40..335a2401a 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_function_inherited_in_v1_contract.sol @@ -32,6 +32,6 @@ contract C is B { // compileViaYul: also // ---- // test() -> 77 -// gas irOptimized: 132435 +// gas irOptimized: 127054 // gas legacy: 155249 // gas legacyOptimized: 111743 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol index 6c5d1df29..8fe8b3ae3 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/abi_encode_v2_in_modifier_used_in_v1_contract.sol @@ -40,5 +40,5 @@ contract C is B { // compileViaYul: also // ---- // test() -> 5, 10 -// gas irOptimized: 91524 +// gas irOptimized: 89080 // gas legacy: 99137 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol index a426c9661..acf9d8c48 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/calldata_array.sol @@ -21,6 +21,6 @@ contract C { // f(uint256[][1]): 32, 32, 0 -> true // f(uint256[][1]): 32, 32, 1, 42 -> true // f(uint256[][1]): 32, 32, 8, 421, 422, 423, 424, 425, 426, 427, 428 -> true -// gas irOptimized: 224675 +// gas irOptimized: 133946 // gas legacy: 141900 // gas legacyOptimized: 121788 diff --git a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol index 3196a29e4..d45b52ba9 100644 --- a/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol +++ b/test/libsolidity/semanticTests/abiEncoderV2/storage_array_encoding.sol @@ -19,10 +19,10 @@ contract C { // compileViaYul: also // ---- // h(uint256[2][]): 0x20, 3, 123, 124, 223, 224, 323, 324 -> 32, 256, 0x20, 3, 123, 124, 223, 224, 323, 324 -// gas irOptimized: 181410 +// gas irOptimized: 181484 // gas legacy: 184929 // gas legacyOptimized: 181504 // i(uint256[2][2]): 123, 124, 223, 224 -> 32, 128, 123, 124, 223, 224 -// gas irOptimized: 112981 +// gas irOptimized: 112920 // gas legacy: 115468 // gas legacyOptimized: 112988 diff --git a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol index a26d7bf08..9fb7c6112 100644 --- a/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol +++ b/test/libsolidity/semanticTests/abiencodedecode/abi_decode_simple_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg" -// gas irOptimized: 136231 +// gas irOptimized: 136127 // gas legacy: 137190 // gas legacyOptimized: 136082 diff --git a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol index a95183c30..ebd0144a1 100644 --- a/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/arrays_complex_from_and_to_storage.sol @@ -14,7 +14,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[3][]): 0x20, 0x06, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12 -> 0x06 -// gas irOptimized: 191293 +// gas irOptimized: 189863 // gas legacy: 211485 // gas legacyOptimized: 206394 // data(uint256,uint256): 0x02, 0x02 -> 0x09 diff --git a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol index b1b3a7bf4..9fcb58ad4 100644 --- a/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol +++ b/test/libsolidity/semanticTests/array/byte_array_storage_layout.sol @@ -47,7 +47,7 @@ contract c { // gas legacyOptimized: 58606 // storageEmpty -> 0 // test_long() -> 67 -// gas irOptimized: 91520 +// gas irOptimized: 90990 // gas legacy: 103590 // gas legacyOptimized: 101044 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol index 1f8e202e3..d94095054 100644 --- a/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol +++ b/test/libsolidity/semanticTests/array/byte_array_transitional_2.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 171767 +// gas irOptimized: 161154 // gas legacy: 189715 // gas legacyOptimized: 184472 diff --git a/test/libsolidity/semanticTests/array/bytes_length_member.sol b/test/libsolidity/semanticTests/array/bytes_length_member.sol index 0da89b36e..28f39416c 100644 --- a/test/libsolidity/semanticTests/array/bytes_length_member.sol +++ b/test/libsolidity/semanticTests/array/bytes_length_member.sol @@ -15,7 +15,7 @@ contract c { // ---- // getLength() -> 0 // set(): 1, 2 -> true -// gas irOptimized: 110570 +// gas irOptimized: 110451 // gas legacy: 110726 // gas legacyOptimized: 110567 // getLength() -> 68 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol index c7fb030aa..5e71647f4 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_calldata_storage.sol @@ -22,7 +22,7 @@ contract c { // compileViaYul: also // ---- // store(uint256[9],uint8[3][]): 21, 22, 23, 24, 25, 26, 27, 28, 29, 0x140, 4, 1, 2, 3, 11, 12, 13, 21, 22, 23, 31, 32, 33 -> 32 -// gas irOptimized: 651816 +// gas irOptimized: 651532 // gas legacy: 694515 // gas legacyOptimized: 694013 // retrieve() -> 9, 28, 9, 28, 4, 3, 32 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol index b9d5ccd96..7a7bf9cbe 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint128.sol @@ -23,6 +23,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 92958 +// gas irOptimized: 91272 // gas legacy: 93035 // gas legacyOptimized: 92257 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol index dddd14840..b0db23179 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_cleanup_uint40.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> true -// gas irOptimized: 154441 +// gas irOptimized: 146336 // gas legacy: 155961 // gas legacyOptimized: 153588 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol index fea48ca61..9d5ea2405 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 135505 +// gas irOptimized: 134523 // gas legacy: 135313 // gas legacyOptimized: 134548 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol index 55b3d39ba..685814275 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_clear_storage_packed.sol @@ -42,11 +42,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0 -// gas irOptimized: 92966 +// gas irOptimized: 91293 // gas legacy: 93006 // gas legacyOptimized: 92261 // g() -> 0 // h() -> 0 -// gas irOptimized: 93012 +// gas irOptimized: 91380 // gas legacy: 93028 // gas legacyOptimized: 92303 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol index 9542662ed..52f68282c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_different_packing.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x05000000000000000000000000000000000000000000000000 -// gas irOptimized: 214644 +// gas irOptimized: 210357 // gas legacy: 221883 // gas legacyOptimized: 220734 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol index a77aaedd6..cdd9b55d4 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_including_array.sol @@ -37,12 +37,12 @@ contract c { // compileViaYul: also // ---- // test() -> 0x02000202 -// gas irOptimized: 4690992 +// gas irOptimized: 4682282 // gas legacy: 4578341 // gas legacyOptimized: 4548354 // storageEmpty -> 1 // clear() -> 0, 0 -// gas irOptimized: 4516821 +// gas irOptimized: 4506598 // gas legacy: 4410769 // gas legacyOptimized: 4382531 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol index f6c53a9f8..d9095cb4e 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_nested_array.sol @@ -15,6 +15,6 @@ contract c { // compileViaYul: also // ---- // test(uint256[2][]): 32, 3, 7, 8, 9, 10, 11, 12 -> 10 -// gas irOptimized: 691977 +// gas irOptimized: 690179 // gas legacy: 686268 // gas legacyOptimized: 685688 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol index e67fe2411..3d802087b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base.sol @@ -19,6 +19,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 226467 +// gas irOptimized: 225242 // gas legacy: 233801 // gas legacyOptimized: 232816 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol index a0a1844ff..82987af7b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_different_base_nested.sol @@ -24,6 +24,6 @@ contract c { // compileViaYul: also // ---- // test() -> 3, 4 -// gas irOptimized: 191858 +// gas irOptimized: 190637 // gas legacy: 195353 // gas legacyOptimized: 192441 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol index e9ad1e78f..40ce42999 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dyn_dyn.sol @@ -17,7 +17,7 @@ contract c { // ---- // setData1(uint256,uint256,uint256): 10, 5, 4 -> // copyStorageStorage() -> -// gas irOptimized: 111563 +// gas irOptimized: 111429 // gas legacy: 109278 // gas legacyOptimized: 109268 // getData2(uint256): 5 -> 10, 4 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol index 47d682bf0..90ea313d9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_dynamic_dynamic.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4 -// gas irOptimized: 272786 +// gas irOptimized: 272096 // gas legacy: 270834 // gas legacyOptimized: 269960 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol index 72ac4201e..76bbe1354 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_dynamic.sol @@ -14,6 +14,6 @@ contract c { // compileViaYul: also // ---- // test() -> 9, 4 -// gas irOptimized: 123375 +// gas irOptimized: 123221 // gas legacy: 123579 // gas legacyOptimized: 123208 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol index 06296e358..89a96426c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_static_static.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 8, 0 -// gas irOptimized: 236656 +// gas irOptimized: 236388 // gas legacy: 234695 // gas legacyOptimized: 234103 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol index fd5c398a1..dbf8d6fa3 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_storage_struct.sol @@ -19,7 +19,7 @@ contract c { // compileViaYul: also // ---- // test() -> 4, 5 -// gas irOptimized: 240552 +// gas irOptimized: 239059 // gas legacy: 238736 // gas legacyOptimized: 237159 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol index fcfc9ffc7..f2dc707a8 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_storage_to_memory_nested.sol @@ -17,6 +17,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 2, 0x40, 0xa0, 2, 0, 1, 2, 2, 3 -// gas irOptimized: 161991 +// gas irOptimized: 160944 // gas legacy: 162278 // gas legacyOptimized: 159955 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol index 311a74992..0c10f7385 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover.sol @@ -20,6 +20,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0xffffffff, 0x0000000000000000000000000a00090008000700060005000400030002000100, 0x0000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 140618 +// gas irOptimized: 126407 // gas legacy: 186406 // gas legacyOptimized: 166126 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol index 802b9a198..3d798df79 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_leftover2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x04000000000000000000000000000000000000000000000000, 0x0, 0x0 -// gas irOptimized: 95528 +// gas irOptimized: 92325 // gas legacy: 97451 // gas legacyOptimized: 94200 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol index 204981aa4..66dd5b670 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x0 -// gas irOptimized: 296092 +// gas irOptimized: 293911 // gas legacy: 303653 // gas legacyOptimized: 301999 diff --git a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol index 61480065f..f44795a3b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol +++ b/test/libsolidity/semanticTests/array/copying/array_copy_target_simple_2.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x01000000000000000000000000000000000000000000000000, 0x02000000000000000000000000000000000000000000000000, 0x03000000000000000000000000000000000000000000000000, 0x04000000000000000000000000000000000000000000000000, 0x00 -// gas irOptimized: 274785 +// gas irOptimized: 273418 // gas legacy: 276381 // gas legacyOptimized: 275453 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol index 55922af9a..4341b2df5 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_calldata_to_storage.sol @@ -38,10 +38,10 @@ contract c { // compileViaYul: true // ---- // test1(uint256[][]): 0x20, 2, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 182348 +// gas irOptimized: 180097 // test2(uint256[][2]): 0x20, 0x40, 0x40, 2, 23, 42 -> 2, 65 -// gas irOptimized: 158638 +// gas irOptimized: 157464 // test3(uint256[2][]): 0x20, 2, 23, 42, 23, 42 -> 2, 65 -// gas irOptimized: 135778 +// gas irOptimized: 134984 // test4(uint256[2][2]): 23, 42, 23, 42 -> 65 -// gas irOptimized: 111695 +// gas irOptimized: 111483 diff --git a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol index 4b7ce0928..cfc602019 100644 --- a/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_nested_memory_to_storage.sol @@ -40,12 +40,12 @@ contract Test { // compileViaYul: also // ---- // test() -> 24 -// gas irOptimized: 227891 +// gas irOptimized: 226186 // gas legacy: 227133 // gas legacyOptimized: 226547 // test1() -> 3 // test2() -> 6 // test3() -> 24 -// gas irOptimized: 134338 +// gas irOptimized: 133423 // gas legacy: 134295 // gas legacyOptimized: 133383 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol index 296789bdf..7f7948228 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_calldata_to_storage.sol @@ -17,4 +17,4 @@ contract C { // compileViaYul: true // ---- // f((uint128,uint64,uint128)[]): 0x20, 3, 0, 0, 12, 0, 11, 0, 10, 0, 0 -> 10, 11, 12 -// gas irOptimized: 121461 +// gas irOptimized: 120509 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol index f268484fd..9f71affb9 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_struct_memory_to_storage.sol @@ -19,4 +19,4 @@ contract C { // compileViaYul: true // ---- // f() -> 10, 11, 12 -// gas irOptimized: 120457 +// gas irOptimized: 119248 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol index 16f9aa7ba..45204390c 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_calldata_to_storage.sol @@ -23,4 +23,4 @@ contract C { // compileViaYul: true // ---- // f((uint256[])[]): 0x20, 3, 0x60, 0x60, 0x60, 0x20, 3, 1, 2, 3 -> 3, 1 -// gas irOptimized: 332878 +// gas irOptimized: 321914 diff --git a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol index 98a48270b..dd3b5429b 100644 --- a/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/array_of_structs_containing_arrays_memory_to_storage.sol @@ -26,4 +26,4 @@ contract C { // compileViaYul: true // ---- // f() -> 3, 3, 3, 1 -// gas irOptimized: 185077 +// gas irOptimized: 183750 diff --git a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol index 215ac9625..45063b11d 100644 --- a/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol +++ b/test/libsolidity/semanticTests/array/copying/array_storage_multi_items_per_slot.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3 -// gas irOptimized: 133671 +// gas irOptimized: 132265 // gas legacy: 134619 // gas legacyOptimized: 131940 diff --git a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol index c2f7faa4f..5588222c6 100644 --- a/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/arrays_from_and_to_storage.sol @@ -12,7 +12,7 @@ contract Test { // compileViaYul: also // ---- // set(uint24[]): 0x20, 18, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 -> 18 -// gas irOptimized: 101659 +// gas irOptimized: 99934 // gas legacy: 103815 // gas legacyOptimized: 101614 // data(uint256): 7 -> 8 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol index 254a16f31..04a782f43 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_inside_mappings.sol @@ -7,11 +7,11 @@ contract c { // compileViaYul: also // ---- // set(uint256): 1, 2 -> true -// gas irOptimized: 110824 +// gas irOptimized: 110621 // gas legacy: 111091 // gas legacyOptimized: 110736 // set(uint256): 2, 2, 3, 4, 5 -> true -// gas irOptimized: 177811 +// gas irOptimized: 177590 // gas legacy: 178021 // gas legacyOptimized: 177666 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol index f449e3bf6..4618a557e 100644 --- a/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/bytes_storage_to_storage.sol @@ -19,25 +19,25 @@ contract c { // ---- // f(uint256): 0 -> 0x20, 0x00 // f(uint256): 31 -> 0x20, 0x1f, 0x0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e00 -// gas irOptimized: 135396 +// gas irOptimized: 114862 // gas legacy: 124364 // gas legacyOptimized: 119898 // f(uint256): 32 -> 0x20, 0x20, 1780731860627700044960722568376592200742329637303199754547598369979440671 -// gas irOptimized: 142291 +// gas irOptimized: 121021 // gas legacy: 135431 // gas legacyOptimized: 130829 // f(uint256): 33 -> 0x20, 33, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x2000000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 149603 +// gas irOptimized: 127832 // gas legacy: 142238 // gas legacyOptimized: 137518 // f(uint256): 63 -> 0x20, 0x3f, 1780731860627700044960722568376592200742329637303199754547598369979440671, 14532552714582660066924456880521368950258152170031413196862950297402215316992 -// gas irOptimized: 174873 +// gas irOptimized: 133392 // gas legacy: 160728 // gas legacyOptimized: 152168 // f(uint256): 12 -> 0x20, 0x0c, 0x0102030405060708090a0b0000000000000000000000000000000000000000 // gas legacy: 59345 // gas legacyOptimized: 57279 // f(uint256): 129 -> 0x20, 0x81, 1780731860627700044960722568376592200742329637303199754547598369979440671, 0x202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f, 29063324697304692433803953038474361308315562010425523193971352996434451193439, 0x606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f, -57896044618658097711785492504343953926634992332820282019728792003956564819968 -// gas irOptimized: 452115 +// gas irOptimized: 367467 // gas legacy: 423017 // gas legacyOptimized: 406021 diff --git a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol index 58e1b4d57..81f1d0e61 100644 --- a/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/calldata_array_dynamic_to_storage.sol @@ -11,6 +11,6 @@ contract C { // compileViaYul: also // ---- // f(uint256[]): 0x20, 0x03, 0x1, 0x2, 0x3 -> 0x1 -// gas irOptimized: 111384 +// gas irOptimized: 111103 // gas legacy: 111565 // gas legacyOptimized: 111347 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol index 4adf028b1..19149a634 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_in_struct_to_storage.sol @@ -37,11 +37,11 @@ contract C { // compileViaYul: also // ---- // f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000 -// gas irOptimized: 180274 +// gas irOptimized: 180098 // gas legacy: 180694 // gas legacyOptimized: 180088 // g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000 -// gas irOptimized: 107618 +// gas irOptimized: 107525 // gas legacy: 107895 // gas legacyOptimized: 107254 // h() -> 0x40, 0x60, 0x00, 0x00 diff --git a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol index 8b7282243..14909bb8a 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_byte_array_to_storage.sol @@ -48,6 +48,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0xff -// gas irOptimized: 122009 +// gas irOptimized: 120116 // gas legacy: 126745 // gas legacyOptimized: 123476 diff --git a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol index f10a49fdb..645f8fafe 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_function_storage_array.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // test() -> 7 -// gas irOptimized: 127846 +// gas irOptimized: 126713 // gas legacy: 205196 // gas legacyOptimized: 204987 diff --git a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol index 7e85e2323..c2e38e9e5 100644 --- a/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol +++ b/test/libsolidity/semanticTests/array/copying/copy_removes_bytes_data.sol @@ -9,7 +9,7 @@ contract c { // compileViaYul: also // ---- // set(): 1, 2, 3, 4, 5 -> true -// gas irOptimized: 177557 +// gas irOptimized: 177429 // gas legacy: 177656 // gas legacyOptimized: 177496 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol index 52141bd48..1b3ebf106 100644 --- a/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol +++ b/test/libsolidity/semanticTests/array/copying/memory_dyn_2d_bytes_to_storage.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 3 -// gas irOptimized: 134208 +// gas irOptimized: 128887 // gas legacy: 130307 // gas legacyOptimized: 129363 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol index 2e58d2d26..d759ca035 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 209108 +// gas irOptimized: 205948 // gas legacy: 212325 // gas legacyOptimized: 211486 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol index 868e8646c..da11093f5 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_bytes.sol @@ -13,6 +13,6 @@ contract C { // compileViaYul: also // ---- // f() -> 0x20, 0x02, 0x40, 0x80, 3, 0x6162630000000000000000000000000000000000000000000000000000000000, 0x99, 44048183304486788312148433451363384677562265908331949128489393215789685032262, 32241931068525137014058842823026578386641954854143559838526554899205067598957, 49951309422467613961193228765530489307475214998374779756599339590522149884499, 0x54555658595a6162636465666768696a6b6c6d6e6f707172737475767778797a, 0x4142434445464748494a4b4c4d4e4f5051525354555658595a00000000000000 -// gas irOptimized: 203063 +// gas irOptimized: 203008 // gas legacy: 204459 // gas legacyOptimized: 203437 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol index a3530af69..aae9f5d1d 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_from_pointer.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> 1, 2, 3, 4, 5, 6, 7 -// gas irOptimized: 209108 +// gas irOptimized: 205948 // gas legacy: 212330 // gas legacyOptimized: 211491 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol index b32332846..4e3c9ba9f 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_nested_struct.sol @@ -26,6 +26,6 @@ contract C { // compileViaYul: also // ---- // f() -> 11, 0x0c, 1, 0x15, 22, 4 -// gas irOptimized: 293695 +// gas irOptimized: 291768 // gas legacy: 293516 // gas legacyOptimized: 290263 diff --git a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol index e75a92e73..ab15fde1c 100644 --- a/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol +++ b/test/libsolidity/semanticTests/array/copying/storage_memory_packed_dyn.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> 2, 3, 4 -// gas irOptimized: 115383 +// gas irOptimized: 118794 // gas legacy: 126449 // gas legacyOptimized: 120902 diff --git a/test/libsolidity/semanticTests/array/create_memory_array.sol b/test/libsolidity/semanticTests/array/create_memory_array.sol index 72c4d0aca..bd061aa3f 100644 --- a/test/libsolidity/semanticTests/array/create_memory_array.sol +++ b/test/libsolidity/semanticTests/array/create_memory_array.sol @@ -20,6 +20,6 @@ contract C { // compileViaYul: also // ---- // f() -> "A", 8, 4, "B" -// gas irOptimized: 150997 +// gas irOptimized: 128810 // gas legacy: 121398 // gas legacyOptimized: 115494 diff --git a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol index d4ce9120c..67a89baf8 100644 --- a/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol +++ b/test/libsolidity/semanticTests/array/delete/bytes_delete_element.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test1() -> true -// gas irOptimized: 244579 +// gas irOptimized: 212092 // gas legacy: 255577 // gas legacyOptimized: 248611 diff --git a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol index 92c0fb40b..a76edc963 100644 --- a/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol +++ b/test/libsolidity/semanticTests/array/delete/delete_storage_array_packed.sol @@ -16,4 +16,4 @@ contract C { // compileViaYul: also // ---- // f() -> 0, 0, 0 -// gas irOptimized: 91179 +// gas irOptimized: 90107 diff --git a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol index 3259c72a4..46e3606ba 100644 --- a/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_array_cleanup.sol @@ -16,7 +16,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 520998 +// gas irOptimized: 520360 // gas legacy: 521773 // gas legacyOptimized: 517048 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol index 300616ecf..6ff4b9639 100644 --- a/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol +++ b/test/libsolidity/semanticTests/array/dynamic_arrays_in_storage.sol @@ -44,7 +44,7 @@ contract c { // ---- // getLengths() -> 0, 0 // setLengths(uint256,uint256): 48, 49 -> -// gas irOptimized: 108326 +// gas irOptimized: 103558 // gas legacy: 108571 // gas legacyOptimized: 100417 // getLengths() -> 48, 49 diff --git a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol index 6bceda899..a3d49eda9 100644 --- a/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/dynamic_multi_array_cleanup.sol @@ -18,7 +18,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> 8 -// gas irOptimized: 124480 +// gas irOptimized: 116558 // gas legacy: 121756 // gas legacyOptimized: 120687 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol index 0147ac446..c79afa22e 100644 --- a/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol +++ b/test/libsolidity/semanticTests/array/fixed_array_cleanup.sol @@ -13,7 +13,7 @@ contract c { // ---- // storageEmpty -> 1 // fill() -> -// gas irOptimized: 465878 +// gas irOptimized: 465538 // gas legacy: 471460 // gas legacyOptimized: 467520 // storageEmpty -> 0 diff --git a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol index 199bb1dce..b7d7927e8 100644 --- a/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol +++ b/test/libsolidity/semanticTests/array/fixed_arrays_as_return_type.sol @@ -21,6 +21,6 @@ contract B { // compileViaYul: also // ---- // f() -> 2, 3, 4, 5, 6, 1000, 1001, 1002, 1003, 1004 -// gas irOptimized: 133483 +// gas irOptimized: 116423 // gas legacy: 235167 // gas legacyOptimized: 133299 diff --git a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol index 63366e934..87fa7405a 100644 --- a/test/libsolidity/semanticTests/array/function_array_cross_calls.sol +++ b/test/libsolidity/semanticTests/array/function_array_cross_calls.sol @@ -45,6 +45,6 @@ contract C { // compileViaYul: also // ---- // test() -> 5, 6, 7 -// gas irOptimized: 337455 +// gas irOptimized: 314380 // gas legacy: 463662 // gas legacyOptimized: 296513 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol index b8f1ebaee..e1278e702 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_array_transition.sol @@ -25,7 +25,7 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3 -// gas irOptimized: 2280897 +// gas irOptimized: 2270841 // gas legacy: 2273722 // gas legacyOptimized: 2262396 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol index 3dbb0e0b6..fff6e7dc3 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint16_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 38, 28, 18 -// gas irOptimized: 195867 +// gas irOptimized: 187932 // gas legacy: 189780 // gas legacyOptimized: 178870 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol index e40577929..da5928ac0 100644 --- a/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol +++ b/test/libsolidity/semanticTests/array/pop/array_pop_uint24_transition.sol @@ -20,7 +20,7 @@ contract c { // compileViaYul: also // ---- // test() -> 20, 10 -// gas irOptimized: 163721 +// gas irOptimized: 159134 // gas legacy: 159459 // gas legacyOptimized: 153281 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol index 7923cf34b..a8ce78a8b 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_copy_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 29, 0x0303030303030303030303030303030303030303030303030303030303000000 -// gas irOptimized: 112526 +// gas irOptimized: 111672 // gas legacy: 127309 // gas legacyOptimized: 124136 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol index 2fdd7ebf7..4bc2121a9 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty.sol @@ -18,7 +18,7 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 219418 +// gas irOptimized: 184772 // gas legacy: 229864 // gas legacyOptimized: 210964 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol index c3cb9a227..1f0e3e9cf 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_long_storage_empty_garbage_ref.sol @@ -17,7 +17,7 @@ contract c { // compileViaYul: also // ---- // test() -> -// gas irOptimized: 150914 +// gas irOptimized: 146901 // gas legacy: 165363 // gas legacyOptimized: 159446 // storageEmpty -> 1 diff --git a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol index 0a361e81d..58efe4e32 100644 --- a/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol +++ b/test/libsolidity/semanticTests/array/pop/byte_array_pop_masking_long.sol @@ -12,6 +12,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0x20, 33, 0x303030303030303030303030303030303030303030303030303030303030303, 0x0300000000000000000000000000000000000000000000000000000000000000 -// gas irOptimized: 110514 +// gas irOptimized: 109293 // gas legacy: 126187 // gas legacyOptimized: 123261 diff --git a/test/libsolidity/semanticTests/array/push/array_push.sol b/test/libsolidity/semanticTests/array/push/array_push.sol index 33f923081..db234266e 100644 --- a/test/libsolidity/semanticTests/array/push/array_push.sol +++ b/test/libsolidity/semanticTests/array/push/array_push.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test() -> 5, 4, 3, 3 -// gas irOptimized: 111269 +// gas irOptimized: 110866 // gas legacy: 111838 // gas legacyOptimized: 111128 diff --git a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol index 72c69233a..85f8fe143 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_nested_from_calldata.sol @@ -14,6 +14,6 @@ contract C { // compileViaYul: also // ---- // f(uint120[]): 0x20, 3, 1, 2, 3 -> 1 -// gas irOptimized: 113684 +// gas irOptimized: 112175 // gas legacy: 113686 // gas legacyOptimized: 113499 diff --git a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol index 5168297ce..5b8bea17b 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_packed_array.sol @@ -16,6 +16,6 @@ contract c { // compileViaYul: also // ---- // test() -> 1, 2, 3, 4 -// gas irOptimized: 93083 +// gas irOptimized: 91505 // gas legacy: 92798 // gas legacyOptimized: 92062 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct.sol b/test/libsolidity/semanticTests/array/push/array_push_struct.sol index a9088e703..cf710c1fa 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct.sol @@ -22,6 +22,6 @@ contract c { // compileViaYul: also // ---- // test() -> 2, 3, 4, 5 -// gas irOptimized: 138070 +// gas irOptimized: 136581 // gas legacy: 147484 // gas legacyOptimized: 146456 diff --git a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol index 1007bf491..da1fe3ca7 100644 --- a/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol +++ b/test/libsolidity/semanticTests/array/push/array_push_struct_from_calldata.sol @@ -18,6 +18,6 @@ contract c { // compileViaYul: also // ---- // test((uint16,uint16,uint16[3],uint16[])): 0x20, 2, 3, 0, 0, 4, 0xC0, 4, 0, 0, 5, 0, 0 -> 2, 3, 4, 5 -// gas irOptimized: 139798 +// gas irOptimized: 138718 // gas legacy: 144322 // gas legacyOptimized: 139171 diff --git a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol index e51336a36..515408ec2 100644 --- a/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol +++ b/test/libsolidity/semanticTests/array/push/byte_array_push_transition.sol @@ -17,6 +17,6 @@ contract c { // compileViaYul: also // ---- // test() -> 0 -// gas irOptimized: 195787 +// gas irOptimized: 178770 // gas legacy: 218028 // gas legacyOptimized: 205124 diff --git a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol index 45935109a..21d750a3b 100644 --- a/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol +++ b/test/libsolidity/semanticTests/array/push/nested_bytes_push.sol @@ -15,6 +15,6 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 180067 +// gas irOptimized: 179269 // gas legacy: 180620 // gas legacyOptimized: 180403 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol index f1621264b..28dd341fd 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_2d.sol @@ -29,14 +29,14 @@ contract C { // ---- // l() -> 0 // f(uint256,uint256): 42, 64 -> -// gas irOptimized: 116221 +// gas irOptimized: 113221 // gas legacy: 108234 // gas legacyOptimized: 102245 // l() -> 1 // ll(uint256): 0 -> 43 // a(uint256,uint256): 0, 42 -> 64 // f(uint256,uint256): 84, 128 -> -// gas irOptimized: 123537 +// gas irOptimized: 117765 // gas legacy: 107780 // gas legacyOptimized: 96331 // l() -> 2 diff --git a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol index 255bc0646..519831ef9 100644 --- a/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol +++ b/test/libsolidity/semanticTests/array/push/push_no_args_bytes.sol @@ -23,7 +23,7 @@ contract C { // ---- // l() -> 0 // g(uint256): 70 -> -// gas irOptimized: 194029 +// gas irOptimized: 189335 // gas legacy: 184991 // gas legacyOptimized: 180608 // l() -> 70 diff --git a/test/libsolidity/semanticTests/array/reusing_memory.sol b/test/libsolidity/semanticTests/array/reusing_memory.sol index a5ca40bfc..3d5af8409 100644 --- a/test/libsolidity/semanticTests/array/reusing_memory.sol +++ b/test/libsolidity/semanticTests/array/reusing_memory.sol @@ -26,6 +26,6 @@ contract Main { // compileViaYul: also // ---- // f(uint256): 0x34 -> 0x46bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c1 -// gas irOptimized: 115243 +// gas irOptimized: 114323 // gas legacy: 126852 // gas legacyOptimized: 114079 diff --git a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol index 7d2f3cf78..387119622 100644 --- a/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol +++ b/test/libsolidity/semanticTests/constructor/arrays_in_constructors.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,address[]): 7, 0x40, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 -> 7, 8 -// gas irOptimized: 486618 +// gas irOptimized: 452561 // gas legacy: 592626 // gas legacyOptimized: 450224 diff --git a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol index 7b0ecfc38..8ad6433c2 100644 --- a/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol +++ b/test/libsolidity/semanticTests/constructor/bytes_in_constructors_packer.sol @@ -26,6 +26,6 @@ contract Creator { // compileViaYul: also // ---- // f(uint256,bytes): 7, 0x40, 78, "abcdefghijklmnopqrstuvwxyzabcdef", "ghijklmnopqrstuvwxyzabcdefghijkl", "mnopqrstuvwxyz" -> 7, "h" -// gas irOptimized: 336157 +// gas irOptimized: 307271 // gas legacy: 429173 // gas legacyOptimized: 298384 diff --git a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol index 10b87a9e0..424f86ea1 100644 --- a/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol +++ b/test/libsolidity/semanticTests/constructor/no_callvalue_check.sol @@ -19,6 +19,6 @@ contract C { // compileViaYul: also // ---- // f(), 2000 ether -> true -// gas irOptimized: 123743 +// gas irOptimized: 123029 // gas legacy: 123226 // gas legacyOptimized: 123092 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol index 43ad75580..4dc58c955 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage.sol @@ -15,6 +15,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 115211 +// gas irOptimized: 113763 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol index 5c48bcb02..de61c01b0 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_array_storage_v2.sol @@ -16,6 +16,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[]): 0x20, 0x03, 0x2a, 0x2b, 0x2c -// gas irOptimized: 115211 +// gas irOptimized: 113763 // gas legacy: 116393 // gas legacyOptimized: 114415 diff --git a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol index 409136b3d..27b8aa8df 100644 --- a/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol +++ b/test/libsolidity/semanticTests/events/event_dynamic_nested_array_storage_v2.sol @@ -17,6 +17,6 @@ contract C { // ---- // createEvent(uint256): 42 -> // ~ emit E(uint256[][]): 0x20, 0x02, 0x40, 0xa0, 0x02, 0x2a, 0x2b, 0x02, 0x2c, 0x2d -// gas irOptimized: 185905 +// gas irOptimized: 183740 // gas legacy: 187621 // gas legacyOptimized: 184551 diff --git a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol index e816a4961..e2d51253e 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_mixed.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_mixed.sol @@ -13,6 +13,6 @@ contract C { // ---- // deposit() -> // ~ emit E(uint256,uint256,uint256,bytes): #0x02, 0x01, 0x03, 0x60, 0x03, "def" -// gas irOptimized: 23685 +// gas irOptimized: 23672 // gas legacy: 24170 // gas legacyOptimized: 23753 diff --git a/test/libsolidity/semanticTests/events/event_indexed_string.sol b/test/libsolidity/semanticTests/events/event_indexed_string.sol index be275081b..16cc35fa5 100644 --- a/test/libsolidity/semanticTests/events/event_indexed_string.sol +++ b/test/libsolidity/semanticTests/events/event_indexed_string.sol @@ -19,6 +19,6 @@ contract C { // ---- // deposit() -> // ~ emit E(string,uint256[4]): #0xa7fb06bb999a5eb9aff9e0779953f4e1e4ce58044936c2f51c7fb879b85c08bd, #0xe755d8cc1a8cde16a2a31160dcd8017ac32d7e2f13215b29a23cdae40a78aa81 -// gas irOptimized: 368478 +// gas irOptimized: 344935 // gas legacy: 390742 // gas legacyOptimized: 376774 diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol index dc356f003..489ac57d5 100644 --- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol +++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol @@ -178,35 +178,35 @@ contract DepositContract is IDepositContract, ERC165 { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1805935 +// gas irOptimized: 1624131 // gas legacy: 2580394 -// gas legacyOptimized: 1803757 +// gas legacyOptimized: 1775403 // supportsInterface(bytes4): 0x0 -> 0 // supportsInterface(bytes4): 0xffffffff00000000000000000000000000000000000000000000000000000000 -> false # defined to be false by ERC-165 # // supportsInterface(bytes4): 0x01ffc9a700000000000000000000000000000000000000000000000000000000 -> true # ERC-165 id # // supportsInterface(bytes4): 0x8564090700000000000000000000000000000000000000000000000000000000 -> true # the deposit interface id # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 127482 +// gas irOptimized: 120024 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 # TODO: check balance and logs after each deposit # // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0 -> FAILURE # Empty input # // get_deposit_root() -> 0xd70a234731285c6804c2a4f56711ddb8c82c99740f207854891028af34e27e5e -// gas irOptimized: 127482 +// gas irOptimized: 120024 // gas legacy: 150465 // gas legacyOptimized: 122798 // get_deposit_count() -> 0x20, 8, 0 // deposit(bytes,bytes,bytes,bytes32), 1 ether: 0x80, 0xe0, 0x120, 0xaa4a8d0b7d9077248630f1a4701ae9764e42271d7f22b7838778411857fd349e, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0x00f50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8 -> # txhash: 0x7085c586686d666e8bb6e9477a0f0b09565b2060a11f1c4209d3a52295033832 # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0x933ad9491b62059dd065b560d256d8957a8c402cc6e8d8ee7290ae11e8f73292, 0x67a8811c397529dac52ae1342ba58c9500000000000000000000000000000000, 0x20, 0xf50428677c60f997aadeab24aabf7fceaef491c96a52b463ae91f95611cf71, 0x08, 0xca9a3b00000000000000000000000000000000000000000000000000000000, 0x60, 0xa29d01cc8c6296a8150e515b5995390ef841dc18948aa3e79be6d7c1851b4cbb, 0x5d6ff49fa70b9c782399506a22a85193151b9b691245cebafd2063012443c132, 0x4b6c36debaedefb7b2d71b0503ffdc00150aaffd42e63358238ec888901738b8, 0x08, 0x00 // get_deposit_root() -> 0x2089653123d9c721215120b6db6738ba273bbc5228ac093b1f983badcdc8a438 -// gas irOptimized: 127486 +// gas irOptimized: 120015 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0100000000000000000000000000000000000000000000000000000000000000 // deposit(bytes,bytes,bytes,bytes32), 32 ether: 0x80, 0xe0, 0x120, 0xdbd986dc85ceb382708cf90a3500f500f0a393c5ece76963ac3ed72eccd2c301, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x00344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d -> # txhash: 0x404d8e109822ce448e68f45216c12cb051b784d068fbe98317ab8e50c58304ac # // ~ emit DepositEvent(bytes,bytes,bytes,bytes,bytes): 0xa0, 0x0100, 0x0140, 0x0180, 0x0200, 0x30, 0xb2ce0f79f90e7b3a113ca5783c65756f96c4b4673c2b5c1eb4efc22280259441, 0x06d601211e8866dc5b50dc48a244dd7c00000000000000000000000000000000, 0x20, 0x344b6c73f71b11c56aba0d01b7d8ad83559f209d0a4101a515f6ad54c89771, 0x08, 0x40597307000000000000000000000000000000000000000000000000000000, 0x60, 0x945caaf82d18e78c033927d51f452ebcd76524497b91d7a11219cb3db6a1d369, 0x7595fc095ce489e46b2ef129591f2f6d079be4faaf345a02c5eb133c072e7c56, 0x0c6c3617eee66b4b878165c502357d49485326bc6b31bc96873f308c8f19c09d, 0x08, 0x0100000000000000000000000000000000000000000000000000000000000000 // get_deposit_root() -> 0x40255975859377d912c53aa853245ebd939bdd2b33a28e084babdcc1ed8238ee -// gas irOptimized: 127486 +// gas irOptimized: 120015 // gas legacy: 150475 // gas legacyOptimized: 122811 // get_deposit_count() -> 0x20, 8, 0x0200000000000000000000000000000000000000000000000000000000000000 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol index 0ecd69fb3..70faa914d 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_signed.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 2171167 +// gas irOptimized: 2146563 // gas legacy: 2602700 -// gas legacyOptimized: 1900162 +// gas legacyOptimized: 1874490 // div(int256,int256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22303 +// gas irOptimized: 22091 // gas legacy: 22767 // gas legacyOptimized: 22282 // exp(int256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 25094 +// gas irOptimized: 25080 // gas legacy: 25203 // gas legacyOptimized: 24357 // exp2(int256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24808 +// gas irOptimized: 24761 // gas legacy: 24864 // gas legacyOptimized: 24110 // gm(int256,int256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23573 +// gas irOptimized: 22742 // gas legacy: 23228 // gas legacyOptimized: 22683 // log10(int256): 3141592653589793238 -> 4971498726941338506 -// gas irOptimized: 31328 +// gas irOptimized: 31156 // gas legacy: 32934 // gas legacyOptimized: 30323 // log2(int256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 29484 +// gas irOptimized: 29361 // gas legacy: 31067 // gas legacyOptimized: 28426 // mul(int256,int256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22414 +// gas irOptimized: 22308 // gas legacy: 22807 // gas legacyOptimized: 22295 // pow(int256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22974 +// gas irOptimized: 22689 // gas legacy: 23508 // gas legacyOptimized: 22921 // sqrt(int256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 23246 +// gas irOptimized: 22337 // gas legacy: 22802 // gas legacyOptimized: 22422 // benchmark(int256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 43323 +// gas irOptimized: 33920 // gas legacy: 36673 // gas legacyOptimized: 34729 diff --git a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol index eb749c68a..d9c98bbc4 100644 --- a/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol +++ b/test/libsolidity/semanticTests/externalContracts/prbmath_unsigned.sol @@ -50,46 +50,46 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 1961108 +// gas irOptimized: 1916328 // gas legacy: 2356230 -// gas legacyOptimized: 1770105 +// gas legacyOptimized: 1746528 // div(uint256,uint256): 3141592653589793238, 88714123 -> 35412542528203691288251815328 -// gas irOptimized: 22103 +// gas irOptimized: 21925 // gas legacy: 22497 // gas legacyOptimized: 22010 // exp(uint256): 3141592653589793238 -> 23140692632779268978 -// gas irOptimized: 24981 +// gas irOptimized: 24850 // gas legacy: 25104 // gas legacyOptimized: 24258 // exp2(uint256): 3141592653589793238 -> 8824977827076287620 -// gas irOptimized: 24746 +// gas irOptimized: 24608 // gas legacy: 24814 // gas legacyOptimized: 24062 // gm(uint256,uint256): 3141592653589793238, 88714123 -> 16694419339601 -// gas irOptimized: 23575 +// gas irOptimized: 22844 // gas legacy: 23269 // gas legacyOptimized: 22724 // log10(uint256): 3141592653589793238 -> 0x44fe4fc084a52b8a -// gas irOptimized: 30936 +// gas irOptimized: 30474 // gas legacy: 32898 // gas legacyOptimized: 29925 // log2(uint256): 3141592653589793238 -> 1651496129472318782 -// gas irOptimized: 28838 +// gas irOptimized: 28344 // gas legacy: 30986 // gas legacyOptimized: 28001 // mul(uint256,uint256): 3141592653589793238, 88714123 -> 278703637 -// gas irOptimized: 22146 +// gas irOptimized: 22001 // gas legacy: 22604 // gas legacyOptimized: 22090 // pow(uint256,uint256): 3141592653589793238, 5 -> 306019684785281453040 -// gas irOptimized: 22653 +// gas irOptimized: 22420 // gas legacy: 23245 // gas legacyOptimized: 22646 // sqrt(uint256): 3141592653589793238 -> 1772453850905516027 -// gas irOptimized: 23264 +// gas irOptimized: 22570 // gas legacy: 22820 // gas legacyOptimized: 22440 // benchmark(uint256): 3141592653589793238 -> 998882724338592125, 1000000000000000000, 1000000000000000000 -// gas irOptimized: 42063 +// gas irOptimized: 35080 // gas legacy: 35385 // gas legacyOptimized: 33449 diff --git a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol index bb56101aa..9550127bd 100644 --- a/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol +++ b/test/libsolidity/semanticTests/externalContracts/ramanujan_pi.sol @@ -35,10 +35,10 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 591094 +// gas irOptimized: 530581 // gas legacy: 733634 -// gas legacyOptimized: 498033 +// gas legacyOptimized: 478742 // prb_pi() -> 3141592656369545286 -// gas irOptimized: 66108 +// gas irOptimized: 58438 // gas legacy: 98903 // gas legacyOptimized: 75735 diff --git a/test/libsolidity/semanticTests/externalContracts/snark.sol b/test/libsolidity/semanticTests/externalContracts/snark.sol index 94e3e781c..2de28f943 100644 --- a/test/libsolidity/semanticTests/externalContracts/snark.sol +++ b/test/libsolidity/semanticTests/externalContracts/snark.sol @@ -297,6 +297,6 @@ contract Test { // pair() -> true // verifyTx() -> true // ~ emit Verified(string): 0x20, 0x16, "Successfully verified." -// gas irOptimized: 111439 +// gas irOptimized: 89789 // gas legacy: 114094 // gas legacyOptimized: 83670 diff --git a/test/libsolidity/semanticTests/externalContracts/strings.sol b/test/libsolidity/semanticTests/externalContracts/strings.sol index 1f209ef6f..e0714671e 100644 --- a/test/libsolidity/semanticTests/externalContracts/strings.sol +++ b/test/libsolidity/semanticTests/externalContracts/strings.sol @@ -51,26 +51,26 @@ contract test { // compileViaYul: also // ---- // constructor() -// gas irOptimized: 912777 +// gas irOptimized: 824381 // gas legacy: 1188228 -// gas legacyOptimized: 771634 +// gas legacyOptimized: 749336 // toSlice(string): 0x20, 11, "hello world" -> 11, 0xa0 -// gas irOptimized: 22877 +// gas irOptimized: 22628 // gas legacy: 23190 // gas legacyOptimized: 22508 // roundtrip(string): 0x20, 11, "hello world" -> 0x20, 11, "hello world" -// gas irOptimized: 23676 +// gas irOptimized: 23485 // gas legacy: 23820 // gas legacyOptimized: 23123 // utf8len(string): 0x20, 16, "\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83\xf0\x9f\x98\x83" -> 4 # Input: "😃😃😃😃" # -// gas irOptimized: 24779 +// gas irOptimized: 24119 // gas legacy: 25716 // gas legacyOptimized: 24115 // multiconcat(string,uint256): 0x40, 3, 11, "hello world" -> 0x20, 0x58, 0x68656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f726c, 0x6468656c6c6f20776f726c6468656c6c6f20776f726c6468656c6c6f20776f72, 49027192869463622675296414541903001712009715982962058146354235762728281047040 # concatenating 3 times # -// gas irOptimized: 29729 +// gas irOptimized: 28865 // gas legacy: 31621 // gas legacyOptimized: 27914 // benchmark(string,bytes32): 0x40, 0x0842021, 8, "solidity" -> 0x2020 -// gas irOptimized: 2903627 +// gas irOptimized: 1952705 // gas legacy: 4381235 // gas legacyOptimized: 2317529 diff --git a/test/libsolidity/semanticTests/functionCall/failed_create.sol b/test/libsolidity/semanticTests/functionCall/failed_create.sol index 747afe8a6..87a88db9c 100644 --- a/test/libsolidity/semanticTests/functionCall/failed_create.sol +++ b/test/libsolidity/semanticTests/functionCall/failed_create.sol @@ -18,7 +18,7 @@ contract C { // compileViaYul: also // ---- // constructor(), 20 wei -// gas irOptimized: 259072 +// gas irOptimized: 218728 // gas legacy: 288299 // gas legacyOptimized: 177933 // f(uint256): 20 -> 1370859564726510389319704988634906228201275401179 @@ -26,7 +26,7 @@ contract C { // f(uint256): 20 -> FAILURE // x() -> 1 // stack(uint256): 1023 -> FAILURE -// gas irOptimized: 391236 +// gas irOptimized: 338027 // gas legacy: 535367 // gas legacyOptimized: 354656 // x() -> 1 diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol index d024a4edb..6839af670 100644 --- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol +++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol @@ -20,7 +20,7 @@ contract test { // compileViaYul: also // ---- // set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0 -// gas irOptimized: 112214 +// gas irOptimized: 111952 // gas legacy: 113806 // gas legacyOptimized: 111781 // get(uint8): 1 -> 21, 22, 42, 43 diff --git a/test/libsolidity/semanticTests/functionTypes/store_function.sol b/test/libsolidity/semanticTests/functionTypes/store_function.sol index 7318b5bc3..3cead8b47 100644 --- a/test/libsolidity/semanticTests/functionTypes/store_function.sol +++ b/test/libsolidity/semanticTests/functionTypes/store_function.sol @@ -28,6 +28,6 @@ contract C { // compileViaYul: also // ---- // t() -> 9 -// gas irOptimized: 100053 +// gas irOptimized: 99780 // gas legacy: 158997 // gas legacyOptimized: 108916 diff --git a/test/libsolidity/semanticTests/immutable/multi_creation.sol b/test/libsolidity/semanticTests/immutable/multi_creation.sol index aa3ca2606..5b3c58c63 100644 --- a/test/libsolidity/semanticTests/immutable/multi_creation.sol +++ b/test/libsolidity/semanticTests/immutable/multi_creation.sol @@ -29,7 +29,7 @@ contract C { // compileViaYul: also // ---- // f() -> 3, 7, 5 -// gas irOptimized: 128980 +// gas irOptimized: 129086 // gas legacy: 151590 // gas legacyOptimized: 125422 // x() -> 7 diff --git a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol index 00998cdf1..7dd9db919 100644 --- a/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol +++ b/test/libsolidity/semanticTests/inheritance/address_overload_resolution.sol @@ -23,8 +23,8 @@ contract D { // compileViaYul: also // ---- // f() -> 1 -// gas irOptimized: 85304 +// gas irOptimized: 78517 // gas legacy: 115012 // g() -> 5 -// gas irOptimized: 85400 +// gas irOptimized: 78547 // gas legacy: 115472 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol index 804e7197f..c79a9f1a0 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_calldata_interface.sol @@ -25,5 +25,5 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 89435 +// gas irOptimized: 85155 // gas legacy: 125609 diff --git a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol index 98b33cd5b..eaaf03404 100644 --- a/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol +++ b/test/libsolidity/semanticTests/inheritance/inherited_function_calldata_memory_interface.sol @@ -25,6 +25,6 @@ contract B { // compileViaYul: also // ---- // g() -> 42 -// gas irOptimized: 118458 +// gas irOptimized: 117193 // gas legacy: 186609 // gas legacyOptimized: 116151 diff --git a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol index f0d9aa8fe..c2beb3dc9 100644 --- a/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol +++ b/test/libsolidity/semanticTests/inlineAssembly/keccak_yul_optimization.sol @@ -26,10 +26,10 @@ contract C { // compileViaYul: also // ---- // f() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 22521 +// gas irOptimized: 22307 // gas legacy: 23385 // gas legacyOptimized: 23092 // g() -> 0xcdb56c384a9682c600315e3470157a4cf7638d0d33e9dae5c40ffd2644fc5a80 -// gas irOptimized: 21391 +// gas irOptimized: 21250 // gas legacy: 21462 // gas legacyOptimized: 21256 diff --git a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol index dd38a7ed8..12488e96c 100644 --- a/test/libsolidity/semanticTests/interface_inheritance_conversions.sol +++ b/test/libsolidity/semanticTests/interface_inheritance_conversions.sol @@ -37,10 +37,10 @@ contract C { // compileViaYul: also // ---- // convertParent() -> 1 -// gas irOptimized: 102437 +// gas irOptimized: 87376 // convertSubA() -> 1, 2 -// gas irOptimized: 103320 +// gas irOptimized: 88184 // gas legacy: 99303 // convertSubB() -> 1, 3 -// gas irOptimized: 103254 +// gas irOptimized: 88110 // gas legacy: 99237 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create.sol b/test/libsolidity/semanticTests/salted_create/salted_create.sol index be2d7bf35..79eb9d9ad 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create.sol @@ -22,6 +22,6 @@ contract A { // ---- // different_salt() -> true // same_salt() -> true -// gas irOptimized: 98438966 +// gas irOptimized: 98438924 // gas legacy: 98439116 // gas legacyOptimized: 98438970 diff --git a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol index 9c52a803a..b3930d060 100644 --- a/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol +++ b/test/libsolidity/semanticTests/salted_create/salted_create_with_value.sol @@ -22,6 +22,6 @@ contract A { // compileViaYul: also // ---- // f(), 10 ether -> 3007, 3008, 3009 -// gas irOptimized: 294879 +// gas irOptimized: 276235 // gas legacy: 422627 // gas legacyOptimized: 287856 diff --git a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol index 937f39e14..235df89c8 100644 --- a/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol +++ b/test/libsolidity/semanticTests/storage/packed_storage_structs_bytes.sol @@ -46,6 +46,6 @@ contract C { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 135766 +// gas irOptimized: 134021 // gas legacy: 136036 // gas legacyOptimized: 133480 diff --git a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol index ac1384b52..6036cc922 100644 --- a/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol +++ b/test/libsolidity/semanticTests/structs/calldata/calldata_struct_with_nested_array_to_storage.sol @@ -18,6 +18,6 @@ contract C { // compileViaYul: also // ---- // f(uint32,(uint128,uint256[][2],uint32)): 55, 0x40, 77, 0x60, 88, 0x40, 0x40, 2, 1, 2 -> 55, 77, 1, 2, 88 -// gas irOptimized: 204368 +// gas irOptimized: 202493 // gas legacy: 208666 // gas legacyOptimized: 203583 diff --git a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol index 1e291fef1..f9c00a297 100644 --- a/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol +++ b/test/libsolidity/semanticTests/structs/conversion/recursive_storage_memory.sol @@ -25,6 +25,6 @@ contract CopyTest { // compileViaYul: also // ---- // run() -> 2, 23, 42 -// gas irOptimized: 198438 +// gas irOptimized: 195015 // gas legacy: 186016 // gas legacyOptimized: 184668 diff --git a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol index 7fb2e8bd1..9a1778c39 100644 --- a/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol +++ b/test/libsolidity/semanticTests/structs/memory_structs_nested_load.sol @@ -69,7 +69,7 @@ contract Test { // compileViaYul: also // ---- // load() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 -// gas irOptimized: 111932 +// gas irOptimized: 110429 // gas legacy: 112999 // gas legacyOptimized: 110881 // store() -> 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 diff --git a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol index 3f13f23ca..c06fc7390 100644 --- a/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol +++ b/test/libsolidity/semanticTests/structs/struct_containing_bytes_copy_and_delete.sol @@ -25,7 +25,7 @@ contract c { // ---- // storageEmpty -> 1 // set(uint256,bytes,uint256): 12, 0x60, 13, 33, "12345678901234567890123456789012", "3" -> true -// gas irOptimized: 133905 +// gas irOptimized: 133717 // gas legacy: 134436 // gas legacyOptimized: 133879 // test(uint256): 32 -> "3" diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol index b54f07e09..53bdef7e5 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy.sol @@ -38,12 +38,12 @@ contract c { // compileViaYul: also // ---- // set(uint256): 7 -> true -// gas irOptimized: 110249 +// gas irOptimized: 110090 // gas legacy: 110616 // gas legacyOptimized: 110006 // retrieve(uint256): 7 -> 1, 3, 4, 2 // copy(uint256,uint256): 7, 8 -> true -// gas irOptimized: 118769 +// gas irOptimized: 118609 // gas legacy: 119166 // gas legacyOptimized: 118622 // retrieve(uint256): 7 -> 1, 3, 4, 2 diff --git a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol index 3d37f06d6..45211bce0 100644 --- a/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol +++ b/test/libsolidity/semanticTests/structs/struct_copy_via_local.sol @@ -21,6 +21,6 @@ contract c { // compileViaYul: also // ---- // test() -> true -// gas irOptimized: 110223 +// gas irOptimized: 109669 // gas legacy: 110627 // gas legacyOptimized: 109706 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol index ee226a0a9..75a2abcc6 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_nested_small.sol @@ -33,4 +33,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0, 0, 0 -// gas irOptimized: 117954 +// gas irOptimized: 117589 diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol index f40a76745..ad93c82f1 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_array.sol @@ -44,7 +44,7 @@ contract C { // compileViaYul: also // ---- // f() -> -// gas irOptimized: 121810 +// gas irOptimized: 121075 // gas legacy: 122132 // gas legacyOptimized: 121500 // g() -> diff --git a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol index 2c929bf2f..7d72b374f 100644 --- a/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol +++ b/test/libsolidity/semanticTests/structs/struct_delete_storage_with_arrays_small.sol @@ -27,4 +27,4 @@ contract C { // compileViaYul: true // ---- // f() -> 0 -// gas irOptimized: 112702 +// gas irOptimized: 111980 diff --git a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol index bf9034b12..b0773e78b 100644 --- a/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol +++ b/test/libsolidity/semanticTests/structs/struct_memory_to_storage_function_ptr.sol @@ -32,6 +32,6 @@ contract C { // compileViaYul: also // ---- // f() -> 42, 23, 34, 42, 42 -// gas irOptimized: 111210 +// gas irOptimized: 110158 // gas legacy: 112021 // gas legacyOptimized: 110548 diff --git a/test/libsolidity/semanticTests/structs/structs.sol b/test/libsolidity/semanticTests/structs/structs.sol index 3b49e6f7c..8b2771be4 100644 --- a/test/libsolidity/semanticTests/structs/structs.sol +++ b/test/libsolidity/semanticTests/structs/structs.sol @@ -32,7 +32,7 @@ contract test { // ---- // check() -> false // set() -> -// gas irOptimized: 134859 +// gas irOptimized: 134588 // gas legacy: 135277 // gas legacyOptimized: 134064 // check() -> true diff --git a/test/libsolidity/semanticTests/various/destructuring_assignment.sol b/test/libsolidity/semanticTests/various/destructuring_assignment.sol index 1f49d3128..ab1f53e02 100644 --- a/test/libsolidity/semanticTests/various/destructuring_assignment.sol +++ b/test/libsolidity/semanticTests/various/destructuring_assignment.sol @@ -36,6 +36,6 @@ contract C { // compileViaYul: also // ---- // f(bytes): 0x20, 0x5, "abcde" -> 0 -// gas irOptimized: 241728 +// gas irOptimized: 239570 // gas legacy: 240358 // gas legacyOptimized: 239682 diff --git a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol index 8213f346a..5d3adbd76 100644 --- a/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol +++ b/test/libsolidity/semanticTests/various/skip_dynamic_types_for_structs.sol @@ -22,6 +22,6 @@ contract C { // compileViaYul: also // ---- // g() -> 2, 6 -// gas irOptimized: 179260 +// gas irOptimized: 178857 // gas legacy: 180890 // gas legacyOptimized: 179609 diff --git a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol index b5f14e3cc..b93c12478 100644 --- a/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol +++ b/test/libsolidity/semanticTests/various/staticcall_for_view_and_pure.sol @@ -38,10 +38,10 @@ contract D { // f() -> 0x1 # This should work, next should throw # // gas legacy: 103844 // fview() -> FAILURE -// gas irOptimized: 98438645 +// gas irOptimized: 98438642 // gas legacy: 98438803 // gas legacyOptimized: 98438596 // fpure() -> FAILURE -// gas irOptimized: 98438646 +// gas irOptimized: 98438643 // gas legacy: 98438803 // gas legacyOptimized: 98438597 diff --git a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol index 165b4f006..5b4c6ff31 100644 --- a/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol +++ b/test/libsolidity/semanticTests/various/swap_in_storage_overwrite.sol @@ -30,7 +30,7 @@ contract c { // x() -> 0, 0 // y() -> 0, 0 // set() -> -// gas irOptimized: 109754 +// gas irOptimized: 109691 // gas legacy: 109732 // gas legacyOptimized: 109682 // x() -> 1, 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol index 1ed094157..4626695c1 100644 --- a/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_memory_index_access.sol @@ -28,7 +28,7 @@ contract C { // index(uint256): 10 -> true // index(uint256): 20 -> true // index(uint256): 0xFF -> true -// gas irOptimized: 167357 +// gas irOptimized: 143528 // gas legacy: 248854 // gas legacyOptimized: 152638 // accessIndex(uint256,int256): 10, 1 -> 2 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol index 669f8083c..38f44be79 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_access.sol @@ -18,33 +18,33 @@ contract C { // ---- // test_indices(uint256): 1 -> // test_indices(uint256): 129 -> -// gas irOptimized: 3070168 +// gas irOptimized: 2989821 // gas legacy: 3071205 // gas legacyOptimized: 3011873 // test_indices(uint256): 5 -> -// gas irOptimized: 373956 +// gas irOptimized: 371949 // gas legacy: 369241 // gas legacyOptimized: 366149 // test_indices(uint256): 10 -> // test_indices(uint256): 15 -> -// gas irOptimized: 76670 +// gas irOptimized: 67954 // test_indices(uint256): 0xFF -> -// gas irOptimized: 3511240 +// gas irOptimized: 3353039 // gas legacy: 3514167 // gas legacyOptimized: 3398107 // test_indices(uint256): 1000 -> -// gas irOptimized: 18591162 +// gas irOptimized: 17981281 // gas legacy: 18617999 // gas legacyOptimized: 18178944 // test_indices(uint256): 129 -> -// gas irOptimized: 2798783 +// gas irOptimized: 2730702 // gas legacy: 2772735 // gas legacyOptimized: 2716547 // test_indices(uint256): 128 -> -// gas irOptimized: 455997 +// gas irOptimized: 383265 // gas legacy: 467272 // gas legacyOptimized: 418424 // test_indices(uint256): 1 -> -// gas irOptimized: 368599 +// gas irOptimized: 368886 // gas legacy: 363407 // gas legacyOptimized: 361811 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol index c2e1e925e..abe3ab5e6 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_boundary_test.sol @@ -18,11 +18,11 @@ contract C { // test_boundary_check(uint256,uint256): 1, 1 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 10, 10 -> FAILURE, hex"4e487b71", 0x32 // test_boundary_check(uint256,uint256): 256, 256 -> FAILURE, hex"4e487b71", 0x32 -// gas irOptimized: 151436 +// gas irOptimized: 137880 // gas legacy: 131830 // gas legacyOptimized: 112054 // test_boundary_check(uint256,uint256): 256, 255 -> 0 -// gas irOptimized: 153717 +// gas irOptimized: 139966 // gas legacy: 134149 // gas legacyOptimized: 114233 // test_boundary_check(uint256,uint256): 256, 0xFFFF -> FAILURE, hex"4e487b71", 0x32 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol index 55f53d92c..78cc8941f 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_index_zeroed_test.sol @@ -54,18 +54,18 @@ contract C { // ---- // test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 5 -> -// gas irOptimized: 133918 +// gas irOptimized: 128454 // gas legacy: 132367 // gas legacyOptimized: 129586 // test_zeroed_indicies(uint256): 10 -> -// gas irOptimized: 179646 +// gas irOptimized: 169089 // gas legacy: 177329 // gas legacyOptimized: 172224 // test_zeroed_indicies(uint256): 15 -> -// gas irOptimized: 204956 +// gas irOptimized: 189364 // gas legacy: 201954 // gas legacyOptimized: 194604 // test_zeroed_indicies(uint256): 0xFF -> -// gas irOptimized: 6218066 +// gas irOptimized: 5947164 // gas legacy: 6163149 // gas legacyOptimized: 6029474 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol index b5479bc29..c18433da0 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_length_access.sol @@ -14,11 +14,11 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 105956 +// gas irOptimized: 97405 // gas legacy: 126722 // gas legacyOptimized: 107818 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 1367718 +// gas irOptimized: 1229387 // gas legacy: 1702119 // gas legacyOptimized: 1398420 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol index 5acbba8fd..d581290dd 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty.sol @@ -13,14 +13,14 @@ contract C { // compileViaYul: also // ---- // pushEmpty(uint256): 128 -// gas irOptimized: 430912 +// gas irOptimized: 370475 // gas legacy: 417287 // gas legacyOptimized: 399048 // pushEmpty(uint256): 256 -// gas irOptimized: 732164 +// gas irOptimized: 637295 // gas legacy: 715083 // gas legacyOptimized: 688908 -// pushEmpty(uint256): 38869 -> FAILURE # out-of-gas # +// pushEmpty(uint256): 48869 -> FAILURE # out-of-gas # // gas irOptimized: 100000000 // gas legacy: 100000000 // gas legacyOptimized: 100000000 diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol index 273c50814..9402cf909 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_empty_length_address.sol @@ -18,15 +18,15 @@ contract C { // set_get_length(uint256): 10 -> 10 // set_get_length(uint256): 20 -> 20 // set_get_length(uint256): 0 -> 0 -// gas irOptimized: 79199 +// gas irOptimized: 77835 // gas legacy: 77730 // gas legacyOptimized: 77162 // set_get_length(uint256): 0xFF -> 0xFF -// gas irOptimized: 155961 +// gas irOptimized: 143362 // gas legacy: 678237 // gas legacyOptimized: 115104 // set_get_length(uint256): 0xFFF -> 0xFFF -// gas irOptimized: 2013003 +// gas irOptimized: 1824739 // gas legacy: 9873774 // gas legacyOptimized: 1398546 // set_get_length(uint256): 0xFFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol index b0ae9700d..b4cb8f672 100644 --- a/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol +++ b/test/libsolidity/semanticTests/viaYul/array_storage_push_pop.sol @@ -15,15 +15,15 @@ contract C { // set_get_length(uint256): 1 -> 0 // set_get_length(uint256): 10 -> 0 // set_get_length(uint256): 20 -> 0 -// gas irOptimized: 88845 +// gas irOptimized: 86635 // gas legacy: 85822 // gas legacyOptimized: 83608 // set_get_length(uint256): 0xFF -> 0 -// gas irOptimized: 852360 +// gas irOptimized: 825475 // gas legacy: 810327 // gas legacyOptimized: 786258 // set_get_length(uint256): 0xFFF -> 0 -// gas irOptimized: 13328532 +// gas irOptimized: 12898447 // gas legacy: 12649059 // gas legacyOptimized: 12267870 // set_get_length(uint256): 0xFFFF -> FAILURE # Out-of-gas # diff --git a/test/libsolidity/semanticTests/viaYul/simple.sol b/test/libsolidity/semanticTests/viaYul/simple.sol new file mode 100644 index 000000000..ba9714fa8 --- /dev/null +++ b/test/libsolidity/semanticTests/viaYul/simple.sol @@ -0,0 +1,15 @@ +contract C { + fallback() external { + assembly { + function f(x, y) { mstore(0x00, x) mstore(0x20, y) } + f(0x42, 0x21) + return(0,0x40) + + } + } +} +// ==== +// allowNonExistingFunctions: true +// compileViaYul: true +// ---- +// f(uint256): 3 -> 0x42, 0x21 diff --git a/test/libyul/EVMCodeTransformTest.cpp b/test/libyul/EVMCodeTransformTest.cpp index 58a0c2795..127d07ac9 100644 --- a/test/libyul/EVMCodeTransformTest.cpp +++ b/test/libyul/EVMCodeTransformTest.cpp @@ -20,6 +20,9 @@ #include #include +#include + +#include #include @@ -57,7 +60,16 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _ return TestResult::FatalError; } - m_obtainedResult = evmasm::disassemble(stack.assemble(AssemblyStack::Machine::EVM).bytecode->bytecode, "\n"); + evmasm::Assembly assembly; + EthAssemblyAdapter adapter(assembly); + stack.compileEVM(adapter, m_stackOpt); + std::ostringstream output; + output << assembly; + m_obtainedResult = output.str(); + +/* + m_obtainedResult = evmasm::disassemble(stack.assemble(AssemblyStack::Machine::EVM).bytecode->bytecode, "\n"); +*/ return checkResult(_stream, _linePrefix, _formatted); } diff --git a/test/libyul/evmCodeTransform/optimizedCodeTransform/stub.yul b/test/libyul/evmCodeTransform/optimizedCodeTransform/stub.yul new file mode 100644 index 000000000..57dd09589 --- /dev/null +++ b/test/libyul/evmCodeTransform/optimizedCodeTransform/stub.yul @@ -0,0 +1,24 @@ +{ + { + let a := 42 + sstore(0,mload(calldataload(add(a, 43)))) + } +} +// ==== +// stackOptimization: true +// ---- +// /* "":64:66 */ +// 0x2b +// /* "":18:20 */ +// 0x2a +// /* "":57:67 */ +// add +// /* "":44:68 */ +// calldataload +// /* "":38:69 */ +// mload +// /* "":36:37 */ +// 0x00 +// /* "":29:70 */ +// sstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/for_1.yul b/test/libyul/evmCodeTransform/stackReuse/for_1.yul index e2f4ba128..891cba288 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_1.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_1.yul @@ -2,18 +2,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// pop(0x00) +// jump(tag_1) +// tag_1: +// /* "":38:39 */ +// pop(0x03) +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/for_2.yul b/test/libyul/evmCodeTransform/stackReuse/for_2.yul index f1f7460d4..65763690c 100644 --- a/test/libyul/evmCodeTransform/stackReuse/for_2.yul +++ b/test/libyul/evmCodeTransform/stackReuse/for_2.yul @@ -2,21 +2,12 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// JUMPDEST -// PUSH1 0x1 -// ISZERO -// PUSH1 0x14 -// JUMPI -// PUSH1 0x8 -// SWAP1 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// PUSH1 0x2 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// POP +// /* "":17:18 */ +// pop(0x00) +// jump(tag_1) +// tag_1: +// /* "":34:35 */ +// pop(0x08) +// /* "":45:46 */ +// pop(0x03) +// jump(tag_1) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul index 13048c020..6c9e03bdc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_argument_reuse.yul @@ -4,25 +4,22 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x17 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// DUP3 -// DUP2 -// SSTORE -// POP -// CALLVALUE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST +// stop +// /* "":6:86 */ +// tag_1: +// swap2 +// swap1 +// swap2 +// /* "":37:46 */ +// address +// /* "":33:47 */ +// pop +// /* "":48:60 */ +// sstore +// /* "":65:76 */ +// callvalue +// /* "":61:77 */ +// pop +// swap1 +// /* "":6:86 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_call.yul b/test/libyul/evmCodeTransform/stackReuse/function_call.yul index c14ccff36..621cfa48d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_call.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_call.yul @@ -6,28 +6,31 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x9 -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0xD -// JUMP -// JUMPDEST -// PUSH1 0x15 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x1F -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0xD -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP +// tag_1 +// /* "":20:21 */ +// 0x02 +// /* "":17:18 */ +// 0x01 +// /* "":15:22 */ +// tag_2 +// jump // in +// tag_1: +// pop +// tag_3 +// /* "":67:68 */ +// 0x04 +// /* "":64:65 */ +// 0x03 +// /* "":62:69 */ +// tag_2 +// jump // in +// tag_3: +// pop +// stop +// /* "":27:52 */ +// tag_2: +// pop +// pop +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul index aa4567a90..772ef6fad 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_many_arguments.yul @@ -25,92 +25,85 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x80 -// JUMP -// JUMPDEST -// DUP1 -// PUSH2 0x100 -// MSTORE -// POP -// DUP1 -// PUSH2 0x120 -// MSTORE -// POP -// DUP1 -// PUSH2 0x140 -// MSTORE -// POP -// DUP1 -// PUSH2 0x160 -// MSTORE -// POP -// DUP1 -// PUSH2 0x180 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x1E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x200 -// MSTORE -// POP -// DUP1 -// PUSH2 0x220 -// MSTORE -// POP -// DUP1 -// PUSH2 0x240 -// MSTORE -// POP -// DUP1 -// PUSH2 0x260 -// MSTORE -// POP -// DUP1 -// PUSH2 0x280 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2A0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2C0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x2E0 -// MSTORE -// POP -// DUP1 -// PUSH2 0x300 -// MSTORE -// POP -// DUP1 -// PUSH2 0x320 -// MSTORE -// POP -// DUP1 -// PUSH2 0x340 -// MSTORE -// POP -// PUSH1 0x0 -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP2 -// SWAP1 -// POP -// JUMP -// JUMPDEST +// stop +// /* "":6:660 */ +// tag_1: +// /* "":130:136 */ +// 0x0100 +// /* "":123:141 */ +// mstore +// /* "":157:163 */ +// 0x0120 +// /* "":150:168 */ +// mstore +// /* "":184:190 */ +// 0x0140 +// /* "":177:195 */ +// mstore +// /* "":211:217 */ +// 0x0160 +// /* "":204:222 */ +// mstore +// /* "":238:244 */ +// 0x0180 +// /* "":231:249 */ +// mstore +// /* "":265:271 */ +// 0x01a0 +// /* "":258:276 */ +// mstore +// /* "":292:298 */ +// 0x01c0 +// /* "":285:303 */ +// mstore +// /* "":319:325 */ +// 0x01e0 +// /* "":312:330 */ +// mstore +// /* "":346:352 */ +// 0x0200 +// /* "":339:357 */ +// mstore +// /* "":373:379 */ +// 0x0220 +// /* "":366:385 */ +// mstore +// /* "":401:407 */ +// 0x0240 +// /* "":394:413 */ +// mstore +// /* "":429:435 */ +// 0x0260 +// /* "":422:441 */ +// mstore +// /* "":457:463 */ +// 0x0280 +// /* "":450:469 */ +// mstore +// /* "":485:491 */ +// 0x02a0 +// /* "":478:497 */ +// mstore +// /* "":513:519 */ +// 0x02c0 +// /* "":506:525 */ +// mstore +// /* "":541:547 */ +// 0x02e0 +// /* "":534:553 */ +// mstore +// /* "":569:575 */ +// 0x0300 +// /* "":562:581 */ +// mstore +// /* "":597:603 */ +// 0x0320 +// /* "":590:609 */ +// mstore +// /* "":625:631 */ +// 0x0340 +// /* "":618:637 */ +// mstore +// swap1 +// /* "":6:660 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params.yul b/test/libyul/evmCodeTransform/stackReuse/function_params.yul index 60139bb76..bb096cd95 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params.yul @@ -4,11 +4,9 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x8 -// JUMP -// JUMPDEST -// POP -// POP -// JUMPDEST -// JUMP -// JUMPDEST +// stop +// /* "":6:26 */ +// tag_1: +// pop +// pop +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul index 3228637dc..982882347 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams.yul @@ -8,17 +8,15 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// stop +// /* "":218:252 */ +// tag_1: +// pop +// pop +// pop +// pop +// 0x00 +// swap1 +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul index 089892a66..d7cf6b399 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_params_and_retparams_partly_used.yul @@ -4,28 +4,25 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1E -// JUMP -// JUMPDEST -// POP -// PUSH1 0x3 -// SWAP1 -// POP -// POP -// POP -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x9 -// PUSH1 0x2 -// SWAP2 -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// stop +// /* "":6:78 */ +// tag_1: +// pop +// pop +// pop +// pop +// 0x00 +// swap1 +// /* "":44:45 */ +// pop(0x03) +// /* "":55:56 */ +// 0x09 +// swap1 +// /* "":62:63 */ +// 0x02 +// dup1 +// swap3 +// /* "":64:76 */ +// mstore +// /* "":6:78 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul index 4dde5208b..f86f1a7b4 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam.yul @@ -4,13 +4,11 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xC -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST +// stop +// /* "":6:30 */ +// tag_1: +// 0x00 +// swap1 +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul index 3c1d90bd3..d8ccb61cf 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_block.yul @@ -4,15 +4,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:63 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":47:58 */ +// callvalue +// /* "":43:59 */ +// pop +// /* "":6:63 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul index fe99402f4..f05af12aa 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_declaration.yul @@ -4,15 +4,16 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xD -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:63 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":50:61 */ +// pop(callvalue) +// /* "":6:63 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul index 7dcb39c10..7af4ad841 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_for.yul @@ -4,24 +4,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x19 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// CALLVALUE -// POP -// JUMPDEST -// PUSH1 0x0 -// ISZERO -// PUSH1 0x15 -// JUMPI -// JUMPDEST -// PUSH1 0xA -// JUMP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:76 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":51:62 */ +// callvalue +// /* "":47:63 */ +// pop +// /* "":6:76 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul index bd882240f..79b2bbd33 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_if.yul @@ -4,20 +4,25 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0x1 -// ISZERO -// PUSH1 0x10 -// JUMPI -// CALLVALUE -// POP -// JUMPDEST -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:68 */ +// tag_1: +// 0x00 +// swap1 +// /* "":44:45 */ +// 0x01 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// tag_2 +// jumpi +// tag_3: +// /* "":6:68 */ +// jump // out +// tag_2: +// /* "":52:63 */ +// callvalue +// /* "":48:64 */ +// pop +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul index 2e16c05d5..d9b8355cc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_leave.yul @@ -4,17 +4,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x10 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// PUSH1 0xD -// JUMP -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:65 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// /* "":6:65 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul index d8440b86e..aef3e0296 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_read.yul @@ -4,18 +4,23 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// ADDRESS -// POP -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// SSTORE -// CALLVALUE -// POP -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:72 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:39 */ +// address +// /* "":26:40 */ +// pop +// dup2 +// /* "":48:49 */ +// 0x00 +// /* "":41:53 */ +// sstore +// /* "":58:69 */ +// callvalue +// /* "":54:70 */ +// pop +// /* "":6:72 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul index c20158eae..1d24d82f7 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned.yul @@ -4,13 +4,14 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0xB -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST +// stop +// /* "":6:44 */ +// tag_1: +// 0x00 +// swap1 +// /* "":30:41 */ +// callvalue +// /* "":26:42 */ +// pop +// /* "":6:44 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul index d9e80547e..4ec88dbbd 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_retparam_unassigned_multiple.yul @@ -4,17 +4,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x11 -// JUMP -// JUMPDEST -// CALLVALUE -// POP -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// JUMP -// JUMPDEST +// stop +// /* "":6:50 */ +// tag_1: +// 0x00 +// swap1 +// 0x00 +// swap1 +// 0x00 +// swap1 +// /* "":36:47 */ +// callvalue +// /* "":32:48 */ +// pop +// /* "":6:50 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul index 2c803e85f..59233bdc1 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_trivial.yul @@ -4,9 +4,7 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x6 -// JUMP -// JUMPDEST -// JUMPDEST -// JUMP -// JUMPDEST +// stop +// /* "":4:20 */ +// tag_1: +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul index 60f287734..93f8b8084 100644 --- a/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul +++ b/test/libyul/evmCodeTransform/stackReuse/function_with_body_embedded.yul @@ -9,27 +9,18 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x3 -// PUSH1 0x17 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// DUP2 -// POP -// PUSH1 0x3 -// SWAP2 -// POP -// DUP2 -// SWAP1 -// POP -// JUMPDEST -// SWAP3 -// SWAP2 -// POP -// POP -// JUMP -// JUMPDEST -// PUSH1 0x7 -// SWAP1 -// POP -// POP +// /* "":15:16 */ +// pop(0x03) +// /* "":182:183 */ +// pop(0x07) +// stop +// /* "":21:172 */ +// tag_1: +// swap1 +// pop +// pop +// /* "":158:159 */ +// 0x03 +// swap1 +// /* "":21:172 */ +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul index 6189e1614..2f9f19204 100644 --- a/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul +++ b/test/libyul/evmCodeTransform/stackReuse/functions_multi_return.yul @@ -10,51 +10,54 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x14 -// JUMP -// JUMPDEST -// POP -// POP -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// JUMP -// JUMPDEST -// PUSH1 0x1E -// PUSH1 0x2 -// PUSH1 0x1 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// PUSH1 0x28 -// PUSH1 0x4 -// PUSH1 0x3 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// SWAP1 -// POP -// POP -// PUSH1 0x31 -// PUSH1 0xB -// JUMP -// JUMPDEST -// PUSH1 0x37 -// PUSH1 0xB -// JUMP -// JUMPDEST -// SWAP2 -// POP -// SWAP2 -// POP -// POP -// POP -// PUSH1 0x7 -// POP +// tag_1 +// /* "":79:80 */ +// 0x02 +// /* "":76:77 */ +// 0x01 +// /* "":74:81 */ +// tag_2 +// jump // in +// tag_1: +// pop +// tag_3 +// /* "":96:97 */ +// 0x04 +// /* "":93:94 */ +// 0x03 +// /* "":91:98 */ +// tag_2 +// jump // in +// tag_3: +// pop +// tag_4 +// /* "":115:118 */ +// tag_5 +// jump // in +// tag_4: +// pop +// pop +// tag_6 +// /* "":131:134 */ +// tag_5 +// jump // in +// tag_6: +// pop +// pop +// /* "":153:154 */ +// pop(0x07) +// stop +// /* "":6:31 */ +// tag_2: +// pop +// pop +// 0x00 +// swap1 +// jump // out +// /* "":36:60 */ +// tag_5: +// 0x00 +// swap1 +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/if.yul b/test/libyul/evmCodeTransform/stackReuse/if.yul index a407bb54c..2cf4d8b25 100644 --- a/test/libyul/evmCodeTransform/stackReuse/if.yul +++ b/test/libyul/evmCodeTransform/stackReuse/if.yul @@ -3,15 +3,19 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// DUP1 -// ISZERO -// PUSH1 0xA -// JUMPI -// DUP1 -// POP -// JUMPDEST -// POP -// PUSH1 0x3 -// POP +// /* "":72:73 */ +// 0x00 +// /* "":66:74 */ +// mload +// dup1 +// tag_1 +// jumpi +// tag_2: +// pop +// /* "":104:105 */ +// pop(0x03) +// stop +// tag_1: +// pop +// pc +// jump(tag_2) diff --git a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul index 1fc780d21..96fd7ffde 100644 --- a/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul +++ b/test/libyul/evmCodeTransform/stackReuse/last_use_in_nested_block.yul @@ -2,9 +2,10 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// POP -// POP -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":15:21 */ +// pop +// /* "":33:34 */ +// pop(0x01) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul index 88d42510c..05e214f86 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_same_variable_name.yul @@ -2,22 +2,17 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// MLOAD -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// DUP1 -// SWAP2 -// POP -// POP -// PUSH1 0x2 -// DUP1 -// SWAP2 -// POP -// PUSH1 0x4 -// SWAP1 -// POP -// POP -// POP +// /* "":17:18 */ +// 0x00 +// /* "":11:19 */ +// mload +// pop +// /* "":31:32 */ +// pop(0x01) +// /* "":38:39 */ +// pop(0x06) +// /* "":60:61 */ +// pop(0x02) +// /* "":74:75 */ +// pop(0x04) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul index ba0ad96e7..6fa4faa47 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot.yul @@ -2,13 +2,12 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// pop(0x01) +// /* "":18:19 */ +// pop(0x06) +// /* "":29:30 */ +// pop(0x02) +// /* "":36:37 */ +// pop(0x04) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul index b064fcc20..e4af73742 100644 --- a/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul +++ b/test/libyul/evmCodeTransform/stackReuse/multi_reuse_single_slot_nested.yul @@ -2,13 +2,12 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x6 -// SWAP1 -// POP -// POP -// PUSH1 0x2 -// PUSH1 0x4 -// SWAP1 -// POP -// POP +// /* "":11:12 */ +// pop(0x01) +// /* "":18:19 */ +// pop(0x06) +// /* "":31:32 */ +// pop(0x02) +// /* "":38:39 */ +// pop(0x04) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul index fe50cb997..ab5862896 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_not_same_scope.yul @@ -8,10 +8,9 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP1 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// dup1 +// /* "":126:138 */ +// sstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul index 5e4cfd093..76b2c2990 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used.yul @@ -6,11 +6,9 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":15:16 */ +// 0x05 +// dup1 +// /* "":74:86 */ +// sstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul index 89a82f65c..d6d488b06 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_last_used_expr.yul @@ -6,13 +6,13 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x2 -// DUP2 -// ADD -// SWAP1 -// POP -// DUP1 -// DUP2 -// SSTORE -// POP +// /* "":37:38 */ +// 0x02 +// /* "":15:16 */ +// 0x05 +// /* "":30:39 */ +// add +// dup1 +// /* "":82:94 */ +// sstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul index 7c7cdfd55..f62dadf92 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_on_decl_assign_to_not_last_used.yul @@ -6,10 +6,9 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// DUP1 -// DUP2 -// DUP2 -// SSTORE -// POP -// POP +// /* "":15:16 */ +// 0x05 +// dup1 +// /* "":107:119 */ +// sstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul index 44b916670..1fb940eae 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots.yul @@ -2,22 +2,23 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// /* "":2:16 */ +// 0x00 +// dup1 +// dup1 +// dup1 +// pop +// swap2 +// swap1 +// pop +// /* "":26:27 */ +// 0x02 +// swap1 +// /* "":37:38 */ +// 0x03 +// swap2 +// /* "":39:51 */ +// mstore +// /* "":52:64 */ +// mstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul index f5e855a46..a83a8ac6b 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function.yul @@ -5,36 +5,34 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x12 -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x18 -// PUSH1 0x3 -// JUMP -// JUMPDEST -// POP -// PUSH1 0x2 -// SWAP2 -// POP -// PUSH1 0x3 -// DUP4 -// DUP4 -// MSTORE -// DUP2 -// DUP2 -// MSTORE -// POP -// POP -// POP -// POP +// tag_1 +// /* "":58:61 */ +// tag_2 +// jump // in +// tag_1: +// pop +// swap2 +// swap1 +// pop +// /* "":72:73 */ +// 0x02 +// swap1 +// /* "":84:85 */ +// 0x03 +// swap2 +// /* "":86:99 */ +// mstore +// /* "":100:113 */ +// mstore +// stop +// /* "":6:35 */ +// tag_2: +// 0x00 +// swap1 +// 0x00 +// swap1 +// 0x00 +// swap1 +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul index 36800b204..d313dc076 100644 --- a/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul +++ b/test/libyul/evmCodeTransform/stackReuse/reuse_slots_function_with_gaps.yul @@ -9,42 +9,38 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x5 -// PUSH1 0x6 -// PUSH1 0x7 -// DUP2 -// DUP4 -// MSTORE -// PUSH1 0x1B -// JUMP -// JUMPDEST -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// PUSH1 0x0 -// JUMPDEST -// SWAP1 -// SWAP2 -// SWAP3 -// SWAP4 -// JUMP -// JUMPDEST -// PUSH1 0x21 -// PUSH1 0xC -// JUMP -// JUMPDEST -// SWAP6 -// POP -// SWAP4 -// POP -// POP -// DUP1 -// DUP3 -// MSTORE -// POP -// POP -// DUP2 -// DUP2 -// MSTORE -// POP -// POP +// /* "":106:107 */ +// 0x05 +// /* "":118:119 */ +// 0x06 +// /* "":130:131 */ +// 0x07 +// swap2 +// /* "":136:150 */ +// mstore +// tag_1 +// /* "":207:210 */ +// tag_2 +// jump // in +// tag_1: +// swap4 +// swap1 +// swap3 +// swap2 +// pop +// /* "":211:224 */ +// mstore +// /* "":225:237 */ +// mstore +// stop +// /* "":155:184 */ +// tag_2: +// 0x00 +// swap1 +// 0x00 +// swap1 +// 0x00 +// swap1 +// 0x00 +// swap1 +// jump // out diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var.yul b/test/libyul/evmCodeTransform/stackReuse/single_var.yul index 06957305e..bf7cfeed3 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var.yul @@ -2,5 +2,6 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// POP +// /* "":2:7 */ +// pop(0x00) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul index 6bc5f504f..75d08120f 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned.yul @@ -2,5 +2,6 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP +// /* "":11:12 */ +// pop(0x01) +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul index 9fdccea85..a5c7f0881 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code.yul @@ -2,8 +2,12 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// POP -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE +// /* "":11:12 */ +// pop(0x01) +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul index 2d66c74db..20969d57d 100644 --- a/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul +++ b/test/libyul/evmCodeTransform/stackReuse/single_var_assigned_plus_code_and_reused.yul @@ -2,11 +2,16 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x1 -// PUSH1 0x4 -// PUSH1 0x3 -// MSTORE -// DUP1 -// MLOAD -// POP -// POP +// /* "":11:12 */ +// 0x01 +// /* "":23:24 */ +// 0x04 +// /* "":20:21 */ +// 0x03 +// /* "":13:25 */ +// mstore +// /* "":30:38 */ +// mload +// /* "":26:39 */ +// pop +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/smoke.yul b/test/libyul/evmCodeTransform/stackReuse/smoke.yul index 0a212e9ca..135ffcaec 100644 --- a/test/libyul/evmCodeTransform/stackReuse/smoke.yul +++ b/test/libyul/evmCodeTransform/stackReuse/smoke.yul @@ -2,3 +2,4 @@ // ==== // stackOptimization: true // ---- +// stop diff --git a/test/libyul/evmCodeTransform/stackReuse/switch.yul b/test/libyul/evmCodeTransform/stackReuse/switch.yul index 480343dcc..29aa611fc 100644 --- a/test/libyul/evmCodeTransform/stackReuse/switch.yul +++ b/test/libyul/evmCodeTransform/stackReuse/switch.yul @@ -2,25 +2,24 @@ // ==== // stackOptimization: true // ---- -// PUSH1 0x0 -// DUP1 -// PUSH1 0x0 -// DUP2 -// EQ -// PUSH1 0x11 -// JUMPI -// PUSH1 0x3 -// SWAP2 -// POP -// PUSH1 0x18 -// JUMP -// JUMPDEST -// PUSH1 0x2 -// POP -// PUSH1 0x3 -// POP -// JUMPDEST -// POP -// POP -// PUSH1 0x9 -// POP +// /* "":11:12 */ +// 0x00 +// /* "":27:28 */ +// 0x00 +// eq +// tag_1 +// jumpi +// tag_2: +// /* "":70:71 */ +// pop(0x03) +// jump(tag_3) +// tag_3: +// /* "":83:84 */ +// pop(0x09) +// stop +// tag_1: +// /* "":40:41 */ +// pop(0x02) +// /* "":51:52 */ +// pop(0x03) +// jump(tag_3) diff --git a/test/libyul/evmCodeTransform/stub.yul b/test/libyul/evmCodeTransform/stub.yul new file mode 100644 index 000000000..2565638a8 --- /dev/null +++ b/test/libyul/evmCodeTransform/stub.yul @@ -0,0 +1,76 @@ +{ + fun_c() + function fun_c() + { + switch iszero(calldataload(0)) + case 0 { } + default { + if calldataload(1) + { + leave + } + if calldataload(2) + { + revert(0, 0) + } + } + revert(0, 0) + } +} +// ==== +// stackOptimization: true +// ---- +// tag_1 +// /* "":14:21 */ +// tag_2 +// jump // in +// tag_1: +// stop +// /* "":34:458 */ +// tag_2: +// /* "":108:109 */ +// 0x00 +// /* "":95:110 */ +// calldataload +// /* "":88:111 */ +// iszero +// /* "":133:134 */ +// 0x00 +// eq +// tag_3 +// jumpi +// tag_4: +// /* "":201:202 */ +// 0x01 +// /* "":188:203 */ +// calldataload +// tag_5 +// jumpi +// tag_6: +// pop +// /* "":314:315 */ +// 0x02 +// /* "":301:316 */ +// calldataload +// tag_7 +// jumpi +// tag_8: +// jump(tag_9) +// tag_9: +// /* "":442:443 */ +// 0x00 +// dup1 +// /* "":432:444 */ +// revert +// tag_7: +// /* "":373:374 */ +// 0x00 +// dup1 +// /* "":363:375 */ +// revert +// tag_5: +// /* "":34:458 */ +// jump // out +// tag_3: +// pop +// jump(tag_9) diff --git a/test/libyul/evmCodeTransform/test.yul b/test/libyul/evmCodeTransform/test.yul new file mode 100644 index 000000000..d40fd1002 --- /dev/null +++ b/test/libyul/evmCodeTransform/test.yul @@ -0,0 +1,7 @@ +{ + +} +// ==== +// stackOptimization: true +// ---- +// stop diff --git a/test/libyul/objectCompiler/long_object_name.yul b/test/libyul/objectCompiler/long_object_name.yul index 0aa8c4405..72382f162 100644 --- a/test/libyul/objectCompiler/long_object_name.yul +++ b/test/libyul/objectCompiler/long_object_name.yul @@ -10,16 +10,18 @@ object "t" { // optimizationPreset: full // ---- // Assembly: -// /* "source":23:147 */ +// /* "source":33:146 */ // dataSize(sub_0) // /* "source":30:31 */ // 0x00 // /* "source":23:147 */ // sstore +// stop // stop // // sub_0: assembly { +// stop // } -// Bytecode: 6000600055fe -// Opcodes: PUSH1 0x0 PUSH1 0x0 SSTORE INVALID -// SourceMappings: 23:124:0:-:0;30:1;23:124 +// Bytecode: 600160005500fe +// Opcodes: PUSH1 0x1 PUSH1 0x0 SSTORE STOP INVALID +// SourceMappings: 33:113:0:-:0;30:1;23:124; diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index 01ecf5aff..ec526be65 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -20,22 +20,24 @@ object "a" { // Assembly: // /* "source":48:49 */ // 0x00 -// 0x00 +// dup1 // /* "source":35:50 */ // calldataload // /* "source":107:127 */ // sstore +// stop // stop // // sub_0: assembly { // /* "source":188:189 */ // 0x00 -// 0x00 +// dup1 // /* "source":175:190 */ // calldataload // /* "source":253:273 */ // sstore +// stop // } -// Bytecode: 600060003555fe -// Opcodes: PUSH1 0x0 PUSH1 0x0 CALLDATALOAD SSTORE INVALID -// SourceMappings: 48:1:0:-:0;;35:15;107:20 +// Bytecode: 600080355500fe +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP INVALID +// SourceMappings: 48:1:0:-:0;;35:15;107:20; diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index 375fa6347..38fa05538 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -10,11 +10,12 @@ // Assembly: // /* "source":26:27 */ // 0x00 -// 0x00 +// dup1 // /* "source":13:28 */ // calldataload // /* "source":79:99 */ // sstore -// Bytecode: 600060003555 -// Opcodes: PUSH1 0x0 PUSH1 0x0 CALLDATALOAD SSTORE -// SourceMappings: 26:1:0:-:0;;13:15;79:20 +// stop +// Bytecode: 600080355500 +// Opcodes: PUSH1 0x0 DUP1 CALLDATALOAD SSTORE STOP +// SourceMappings: 26:1:0:-:0;;13:15;79:20; diff --git a/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_function.yul b/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_function.yul new file mode 100644 index 000000000..45e0c6f19 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_function.yul @@ -0,0 +1,81 @@ +{ + function f(a) -> b { + let x := mload(a) + b := sload(x) + } + // This will stop inlining at some point because + // the function gets too big. + function g() -> x { + x := f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(2))))))))))))))))))) + } +} +// ==== +// EVMVersion: >homestead +// ---- +// step: fullInliner +// +// { +// function f(a) -> b +// { b := sload(mload(a)) } +// function g() -> x_1 +// { +// let a_20 := 2 +// let b_21 := 0 +// b_21 := sload(mload(a_20)) +// let a_23 := b_21 +// let b_24 := 0 +// b_24 := sload(mload(a_23)) +// let a_26 := b_24 +// let b_27 := 0 +// b_27 := sload(mload(a_26)) +// let a_29 := b_27 +// let b_30 := 0 +// b_30 := sload(mload(a_29)) +// let a_32 := b_30 +// let b_33 := 0 +// b_33 := sload(mload(a_32)) +// let a_35 := b_33 +// let b_36 := 0 +// b_36 := sload(mload(a_35)) +// let a_38 := b_36 +// let b_39 := 0 +// b_39 := sload(mload(a_38)) +// let a_41 := b_39 +// let b_42 := 0 +// b_42 := sload(mload(a_41)) +// let a_44 := b_42 +// let b_45 := 0 +// b_45 := sload(mload(a_44)) +// let a_47 := b_45 +// let b_48 := 0 +// b_48 := sload(mload(a_47)) +// let a_50 := b_48 +// let b_51 := 0 +// b_51 := sload(mload(a_50)) +// let a_53 := b_51 +// let b_54 := 0 +// b_54 := sload(mload(a_53)) +// let a_56 := b_54 +// let b_57 := 0 +// b_57 := sload(mload(a_56)) +// let a_59 := b_57 +// let b_60 := 0 +// b_60 := sload(mload(a_59)) +// let a_62 := b_60 +// let b_63 := 0 +// b_63 := sload(mload(a_62)) +// let a_65 := b_63 +// let b_66 := 0 +// b_66 := sload(mload(a_65)) +// let a_68 := b_66 +// let b_69 := 0 +// b_69 := sload(mload(a_68)) +// let a_71 := b_69 +// let b_72 := 0 +// b_72 := sload(mload(a_71)) +// let a_74 := b_72 +// let b_75 := 0 +// b_75 := sload(mload(a_74)) +// x_1 := b_75 +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_global_context.yul b/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_global_context.yul new file mode 100644 index 000000000..fd5cd378b --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/inline_into_big_global_context.yul @@ -0,0 +1,78 @@ +{ + function f(a) -> b { + let x := mload(a) + b := sload(x) + } + // This will stop inlining at some point because + // the global context gets too big. + let x := f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(2))))))))))))))))))) +} +// ==== +// EVMVersion: >homestead +// ---- +// step: fullInliner +// +// { +// { +// let a_20 := 2 +// let b_21 := 0 +// b_21 := sload(mload(a_20)) +// let a_23 := b_21 +// let b_24 := 0 +// b_24 := sload(mload(a_23)) +// let a_26 := b_24 +// let b_27 := 0 +// b_27 := sload(mload(a_26)) +// let a_29 := b_27 +// let b_30 := 0 +// b_30 := sload(mload(a_29)) +// let a_32 := b_30 +// let b_33 := 0 +// b_33 := sload(mload(a_32)) +// let a_35 := b_33 +// let b_36 := 0 +// b_36 := sload(mload(a_35)) +// let a_38 := b_36 +// let b_39 := 0 +// b_39 := sload(mload(a_38)) +// let a_41 := b_39 +// let b_42 := 0 +// b_42 := sload(mload(a_41)) +// let a_44 := b_42 +// let b_45 := 0 +// b_45 := sload(mload(a_44)) +// let a_47 := b_45 +// let b_48 := 0 +// b_48 := sload(mload(a_47)) +// let a_50 := b_48 +// let b_51 := 0 +// b_51 := sload(mload(a_50)) +// let a_53 := b_51 +// let b_54 := 0 +// b_54 := sload(mload(a_53)) +// let a_56 := b_54 +// let b_57 := 0 +// b_57 := sload(mload(a_56)) +// let a_59 := b_57 +// let b_60 := 0 +// b_60 := sload(mload(a_59)) +// let a_62 := b_60 +// let b_63 := 0 +// b_63 := sload(mload(a_62)) +// let a_65 := b_63 +// let b_66 := 0 +// b_66 := sload(mload(a_65)) +// let a_68 := b_66 +// let b_69 := 0 +// b_69 := sload(mload(a_68)) +// let a_71 := b_69 +// let b_72 := 0 +// b_72 := sload(mload(a_71)) +// let a_74 := b_72 +// let b_75 := 0 +// b_75 := sload(mload(a_74)) +// let x_1 := b_75 +// } +// function f(a) -> b +// { b := sload(mload(a)) } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul index c1ce89bcf..fc0e59372 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul @@ -9,6 +9,8 @@ x := f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(2))))))))))))))))))) } } +// ==== +// EVMVersion: =homestead // ---- // step: fullInliner // diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul index 10ccc2a37..47989750a 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul @@ -7,6 +7,8 @@ // the global context gets too big. let x := f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(2))))))))))))))))))) } +// ==== +// EVMVersion: =homestead // ---- // step: fullInliner // diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi2.yul b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul index d8c8e9055..ef2187daa 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi2.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul @@ -1078,49 +1078,50 @@ // { // { // let _1 := mload(1) -// let _2 := mload(0) -// if slt(sub(_1, _2), 64) { revert(0, 0) } -// sstore(0, and(calldataload(_2), sub(shl(160, 1), 1))) -// let x0, x1, x2, x3, x4 := abi_decode_addresst_uint256t_bytes_calldatat_enum_Operation(mload(7), mload(8)) -// sstore(x1, x0) -// sstore(x3, x2) -// sstore(1, x4) -// pop(abi_encode_bytes32_address_uint256_bytes32_enum_Operation_uint256_uint256_uint256_address_address_uint256(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41))) -// } -// function abi_decode_addresst_uint256t_bytes_calldatat_enum_Operation(headStart, dataEnd) -> value0, value1, value2, value3, value4 -// { -// if slt(sub(dataEnd, headStart), 128) { revert(0, 0) } -// value0 := and(calldataload(headStart), sub(shl(160, 1), 1)) -// value1 := calldataload(add(headStart, 32)) -// let offset := calldataload(add(headStart, 64)) -// let _1 := 0xffffffffffffffff -// if gt(offset, _1) { revert(0, 0) } -// let _2 := add(headStart, offset) -// if iszero(slt(add(_2, 0x1f), dataEnd)) { revert(0, 0) } -// let length := calldataload(_2) -// if gt(length, _1) { revert(0, 0) } -// if gt(add(add(_2, length), 32), dataEnd) { revert(0, 0) } -// value2 := add(_2, 32) -// value3 := length -// let _3 := calldataload(add(headStart, 96)) -// if iszero(lt(_3, 3)) { revert(0, 0) } -// value4 := _3 -// } -// function abi_encode_bytes32_address_uint256_bytes32_enum_Operation_uint256_uint256_uint256_address_address_uint256(headStart, value10, value9, value8, value7, value6, value5, value4, value3, value2, value1, value0) -> tail -// { -// tail := add(headStart, 352) -// mstore(headStart, value0) -// let _1 := sub(shl(160, 1), 1) -// mstore(add(headStart, 32), and(value1, _1)) -// mstore(add(headStart, 64), value2) -// mstore(add(headStart, 96), value3) -// if iszero(lt(value4, 3)) { invalid() } -// mstore(add(headStart, 128), value4) -// mstore(add(headStart, 160), value5) -// mstore(add(headStart, 192), value6) -// mstore(add(headStart, 224), value7) -// mstore(add(headStart, 256), and(value8, _1)) -// mstore(add(headStart, 288), and(value9, _1)) -// mstore(add(headStart, 320), value10) +// let _2 := 0 +// let _3 := mload(_2) +// if slt(sub(_1, _3), 64) { revert(_2, _2) } +// let _4 := sub(shl(160, 1), 1) +// sstore(_2, and(calldataload(_3), _4)) +// let _5 := mload(8) +// let _6 := mload(7) +// if slt(sub(_5, _6), 128) { revert(_2, _2) } +// let offset := calldataload(add(_6, 64)) +// let _7 := 0xffffffffffffffff +// if gt(offset, _7) { revert(_2, _2) } +// let _8 := add(_6, offset) +// if iszero(slt(add(_8, 0x1f), _5)) { revert(_2, _2) } +// let length := calldataload(_8) +// if gt(length, _7) { revert(_2, _2) } +// if gt(add(add(_8, length), 32), _5) { revert(_2, _2) } +// let _9 := calldataload(add(_6, 96)) +// if iszero(lt(_9, 3)) { revert(_2, _2) } +// sstore(calldataload(add(_6, 32)), and(calldataload(_6), _4)) +// sstore(length, add(_8, 32)) +// sstore(1, _9) +// let _10 := mload(41) +// let _11 := mload(40) +// let _12 := mload(39) +// let _13 := mload(38) +// let _14 := mload(37) +// let _15 := mload(36) +// let _16 := mload(35) +// let _17 := mload(34) +// let _18 := mload(33) +// let _19 := mload(32) +// let _20 := mload(0x1f) +// let _21 := mload(30) +// mstore(_21, _10) +// mstore(add(_21, 32), and(_11, _4)) +// mstore(add(_21, 64), _12) +// mstore(add(_21, 96), _13) +// if iszero(lt(_14, 3)) { invalid() } +// mstore(add(_21, 128), _14) +// mstore(add(_21, 160), _15) +// mstore(add(_21, 192), _16) +// mstore(add(_21, 224), _17) +// mstore(add(_21, 256), and(_18, _4)) +// mstore(add(_21, 288), and(_19, _4)) +// mstore(add(_21, 320), _20) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index b69d19cdb..3245f1964 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -486,80 +486,65 @@ // srcPtr := add(srcPtr, 0x20) // pos := add(pos, 0x60) // } -// let a, b, c, d := abi_decode_uint256t_uint256t_array_uint256_dynt_array_array_uint256_memory_dyn(mload(0x20), mload(64)) -// sstore(a, b) -// sstore(c, d) -// sstore(_1, pos) -// } -// function abi_decode_array_array_uint256_memory_dyn(offset, end) -> array -// { -// let _1 := 0x1f -// if iszero(slt(add(offset, _1), end)) { revert(0, 0) } -// let length := calldataload(offset) -// array := allocateMemory(array_allocation_size_array_address_dyn_memory(length)) -// let dst := array -// mstore(array, length) -// let _2 := 0x20 -// dst := add(array, _2) -// let src := add(offset, _2) -// if gt(add(add(offset, shl(6, length)), _2), end) { revert(0, 0) } -// let i := 0 -// for { } lt(i, length) { i := add(i, 1) } -// { -// if iszero(slt(add(src, _1), end)) { revert(0, 0) } -// let dst_1 := allocateMemory_967() -// let dst_2 := dst_1 -// let src_1 := src -// let _3 := add(src, 64) -// if gt(_3, end) { revert(0, 0) } -// let i_1 := 0 -// for { } lt(i_1, 0x2) { i_1 := add(i_1, 1) } -// { -// mstore(dst_1, calldataload(src_1)) -// dst_1 := add(dst_1, _2) -// src_1 := add(src_1, _2) -// } -// mstore(dst, dst_2) -// dst := add(dst, _2) -// src := _3 -// } -// } -// function abi_decode_uint256t_uint256t_array_uint256_dynt_array_array_uint256_memory_dyn(headStart, dataEnd) -> value0, value1, value2, value3 -// { -// if slt(sub(dataEnd, headStart), 128) { revert(0, 0) } -// value0 := calldataload(headStart) -// let _1 := 32 -// value1 := calldataload(add(headStart, _1)) -// let offset := calldataload(add(headStart, 64)) -// let _2 := 0xffffffffffffffff -// if gt(offset, _2) { revert(0, 0) } -// let _3 := add(headStart, offset) -// if iszero(slt(add(_3, 0x1f), dataEnd)) { revert(0, 0) } -// let length := calldataload(_3) -// let dst := allocateMemory(array_allocation_size_array_address_dyn_memory(length)) +// let _4 := mload(64) +// let _5 := mload(0x20) +// if slt(sub(_4, _5), 128) { revert(_1, _1) } +// let offset := calldataload(add(_5, 64)) +// let _6 := 0xffffffffffffffff +// if gt(offset, _6) { revert(_1, _1) } +// let _7 := add(_5, offset) +// if iszero(slt(add(_7, 0x1f), _4)) { revert(_1, _1) } +// let length_1 := calldataload(_7) +// let dst := allocateMemory(array_allocation_size_array_address_dyn_memory(length_1)) // let dst_1 := dst -// mstore(dst, length) -// dst := add(dst, _1) -// let src := add(_3, _1) -// if gt(add(add(_3, shl(5, length)), _1), dataEnd) { revert(0, 0) } -// let i := 0 -// for { } lt(i, length) { i := add(i, 1) } +// mstore(dst, length_1) +// dst := add(dst, 0x20) +// let src := add(_7, 0x20) +// if gt(add(add(_7, shl(5, length_1)), 0x20), _4) { revert(_1, _1) } +// let i_2 := _1 +// for { } lt(i_2, length_1) { i_2 := add(i_2, 1) } // { // mstore(dst, calldataload(src)) -// dst := add(dst, _1) -// src := add(src, _1) +// dst := add(dst, 0x20) +// src := add(src, 0x20) // } -// value2 := dst_1 -// let offset_1 := calldataload(add(headStart, 96)) -// if gt(offset_1, _2) { revert(0, 0) } -// value3 := abi_decode_array_array_uint256_memory_dyn(add(headStart, offset_1), dataEnd) -// } -// function allocateMemory_967() -> memPtr -// { -// memPtr := mload(64) -// let newFreePtr := add(memPtr, 64) -// if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) { revert(0, 0) } -// mstore(64, newFreePtr) +// let offset_1 := calldataload(add(_5, 0x60)) +// if gt(offset_1, _6) { revert(_1, _1) } +// let _8 := add(_5, offset_1) +// if iszero(slt(add(_8, 0x1f), _4)) { revert(_1, _1) } +// let length_2 := calldataload(_8) +// let dst_2 := allocateMemory(array_allocation_size_array_address_dyn_memory(length_2)) +// let dst_3 := dst_2 +// mstore(dst_2, length_2) +// dst_2 := add(dst_2, 0x20) +// let src_1 := add(_8, 0x20) +// if gt(add(add(_8, shl(6, length_2)), 0x20), _4) { revert(_1, _1) } +// let i_3 := _1 +// for { } lt(i_3, length_2) { i_3 := add(i_3, 1) } +// { +// if iszero(slt(add(src_1, 0x1f), _4)) { revert(_1, _1) } +// let memPtr := mload(64) +// let newFreePtr := add(memPtr, 64) +// if or(gt(newFreePtr, _6), lt(newFreePtr, memPtr)) { revert(_1, _1) } +// mstore(64, newFreePtr) +// let dst_4 := memPtr +// let src_2 := src_1 +// let _9 := add(src_1, 64) +// if gt(_9, _4) { revert(_1, _1) } +// let i_4 := _1 +// for { } lt(i_4, 0x2) { i_4 := add(i_4, 1) } +// { +// mstore(dst_4, calldataload(src_2)) +// dst_4 := add(dst_4, 0x20) +// src_2 := add(src_2, 0x20) +// } +// mstore(dst_2, memPtr) +// dst_2 := add(dst_2, 0x20) +// src_1 := _9 +// } +// sstore(calldataload(_5), calldataload(add(_5, 0x20))) +// sstore(dst_1, dst_3) +// sstore(_1, pos) // } // function allocateMemory(size) -> memPtr // { diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul index 68640c7ca..719707f8e 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -237,12 +237,10 @@ // { // mstore(0x80, 7673901602397024137095011250362199966051872585513276903826533215767972925880) // mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) -// let _1 := calldataload(0x04) -// let notes := add(0x04, _1) // let m := calldataload(0x24) -// let n := calldataload(notes) -// let _2 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 -// let challenge := mod(calldataload(0x44), _2) +// let n := calldataload(add(0x04, calldataload(0x04))) +// let _1 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 +// let challenge := mod(calldataload(0x44), _1) // if gt(m, n) // { // mstore(0x00, 404) @@ -252,70 +250,110 @@ // mstore(0x2a0, caller()) // mstore(0x2c0, kn) // mstore(0x2e0, m) -// kn := mulmod(sub(_2, kn), challenge, _2) -// hashCommitments(notes, n) -// let b := add(0x300, shl(7, n)) +// kn := mulmod(sub(_1, kn), challenge, _1) // let i := 0 // for { } lt(i, n) { i := add(i, 0x01) } // { -// let _3 := add(_1, mul(i, 0xc0)) -// let noteIndex := add(_3, 0x24) +// calldatacopy(add(0x300, shl(7, i)), add(add(calldataload(0x04), mul(i, 0xc0)), 100), 0x80) +// } +// mstore(0, keccak256(0x300, shl(7, n))) +// let b := add(0x300, shl(7, n)) +// let i_1 := 0 +// for { } lt(i_1, n) { i_1 := add(i_1, 0x01) } +// { +// let _2 := add(calldataload(0x04), mul(i_1, 0xc0)) // let k := 0 -// let a := calldataload(add(_3, 0x44)) +// let a := calldataload(add(_2, 0x44)) // let c := challenge -// let _4 := add(i, 0x01) -// switch eq(_4, n) +// switch eq(add(i_1, 0x01), n) // case 1 { // k := kn -// if eq(m, n) { k := sub(_2, kn) } +// if eq(m, n) { k := sub(_1, kn) } // } -// case 0 { k := calldataload(noteIndex) } -// validateCommitment(noteIndex, k, a) -// switch gt(_4, m) +// case 0 { +// k := calldataload(add(_2, 0x24)) +// } +// let gammaX := calldataload(add(_2, 100)) +// let sigmaX := calldataload(add(_2, 164)) +// let _3 := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 +// if iszero(and(and(and(eq(mod(a, _1), a), gt(a, 0x01)), and(eq(mod(k, _1), k), gt(k, 0x01))), and(eq(addmod(mulmod(mulmod(sigmaX, sigmaX, _3), sigmaX, _3), 3, _3), mulmod(calldataload(add(_2, 196)), calldataload(add(_2, 196)), _3)), eq(addmod(mulmod(mulmod(gammaX, gammaX, _3), gammaX, _3), 3, _3), mulmod(calldataload(add(_2, 132)), calldataload(add(_2, 132)), _3))))) +// { +// mstore(0, 400) +// revert(0, 0x20) +// } +// switch gt(add(i_1, 0x01), m) // case 1 { -// kn := addmod(kn, sub(_2, k), _2) -// let x := mod(mload(0), _2) -// k := mulmod(k, x, _2) -// a := mulmod(a, x, _2) -// c := mulmod(challenge, x, _2) +// kn := addmod(kn, sub(_1, k), _1) +// let x := mod(mload(0), _1) +// k := mulmod(k, x, _1) +// a := mulmod(a, x, _1) +// c := mulmod(challenge, x, _1) // mstore(0, keccak256(0, 0x20)) // } -// case 0 { kn := addmod(kn, k, _2) } -// let _5 := 0x40 -// calldatacopy(0xe0, add(_3, 164), _5) -// calldatacopy(0x20, add(_3, 100), _5) -// mstore(0x120, sub(_2, c)) +// case 0 { kn := addmod(kn, k, _1) } +// calldatacopy(0xe0, add(_2, 164), 0x40) +// calldatacopy(0x20, add(_2, 100), 0x40) +// mstore(0x120, sub(_1, c)) // mstore(0x60, k) // mstore(0xc0, a) -// let result := call(gas(), 7, 0, 0xe0, 0x60, 0x1a0, _5) -// let result_1 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x120, _5)) -// let _6 := 0x160 -// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, 0x60, _6, _5)) -// let result_3 := and(result_2, call(gas(), 6, 0, 0x120, 0x80, _6, _5)) -// result := and(result_3, call(gas(), 6, 0, _6, 0x80, b, _5)) -// if eq(i, m) +// let result := call(gas(), 7, 0, 0xe0, 0x60, 0x1a0, 0x40) +// let result_1 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x120, 0x40)) +// let result_2 := and(result_1, call(gas(), 7, 0, 0x80, 0x60, 0x160, 0x40)) +// let result_3 := and(result_2, call(gas(), 6, 0, 0x120, 0x80, 0x160, 0x40)) +// result := and(result_3, call(gas(), 6, 0, 0x160, 0x80, b, 0x40)) +// if eq(i_1, m) // { // mstore(0x260, mload(0x20)) -// mstore(0x280, mload(_5)) +// mstore(0x280, mload(0x40)) // mstore(0x1e0, mload(0xe0)) -// mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) +// mstore(0x200, sub(_3, mload(0x100))) // } -// if gt(i, m) +// if gt(i_1, m) // { // mstore(0x60, c) -// let result_4 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x220, _5)) -// let result_5 := and(result_4, call(gas(), 6, 0, 0x220, 0x80, 0x260, _5)) -// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, _5)) +// let result_4 := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x220, 0x40)) +// let result_5 := and(result_4, call(gas(), 6, 0, 0x220, 0x80, 0x260, 0x40)) +// result := and(result_5, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, 0x40)) // } // if iszero(result) // { // mstore(0, 400) // revert(0, 0x20) // } -// b := add(b, _5) +// b := add(b, 0x40) // } -// if lt(m, n) { validatePairing() } -// if iszero(eq(mod(keccak256(0x2a0, add(b, not(671))), _2), challenge)) +// if lt(m, n) +// { +// let _4 := 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b +// let _5 := 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa +// let _6 := 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2 +// let _7 := 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed +// if or(or(or(or(or(or(or(iszero(calldataload(100)), iszero(calldataload(132))), iszero(calldataload(164))), iszero(calldataload(196))), eq(calldataload(100), _7)), eq(calldataload(132), _6)), eq(calldataload(164), _5)), eq(calldataload(196), _4)) +// { +// mstore(0, 400) +// revert(0, 0x20) +// } +// let _8 := mload(0x1e0) +// mstore(0x20, _8) +// mstore(0x40, mload(0x200)) +// mstore(0x80, _7) +// mstore(0x60, _6) +// mstore(0xc0, _5) +// mstore(0xa0, _4) +// mstore(0xe0, mload(0x260)) +// mstore(0x100, mload(0x280)) +// mstore(0x140, calldataload(100)) +// mstore(0x120, calldataload(132)) +// mstore(0x180, calldataload(164)) +// mstore(0x160, calldataload(196)) +// let success := call(gas(), 8, 0, 0x20, 0x180, 0x20, 0x20) +// if or(iszero(success), iszero(mload(0x20))) +// { +// mstore(0, 400) +// revert(0, 0x20) +// } +// } +// if iszero(eq(mod(keccak256(0x2a0, add(b, not(671))), _1), challenge)) // { // mstore(0, 404) // revert(0, 0x20) @@ -323,64 +361,4 @@ // mstore(0, 0x01) // return(0, 0x20) // } -// function validatePairing() -// { -// let t2_x := calldataload(0x64) -// let t2_x_1 := calldataload(132) -// let t2_y := calldataload(164) -// let t2_y_1 := calldataload(196) -// let _1 := 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b -// let _2 := 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa -// let _3 := 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2 -// let _4 := 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed -// if or(or(or(or(or(or(or(iszero(t2_x), iszero(t2_x_1)), iszero(t2_y)), iszero(t2_y_1)), eq(t2_x, _4)), eq(t2_x_1, _3)), eq(t2_y, _2)), eq(t2_y_1, _1)) -// { -// mstore(0x00, 400) -// revert(0x00, 0x20) -// } -// let _5 := mload(0x1e0) -// let _6 := 0x20 -// mstore(_6, _5) -// mstore(0x40, mload(0x200)) -// mstore(0x80, _4) -// mstore(0x60, _3) -// mstore(0xc0, _2) -// mstore(0xa0, _1) -// mstore(0xe0, mload(0x260)) -// mstore(0x100, mload(0x280)) -// mstore(0x140, t2_x) -// mstore(0x120, t2_x_1) -// let _7 := 0x180 -// mstore(_7, t2_y) -// mstore(0x160, t2_y_1) -// let success := call(gas(), 8, 0, _6, _7, _6, _6) -// if or(iszero(success), iszero(mload(_6))) -// { -// mstore(0, 400) -// revert(0, _6) -// } -// } -// function validateCommitment(note, k, a) -// { -// let gammaX := calldataload(add(note, 0x40)) -// let gammaY := calldataload(add(note, 0x60)) -// let sigmaX := calldataload(add(note, 0x80)) -// let sigmaY := calldataload(add(note, 0xa0)) -// let _1 := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 -// let _2 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 -// if iszero(and(and(and(eq(mod(a, _2), a), gt(a, 1)), and(eq(mod(k, _2), k), gt(k, 1))), and(eq(addmod(mulmod(mulmod(sigmaX, sigmaX, _1), sigmaX, _1), 3, _1), mulmod(sigmaY, sigmaY, _1)), eq(addmod(mulmod(mulmod(gammaX, gammaX, _1), gammaX, _1), 3, _1), mulmod(gammaY, gammaY, _1))))) -// { -// mstore(0x00, 400) -// revert(0x00, 0x20) -// } -// } -// function hashCommitments(notes, n) -// { -// let i := 0 -// for { } lt(i, n) { i := add(i, 0x01) } -// { -// calldatacopy(add(0x300, shl(7, i)), add(add(notes, mul(i, 0xc0)), 0x60), 0x80) -// } -// mstore(0, keccak256(0x300, shl(7, n))) -// } // }