From 9a4bec7e474a310c7f93ff3b84928e0e9ba9cce6 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 15 Oct 2018 11:52:35 +0200 Subject: Renaming libjulia to libyul --- test/libyul/Common.cpp | 95 +++++++ test/libyul/Common.h | 55 ++++ test/libyul/Inliner.cpp | 111 ++++++++ test/libyul/Parser.cpp | 306 +++++++++++++++++++++ test/libyul/YulOptimizerTest.cpp | 239 ++++++++++++++++ test/libyul/YulOptimizerTest.h | 75 +++++ .../commonSubexpressionEliminator/branches_for.yul | 24 ++ .../commonSubexpressionEliminator/branches_if.yul | 15 + .../non_movable_instr.yul | 10 + .../non_movable_instr2.yul | 10 + .../commonSubexpressionEliminator/smoke.yul | 5 + .../commonSubexpressionEliminator/trivial.yul | 10 + .../variable_for_variable.yul | 27 ++ .../disambiguator/for_statement.yul | 28 ++ .../disambiguator/funtion_call.yul | 22 ++ .../disambiguator/if_statement.yul | 22 ++ .../yulOptimizerTests/disambiguator/smoke.yul | 5 + .../yulOptimizerTests/disambiguator/smoke_yul.yul | 6 + .../disambiguator/switch_statement.yul | 27 ++ .../yulOptimizerTests/disambiguator/variables.yul | 12 + .../disambiguator/variables_clash.yul | 13 + .../disambiguator/variables_inside_functions.yul | 24 ++ .../expressionInliner/complex_with_evm.yul | 13 + .../expressionInliner/double_calls.yul | 18 ++ .../expressionInliner/double_recursive_calls.yul | 18 ++ .../expressionInliner/no_inline_mload.yul | 14 + .../expressionInliner/no_move_with_sideeffects.yul | 27 ++ .../yulOptimizerTests/expressionInliner/simple.yul | 14 + .../expressionInliner/with_args.yul | 14 + .../expressionJoiner/if_condition.yul | 21 ++ .../expressionJoiner/muli_wrong_order3.yul | 13 + .../yulOptimizerTests/expressionJoiner/multi.yul | 11 + .../expressionJoiner/multi_reference.yul | 11 + .../expressionJoiner/multi_wrong_order.yul | 15 + .../expressionJoiner/multi_wrong_order2.yul | 12 + .../no_replacement_across_blocks.yul | 19 ++ .../no_replacement_in_loop_condition1.yul | 15 + .../no_replacement_in_loop_condition2.yul | 16 ++ .../expressionJoiner/only_assignment.yul | 16 ++ .../expressionJoiner/reassignment.yul | 13 + .../yulOptimizerTests/expressionJoiner/simple.yul | 10 + .../expressionJoiner/single_wrong_order.yul | 13 + .../yulOptimizerTests/expressionJoiner/smoke.yul | 5 + .../expressionJoiner/switch_expression.yul | 28 ++ .../yulOptimizerTests/expressionJoiner/triple.yul | 12 + .../expressionSimplifier/constant_propagation.yul | 6 + .../expressionSimplifier/constants.yul | 6 + .../identity_rules_complex.yul | 6 + .../identity_rules_negative.yul | 6 + .../expressionSimplifier/identity_rules_simple.yul | 10 + .../including_function_calls.yul | 12 + .../expressionSimplifier/inside_for.yul | 16 ++ .../expressionSimplifier/invariant.yul | 10 + .../expressionSimplifier/mod_and_1.yul | 8 + .../expressionSimplifier/mod_and_2.yul | 8 + ...t_applied_function_call_different_arguments.yul | 12 + .../not_applied_function_call_different_names.yul | 16 ++ ..._applied_function_call_equality_not_movable.yul | 13 + ...pplied_removes_non_constant_and_not_movable.yul | 10 + .../expressionSimplifier/reversed.yul | 8 + .../expressionSimplifier/smoke.yul | 5 + .../expressionSplitter/control_flow.yul | 40 +++ .../expressionSplitter/inside_function.yul | 29 ++ .../yulOptimizerTests/expressionSplitter/smoke.yul | 5 + .../expressionSplitter/switch.yul | 33 +++ .../expressionSplitter/trivial.yul | 14 + .../fullInliner/inside_condition.yul | 32 +++ .../fullInliner/move_up_rightwards_argument.yul | 28 ++ .../yulOptimizerTests/fullInliner/multi_fun.yul | 40 +++ .../yulOptimizerTests/fullInliner/multi_return.yul | 21 ++ .../yulOptimizerTests/fullInliner/no_return.yul | 22 ++ .../yulOptimizerTests/fullInliner/pop_result.yul | 28 ++ .../yulOptimizerTests/fullInliner/simple.yul | 26 ++ .../functionGrouper/empty_block.yul | 24 ++ .../functionGrouper/multi_fun_mixed.yul | 24 ++ .../functionGrouper/nested_fun.yul | 27 ++ .../functionGrouper/single_fun.yul | 14 + .../yulOptimizerTests/functionGrouper/smoke.yul | 7 + .../functionHoister/empty_block.yul | 26 ++ .../functionHoister/multi_mixed.yul | 23 ++ .../yulOptimizerTests/functionHoister/nested.yul | 23 ++ .../yulOptimizerTests/functionHoister/single.yul | 13 + .../yulOptimizerTests/functionHoister/smoke.yul | 6 + .../yulOptimizerTests/mainFunction/empty_block.yul | 33 +++ .../mainFunction/multi_fun_mixed.yul | 26 ++ .../yulOptimizerTests/mainFunction/nested_fun.yul | 26 ++ .../yulOptimizerTests/mainFunction/sigle_fun.yul | 16 ++ .../yulOptimizerTests/mainFunction/smoke.yul | 9 + .../rematerialiser/branches_for1.yul | 21 ++ .../rematerialiser/branches_for2.yul | 25 ++ .../branches_for_declared_in_init1.yul | 23 ++ .../branches_for_declared_in_init2.yul | 24 ++ .../rematerialiser/branches_if.yul | 18 ++ .../rematerialiser/branches_switch.yul | 24 ++ .../rematerialiser/do_not_move_out_of_scope.yul | 19 ++ .../do_not_remat_large_amounts_of_code1.yul | 10 + .../do_not_remat_large_amounts_of_code2.yul | 10 + .../rematerialiser/expression.yul | 10 + .../rematerialiser/non_movable_function.yul | 18 ++ .../rematerialiser/non_movable_instruction.yul | 14 + .../yulOptimizerTests/rematerialiser/reassign.yul | 21 ++ .../rematerialiser/reassignment.yul | 19 ++ .../yulOptimizerTests/rematerialiser/smoke.yul | 5 + .../yulOptimizerTests/rematerialiser/trivial.yul | 12 + .../rematerialiser/update_asignment_remat.yul | 13 + .../yulOptimizerTests/unusedPruner/functions.yul | 8 + .../unusedPruner/intermediate_assignment.yul | 11 + .../unusedPruner/intermediate_multi_assignment.yul | 16 ++ .../unusedPruner/multi_assign.yul | 16 ++ .../unusedPruner/multi_assignments.yul | 12 + .../unusedPruner/multi_declarations.yul | 7 + .../unusedPruner/multi_declare.yul | 12 + .../unusedPruner/multi_partial_assignments.yul | 10 + .../yulOptimizerTests/unusedPruner/smoke.yul | 5 + .../yulOptimizerTests/unusedPruner/trivial.yul | 10 + 115 files changed, 2649 insertions(+) create mode 100644 test/libyul/Common.cpp create mode 100644 test/libyul/Common.h create mode 100644 test/libyul/Inliner.cpp create mode 100644 test/libyul/Parser.cpp create mode 100644 test/libyul/YulOptimizerTest.cpp create mode 100644 test/libyul/YulOptimizerTest.h create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_if.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul create mode 100644 test/libyul/yulOptimizerTests/commonSubexpressionEliminator/variable_for_variable.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/for_statement.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/if_statement.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/variables.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul create mode 100644 test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/complex_with_evm.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/double_calls.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/double_recursive_calls.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/no_inline_mload.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/no_move_with_sideeffects.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/simple.yul create mode 100644 test/libyul/yulOptimizerTests/expressionInliner/with_args.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/multi.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/simple.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul create mode 100644 test/libyul/yulOptimizerTests/expressionJoiner/triple.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSplitter/control_flow.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSplitter/inside_function.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSplitter/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSplitter/switch.yul create mode 100644 test/libyul/yulOptimizerTests/expressionSplitter/trivial.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/multi_return.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/no_return.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/pop_result.yul create mode 100644 test/libyul/yulOptimizerTests/fullInliner/simple.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul create mode 100644 test/libyul/yulOptimizerTests/functionGrouper/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/functionHoister/empty_block.yul create mode 100644 test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul create mode 100644 test/libyul/yulOptimizerTests/functionHoister/nested.yul create mode 100644 test/libyul/yulOptimizerTests/functionHoister/single.yul create mode 100644 test/libyul/yulOptimizerTests/functionHoister/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/mainFunction/empty_block.yul create mode 100644 test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul create mode 100644 test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul create mode 100644 test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul create mode 100644 test/libyul/yulOptimizerTests/mainFunction/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/branches_switch.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/do_not_move_out_of_scope.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code1.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code2.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/expression.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/non_movable_function.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/non_movable_instruction.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/reassign.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/reassignment.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/trivial.yul create mode 100644 test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/functions.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/smoke.yul create mode 100644 test/libyul/yulOptimizerTests/unusedPruner/trivial.yul (limited to 'test/libyul') diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp new file mode 100644 index 00000000..f23136e6 --- /dev/null +++ b/test/libyul/Common.cpp @@ -0,0 +1,95 @@ +/* + 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 . +*/ +/** + * @date 2017 + * Common functions the Yul tests. + */ + +#include + +#include + +#include + +#include + +#include +#include +#include + +#include +#include + +#include + +using namespace std; +using namespace dev::julia; +using namespace dev::solidity; + +void dev::julia::test::printErrors(ErrorList const& _errors, Scanner const& _scanner) +{ + SourceReferenceFormatter formatter(cout, [&](std::string const&) -> Scanner const& { return _scanner; }); + + for (auto const& error: _errors) + formatter.printExceptionInformation( + *error, + (error->type() == Error::Type::Warning) ? "Warning" : "Error" + ); +} + + +pair, shared_ptr> dev::julia::test::parse(string const& _source, bool _yul) +{ + auto flavour = _yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict; + ErrorList errors; + ErrorReporter errorReporter(errors); + auto scanner = make_shared(CharStream(_source), ""); + auto parserResult = assembly::Parser(errorReporter, flavour).parse(scanner, false); + if (parserResult) + { + BOOST_REQUIRE(errorReporter.errors().empty()); + auto analysisInfo = make_shared(); + assembly::AsmAnalyzer analyzer( + *analysisInfo, + errorReporter, + dev::test::Options::get().evmVersion(), + boost::none, + flavour + ); + if (analyzer.analyze(*parserResult)) + { + BOOST_REQUIRE(errorReporter.errors().empty()); + return make_pair(parserResult, analysisInfo); + } + } + printErrors(errors, *scanner); + BOOST_FAIL("Invalid source."); + + // Unreachable. + return {}; +} + +assembly::Block dev::julia::test::disambiguate(string const& _source, bool _yul) +{ + auto result = parse(_source, _yul); + return boost::get(Disambiguator(*result.second)(*result.first)); +} + +string dev::julia::test::format(string const& _source, bool _yul) +{ + return assembly::AsmPrinter(_yul)(*parse(_source, _yul).first); +} diff --git a/test/libyul/Common.h b/test/libyul/Common.h new file mode 100644 index 00000000..b9c3d2fb --- /dev/null +++ b/test/libyul/Common.h @@ -0,0 +1,55 @@ +/* + 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 . +*/ +/** + * @date 2017 + * Common functions the Yul tests. + */ + +#pragma once + +#include + +#include +#include +#include + +namespace dev +{ +namespace solidity +{ +class Scanner; +class Error; +using ErrorList = std::vector>; +namespace assembly +{ +struct AsmAnalysisInfo; +} +} +namespace julia +{ +namespace test +{ + +void printErrors(solidity::ErrorList const& _errors, solidity::Scanner const& _scanner); +std::pair, std::shared_ptr> +parse(std::string const& _source, bool _yul = true); +solidity::assembly::Block disambiguate(std::string const& _source, bool _yul = true); +std::string format(std::string const& _source, bool _yul = true); + +} +} +} diff --git a/test/libyul/Inliner.cpp b/test/libyul/Inliner.cpp new file mode 100644 index 00000000..471b2e2f --- /dev/null +++ b/test/libyul/Inliner.cpp @@ -0,0 +1,111 @@ +/* + 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 . +*/ +/** + * @date 2017 + * Unit tests for the Yul function inliner. + */ + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include + +using namespace std; +using namespace dev; +using namespace dev::julia; +using namespace dev::julia::test; +using namespace dev::solidity; + +namespace +{ +string inlinableFunctions(string const& _source) +{ + auto ast = disambiguate(_source); + + InlinableExpressionFunctionFinder funFinder; + funFinder(ast); + + return boost::algorithm::join( + funFinder.inlinableFunctions() | boost::adaptors::map_keys, + "," + ); +} + +} + + +BOOST_AUTO_TEST_SUITE(YulInlinableFunctionFilter) + +BOOST_AUTO_TEST_CASE(smoke_test) +{ + BOOST_CHECK_EQUAL(inlinableFunctions("{ }"), ""); +} + +BOOST_AUTO_TEST_CASE(simple) +{ + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 } }"), "f"); + BOOST_CHECK_EQUAL(inlinableFunctions("{" + "function g(a:u256) -> b:u256 { b := a }" + "function f() -> x:u256 { x := g(2:u256) }" + "}"), "f,g"); +} + +BOOST_AUTO_TEST_CASE(simple_inside_structures) +{ + BOOST_CHECK_EQUAL(inlinableFunctions("{" + "switch 2:u256 " + "case 2:u256 {" + "function g(a:u256) -> b:u256 { b := a }" + "function f() -> x:u256 { x := g(2:u256) }" + "}" + "}"), "f,g"); + BOOST_CHECK_EQUAL(inlinableFunctions("{" + "for {" + "function g(a:u256) -> b:u256 { b := a }" + "} 1:u256 {" + "function f() -> x:u256 { x := g(2:u256) }" + "}" + "{" + "function h() -> y:u256 { y := 2:u256 }" + "}" + "}"), "f,g,h"); +} + +BOOST_AUTO_TEST_CASE(negative) +{ + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := 2:u256 {} } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := f() } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256 { x := x } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f() -> x:u256, y:u256 { x := 2:u256 } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions( + "{ function g() -> x:u256, y:u256 {} function f(y:u256) -> x:u256 { x,y := g() } }"), ""); + BOOST_CHECK_EQUAL(inlinableFunctions("{ function f(y:u256) -> x:u256 { y := 2:u256 } }"), ""); +} + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp new file mode 100644 index 00000000..3f329d28 --- /dev/null +++ b/test/libyul/Parser.cpp @@ -0,0 +1,306 @@ +/* + 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 . +*/ +/** + * @date 2017 + * Unit tests for parsing Yul. + */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +using namespace std; + +namespace dev +{ +namespace solidity +{ +namespace test +{ + +namespace +{ + +bool parse(string const& _source, ErrorReporter& errorReporter) +{ + try + { + auto scanner = make_shared(CharStream(_source)); + auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Yul).parse(scanner, false); + if (parserResult) + { + assembly::AsmAnalysisInfo analysisInfo; + return (assembly::AsmAnalyzer( + analysisInfo, + errorReporter, + dev::test::Options::get().evmVersion(), + boost::none, + assembly::AsmFlavour::Yul + )).analyze(*parserResult); + } + } + catch (FatalError const&) + { + BOOST_FAIL("Fatal error leaked."); + } + return false; +} + +boost::optional parseAndReturnFirstError(string const& _source, bool _allowWarnings = true) +{ + ErrorList errors; + ErrorReporter errorReporter(errors); + if (!parse(_source, errorReporter)) + { + BOOST_REQUIRE_EQUAL(errors.size(), 1); + return *errors.front(); + } + else + { + // If success is true, there might still be an error in the assembly stage. + if (_allowWarnings && Error::containsOnlyWarnings(errors)) + return {}; + else if (!errors.empty()) + { + if (!_allowWarnings) + BOOST_CHECK_EQUAL(errors.size(), 1); + return *errors.front(); + } + } + return {}; +} + +bool successParse(std::string const& _source, bool _allowWarnings = true) +{ + return !parseAndReturnFirstError(_source, _allowWarnings); +} + +Error expectError(std::string const& _source, bool _allowWarnings = false) +{ + + auto error = parseAndReturnFirstError(_source, _allowWarnings); + BOOST_REQUIRE(error); + return *error; +} + +} + +#define CHECK_ERROR(text, typ, substring) \ +do \ +{ \ + Error err = expectError((text), false); \ + BOOST_CHECK(err.type() == (Error::Type::typ)); \ + BOOST_CHECK(searchErrorMessage(err, (substring))); \ +} while(0) + +BOOST_AUTO_TEST_SUITE(YulParser) + +BOOST_AUTO_TEST_CASE(smoke_test) +{ + BOOST_CHECK(successParse("{ }")); +} + +BOOST_AUTO_TEST_CASE(vardecl) +{ + BOOST_CHECK(successParse("{ let x:u256 := 7:u256 }")); +} + +BOOST_AUTO_TEST_CASE(vardecl_bool) +{ + BOOST_CHECK(successParse("{ let x:bool := true:bool }")); + BOOST_CHECK(successParse("{ let x:bool := false:bool }")); +} + +BOOST_AUTO_TEST_CASE(vardecl_empty) +{ + BOOST_CHECK(successParse("{ let x:u256 }")); +} + +BOOST_AUTO_TEST_CASE(assignment) +{ + BOOST_CHECK(successParse("{ let x:u256 := 2:u256 let y:u256 := x }")); +} + +BOOST_AUTO_TEST_CASE(vardecl_complex) +{ + BOOST_CHECK(successParse("{ function add(a:u256, b:u256) -> c:u256 {} let y:u256 := 2:u256 let x:u256 := add(7:u256, add(6:u256, y)) }")); +} + +BOOST_AUTO_TEST_CASE(blocks) +{ + BOOST_CHECK(successParse("{ let x:u256 := 7:u256 { let y:u256 := 3:u256 } { let z:u256 := 2:u256 } }")); +} + +BOOST_AUTO_TEST_CASE(function_definitions) +{ + BOOST_CHECK(successParse("{ function f() { } function g(a:u256) -> x:u256 { } }")); +} + +BOOST_AUTO_TEST_CASE(function_definitions_multiple_args) +{ + BOOST_CHECK(successParse("{ function f(a:u256, d:u256) { } function g(a:u256, d:u256) -> x:u256, y:u256 { } }")); +} + +BOOST_AUTO_TEST_CASE(function_calls) +{ + BOOST_CHECK(successParse("{ function f(a:u256) -> b:u256 {} function g(a:u256, b:u256, c:u256) {} function x() { g(1:u256, 2:u256, f(3:u256)) x() } }")); +} + +BOOST_AUTO_TEST_CASE(tuple_assignment) +{ + BOOST_CHECK(successParse("{ function f() -> a:u256, b:u256, c:u256 {} let x:u256, y:u256, z:u256 := f() }")); +} + +BOOST_AUTO_TEST_CASE(label) +{ + CHECK_ERROR("{ label: }", ParserError, "Labels are not supported."); +} + +BOOST_AUTO_TEST_CASE(instructions) +{ + CHECK_ERROR("{ pop }", ParserError, "Call or assignment expected."); +} + +BOOST_AUTO_TEST_CASE(push) +{ + CHECK_ERROR("{ 0x42:u256 }", ParserError, "Call or assignment expected."); +} + +BOOST_AUTO_TEST_CASE(assign_from_stack) +{ + CHECK_ERROR("{ =: x:u256 }", ParserError, "Literal or identifier expected."); +} + +BOOST_AUTO_TEST_CASE(empty_call) +{ + CHECK_ERROR("{ () }", ParserError, "Literal or identifier expected."); +} + +BOOST_AUTO_TEST_CASE(tokens_as_identifers) +{ + BOOST_CHECK(successParse("{ let return:u256 := 1:u256 }")); + BOOST_CHECK(successParse("{ let byte:u256 := 1:u256 }")); + BOOST_CHECK(successParse("{ let address:u256 := 1:u256 }")); + BOOST_CHECK(successParse("{ let bool:u256 := 1:u256 }")); +} + +BOOST_AUTO_TEST_CASE(lacking_types) +{ + CHECK_ERROR("{ let x := 1:u256 }", ParserError, "Expected identifier but got '='"); + CHECK_ERROR("{ let x:u256 := 1 }", ParserError, "Expected ':' but got '}'"); + CHECK_ERROR("{ function f(a) {} }", ParserError, "Expected ':' but got ')'"); + CHECK_ERROR("{ function f(a:u256) -> b {} }", ParserError, "Expected ':' but got '{'"); +} + +BOOST_AUTO_TEST_CASE(invalid_types) +{ + /// testing invalid literal + /// NOTE: these will need to change when types are compared + CHECK_ERROR("{ let x:bool := 1:invalid }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported)."); + /// testing invalid variable declaration + CHECK_ERROR("{ let x:invalid := 1:bool }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported)."); + CHECK_ERROR("{ function f(a:invalid) {} }", TypeError, "\"invalid\" is not a valid type (user defined types are not yet supported)."); +} + +BOOST_AUTO_TEST_CASE(number_literals) +{ + BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }")); + CHECK_ERROR("{ let x:u256 := .1:u256 }", ParserError, "Invalid number literal."); + CHECK_ERROR("{ let x:u256 := 1e5:u256 }", ParserError, "Invalid number literal."); + CHECK_ERROR("{ let x:u256 := 67.235:u256 }", ParserError, "Invalid number literal."); + CHECK_ERROR("{ let x:u256 := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff:u256 }", TypeError, "Number literal too large (> 256 bits)"); +} + +BOOST_AUTO_TEST_CASE(builtin_types) +{ + BOOST_CHECK(successParse("{ let x:bool := true:bool }")); + BOOST_CHECK(successParse("{ let x:u8 := 1:u8 }")); + BOOST_CHECK(successParse("{ let x:s8 := 1:u8 }")); + BOOST_CHECK(successParse("{ let x:u32 := 1:u32 }")); + BOOST_CHECK(successParse("{ let x:s32 := 1:s32 }")); + BOOST_CHECK(successParse("{ let x:u64 := 1:u64 }")); + BOOST_CHECK(successParse("{ let x:s64 := 1:s64 }")); + BOOST_CHECK(successParse("{ let x:u128 := 1:u128 }")); + BOOST_CHECK(successParse("{ let x:s128 := 1:s128 }")); + BOOST_CHECK(successParse("{ let x:u256 := 1:u256 }")); + BOOST_CHECK(successParse("{ let x:s256 := 1:s256 }")); +} + +BOOST_AUTO_TEST_CASE(recursion_depth) +{ + string input; + for (size_t i = 0; i < 20000; i++) + input += "{"; + input += "let x:u256 := 0:u256"; + for (size_t i = 0; i < 20000; i++) + input += "}"; + + CHECK_ERROR(input, ParserError, "recursion"); +} + +BOOST_AUTO_TEST_CASE(multiple_assignment) +{ + CHECK_ERROR("{ let x:u256 function f() -> a:u256, b:u256 {} 123:u256, x := f() }", ParserError, "Label name / variable name must precede \",\" (multiple assignment)."); + CHECK_ERROR("{ let x:u256 function f() -> a:u256, b:u256 {} x, 123:u256 := f() }", ParserError, "Variable name expected in multiple assignment."); + + /// NOTE: Travis hiccups if not having a variable + char const* text = R"( + { + function f(a:u256) -> r1:u256, r2:u256 { + r1 := a + r2 := 7:u256 + } + let x:u256 := 9:u256 + let y:u256 := 2:u256 + x, y := f(x) + } + )"; + BOOST_CHECK(successParse(text)); +} + +BOOST_AUTO_TEST_CASE(if_statement) +{ + BOOST_CHECK(successParse("{ if true:bool {} }")); + BOOST_CHECK(successParse("{ if false:bool { let x:u256 := 3:u256 } }")); + BOOST_CHECK(successParse("{ function f() -> x:bool {} if f() { let b:bool := f() } }")); +} + +BOOST_AUTO_TEST_CASE(if_statement_invalid) +{ + CHECK_ERROR("{ if let x:u256 {} }", ParserError, "Literal or identifier expected."); + CHECK_ERROR("{ if true:bool let x:u256 := 3:u256 }", ParserError, "Expected '{' but got reserved keyword 'let'"); + // TODO change this to an error once we check types. + BOOST_CHECK(successParse("{ if 42:u256 { } }")); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} +} // end namespaces diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp new file mode 100644 index 00000000..62a4aa10 --- /dev/null +++ b/test/libyul/YulOptimizerTest.cpp @@ -0,0 +1,239 @@ +/* + 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 . +*/ + +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +using namespace dev; +using namespace dev::julia; +using namespace dev::julia::test; +using namespace dev::solidity; +using namespace dev::solidity::test; +using namespace std; + +YulOptimizerTest::YulOptimizerTest(string const& _filename) +{ + boost::filesystem::path path(_filename); + + if (path.empty() || std::next(path.begin()) == path.end() || std::next(std::next(path.begin())) == path.end()) + BOOST_THROW_EXCEPTION(runtime_error("Filename path has to contain a directory: \"" + _filename + "\".")); + m_optimizerStep = std::prev(std::prev(path.end()))->string(); + + ifstream file(_filename); + if (!file) + BOOST_THROW_EXCEPTION(runtime_error("Cannot open test case: \"" + _filename + "\".")); + file.exceptions(ios::badbit); + + string line; + while (getline(file, line)) + { + if (boost::algorithm::starts_with(line, "// ----")) + break; + if (m_source.empty() && boost::algorithm::starts_with(line, "// yul")) + m_yul = true; + m_source += line + "\n"; + } + while (getline(file, line)) + if (boost::algorithm::starts_with(line, "// ")) + m_expectation += line.substr(3) + "\n"; + else + m_expectation += line + "\n"; +} + +bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool const _formatted) +{ + assembly::AsmPrinter printer{m_yul}; + shared_ptr ast; + shared_ptr analysisInfo; + if (!parse(_stream, _linePrefix, _formatted)) + return false; + + if (m_optimizerStep == "disambiguator") + disambiguate(); + else if (m_optimizerStep == "commonSubexpressionEliminator") + { + disambiguate(); + (CommonSubexpressionEliminator{})(*m_ast); + } + else if (m_optimizerStep == "expressionSplitter") + { + NameDispenser nameDispenser; + nameDispenser.m_usedNames = NameCollector(*m_ast).names(); + ExpressionSplitter{nameDispenser}(*m_ast); + } + else if (m_optimizerStep == "functionGrouper") + { + disambiguate(); + (FunctionGrouper{})(*m_ast); + } + else if (m_optimizerStep == "functionHoister") + { + disambiguate(); + (FunctionHoister{})(*m_ast); + } + else if (m_optimizerStep == "expressionInliner") + { + disambiguate(); + ExpressionInliner(*m_ast).run(); + } + else if (m_optimizerStep == "fullInliner") + { + disambiguate(); + (FunctionHoister{})(*m_ast); + (FunctionGrouper{})(*m_ast); + FullInliner(*m_ast).run(); + } + else if (m_optimizerStep == "mainFunction") + { + disambiguate(); + (FunctionGrouper{})(*m_ast); + (MainFunction{})(*m_ast); + } + else if (m_optimizerStep == "rematerialiser") + { + disambiguate(); + (Rematerialiser{})(*m_ast); + } + else if (m_optimizerStep == "expressionSimplifier") + { + disambiguate(); + (ExpressionSimplifier{})(*m_ast); + } + else if (m_optimizerStep == "unusedPruner") + { + disambiguate(); + UnusedPruner::runUntilStabilised(*m_ast); + } + else if (m_optimizerStep == "expressionJoiner") + { + disambiguate(); + ExpressionJoiner::run(*m_ast);\ + } + else + { + FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Invalid optimizer step: " << m_optimizerStep << endl; + return false; + } + + m_obtainedResult = m_optimizerStep + "\n" + printer(*m_ast) + "\n"; + + if (m_expectation != m_obtainedResult) + { + string nextIndentLevel = _linePrefix + " "; + FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Expected result:" << endl; + // TODO could compute a simple diff with highlighted lines + printIndented(_stream, m_expectation, nextIndentLevel); + FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::CYAN}) << _linePrefix << "Obtained result:" << endl; + printIndented(_stream, m_obtainedResult, nextIndentLevel); + return false; + } + return true; +} + +void YulOptimizerTest::printSource(ostream& _stream, string const& _linePrefix, bool const) const +{ + printIndented(_stream, m_source, _linePrefix); +} + +void YulOptimizerTest::printUpdatedExpectations(ostream& _stream, string const& _linePrefix) const +{ + printIndented(_stream, m_obtainedResult, _linePrefix); +} + +void YulOptimizerTest::printIndented(ostream& _stream, string const& _output, string const& _linePrefix) const +{ + stringstream output(_output); + string line; + while (getline(output, line)) + _stream << _linePrefix << line << endl; +} + +bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted) +{ + assembly::AsmFlavour flavour = m_yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict; + ErrorList errors; + ErrorReporter errorReporter(errors); + shared_ptr scanner = make_shared(CharStream(m_source), ""); + m_ast = assembly::Parser(errorReporter, flavour).parse(scanner, false); + if (!m_ast || !errorReporter.errors().empty()) + { + FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl; + printErrors(_stream, errorReporter.errors(), *scanner); + return false; + } + m_analysisInfo = make_shared(); + assembly::AsmAnalyzer analyzer( + *m_analysisInfo, + errorReporter, + dev::test::Options::get().evmVersion(), + boost::none, + flavour + ); + if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) + { + FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error analyzing source." << endl; + printErrors(_stream, errorReporter.errors(), *scanner); + return false; + } + return true; +} + +void YulOptimizerTest::disambiguate() +{ + *m_ast = boost::get(Disambiguator(*m_analysisInfo)(*m_ast)); + m_analysisInfo.reset(); +} + +void YulOptimizerTest::printErrors(ostream& _stream, ErrorList const& _errors, Scanner const& _scanner) +{ + SourceReferenceFormatter formatter(_stream, [&](string const&) -> Scanner const& { return _scanner; }); + + for (auto const& error: _errors) + formatter.printExceptionInformation( + *error, + (error->type() == Error::Type::Warning) ? "Warning" : "Error" + ); +} diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h new file mode 100644 index 00000000..8f9a81f7 --- /dev/null +++ b/test/libyul/YulOptimizerTest.h @@ -0,0 +1,75 @@ +/* + 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 . +*/ + +#pragma once + +#include + + +namespace dev +{ +namespace solidity +{ +class Scanner; +class Error; +using ErrorList = std::vector>; +namespace assembly +{ +struct AsmAnalysisInfo; +struct Block; +} +} +namespace julia +{ +namespace test +{ + +class YulOptimizerTest: public solidity::test::TestCase +{ +public: + static std::unique_ptr create(std::string const& _filename) + { + return std::unique_ptr(new YulOptimizerTest(_filename)); + } + + explicit YulOptimizerTest(std::string const& _filename); + + bool run(std::ostream& _stream, std::string const& _linePrefix = "", bool const _formatted = false) override; + + void printSource(std::ostream& _stream, std::string const &_linePrefix = "", bool const _formatted = false) const override; + void printUpdatedExpectations(std::ostream& _stream, std::string const& _linePrefix) const override; + +private: + void printIndented(std::ostream& _stream, std::string const& _output, std::string const& _linePrefix = "") const; + bool parse(std::ostream& _stream, std::string const& _linePrefix, bool const _formatted); + void disambiguate(); + + static void printErrors(std::ostream& _stream, solidity::ErrorList const& _errors, solidity::Scanner const& _scanner); + + std::string m_source; + bool m_yul = false; + std::string m_optimizerStep; + std::string m_expectation; + + std::shared_ptr m_ast; + std::shared_ptr m_analysisInfo; + std::string m_obtainedResult; +}; + +} +} +} diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul new file mode 100644 index 00000000..c59bced7 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_for.yul @@ -0,0 +1,24 @@ +{ + let a := 1 let b := codesize() + for { } lt(1, codesize()) { mstore(1, codesize()) a := add(a, codesize()) } { + mstore(1, codesize()) + } + mstore(1, codesize()) +} +// ---- +// commonSubexpressionEliminator +// { +// let a := 1 +// let b := codesize() +// for { +// } +// lt(1, b) +// { +// mstore(1, b) +// a := add(a, b) +// } +// { +// mstore(1, b) +// } +// mstore(1, b) +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_if.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_if.yul new file mode 100644 index 00000000..5b8200d9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/branches_if.yul @@ -0,0 +1,15 @@ +{ + let b := 1 + if b { b := 1 } + let c := 1 +} +// ---- +// commonSubexpressionEliminator +// { +// let b := 1 +// if b +// { +// b := b +// } +// let c := 1 +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr.yul new file mode 100644 index 00000000..cb0ca38d --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr.yul @@ -0,0 +1,10 @@ +{ + let a := mload(1) + let b := mload(1) +} +// ---- +// commonSubexpressionEliminator +// { +// let a := mload(1) +// let b := mload(1) +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul new file mode 100644 index 00000000..ebc17446 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/non_movable_instr2.yul @@ -0,0 +1,10 @@ +{ + let a := gas() + let b := gas() +} +// ---- +// commonSubexpressionEliminator +// { +// let a := gas() +// let b := gas() +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/smoke.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/smoke.yul new file mode 100644 index 00000000..b9457229 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// commonSubexpressionEliminator +// { +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul new file mode 100644 index 00000000..684272f5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/trivial.yul @@ -0,0 +1,10 @@ +{ + let a := mul(1, codesize()) + let b := mul(1, codesize()) +} +// ---- +// commonSubexpressionEliminator +// { +// let a := mul(1, codesize()) +// let b := a +// } diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/variable_for_variable.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/variable_for_variable.yul new file mode 100644 index 00000000..ab94afc2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/variable_for_variable.yul @@ -0,0 +1,27 @@ +{ + + let a := mload(0) + let b := add(a, 7) + let c := a + let d := c + let x := add(a, b) + // CSE has to recognize equality with x here. + let y := add(d, add(c, 7)) + // some reassignments + b := mload(a) + a := b + mstore(2, a) +} +// ---- +// commonSubexpressionEliminator +// { +// let a := mload(0) +// let b := add(a, 7) +// let c := a +// let d := a +// let x := add(a, b) +// let y := x +// b := mload(a) +// a := b +// mstore(2, b) +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul new file mode 100644 index 00000000..0d2a38c5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/for_statement.yul @@ -0,0 +1,28 @@ +// yul +{ + { let a:u256, b:u256 } + { + for { let a:u256 } a { a := a } { + let b:u256 := a + } + } +} +// ---- +// disambiguator +// { +// { +// let a:u256, b:u256 +// } +// { +// for { +// let a_1:u256 +// } +// a_1 +// { +// a_1 := a_1 +// } +// { +// let b_1:u256 := a_1 +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul new file mode 100644 index 00000000..f917bb68 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/funtion_call.yul @@ -0,0 +1,22 @@ +// yul +{ + { let a:u256, b:u256, c:u256, d:u256, f:u256 } + { + function f(a:u256) -> c:u256, d:u256 { + let b:u256, c_1:u256 := f(a) + } + } +} +// ---- +// disambiguator +// { +// { +// let a:u256, b:u256, c:u256, d:u256, f:u256 +// } +// { +// function f_1(a_1:u256) -> c_1:u256, d_1:u256 +// { +// let b_1:u256, c_1_1:u256 := f_1(a_1) +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul new file mode 100644 index 00000000..14f53757 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/if_statement.yul @@ -0,0 +1,22 @@ +// yul +{ + { let a:u256, b:u256, c:u256 } + { + let a:bool + if a { let b:bool := a } + } +} +// ---- +// disambiguator +// { +// { +// let a:u256, b:u256, c:u256 +// } +// { +// let a_1:bool +// if a_1 +// { +// let b_1:bool := a_1 +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/smoke.yul b/test/libyul/yulOptimizerTests/disambiguator/smoke.yul new file mode 100644 index 00000000..d6cd8a61 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// disambiguator +// { +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul b/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul new file mode 100644 index 00000000..e55f4cd3 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/smoke_yul.yul @@ -0,0 +1,6 @@ +// yul +{ } +// ---- +// disambiguator +// { +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul new file mode 100644 index 00000000..340ecccf --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/switch_statement.yul @@ -0,0 +1,27 @@ +// yul +{ + { let a:u256, b:u256, c:u256 } + { + let a:u256 + switch a + case 0:u256 { let b:u256 := a } + default { let c:u256 := a } + } +} +// ---- +// disambiguator +// { +// { +// let a:u256, b:u256, c:u256 +// } +// { +// let a_1:u256 +// switch a_1 +// case 0:u256 { +// let b_1:u256 := a_1 +// } +// default { +// let c_1:u256 := a_1 +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables.yul b/test/libyul/yulOptimizerTests/disambiguator/variables.yul new file mode 100644 index 00000000..65bd4c8f --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/variables.yul @@ -0,0 +1,12 @@ +// yul +{ { let a:u256 } { let a:u256 } } +// ---- +// disambiguator +// { +// { +// let a:u256 +// } +// { +// let a_1:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul new file mode 100644 index 00000000..e462442a --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_clash.yul @@ -0,0 +1,13 @@ +// yul +{ { let a:u256 let a_1:u256 } { let a:u256 } } +// ---- +// disambiguator +// { +// { +// let a:u256 +// let a_1:u256 +// } +// { +// let a_2:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul new file mode 100644 index 00000000..e80959f6 --- /dev/null +++ b/test/libyul/yulOptimizerTests/disambiguator/variables_inside_functions.yul @@ -0,0 +1,24 @@ +// yul +{ + { let c:u256 let b:u256 } + function f(a:u256, c:u256) -> b:u256 { let x:u256 } + { + let a:u256 let x:u256 + } +} +// ---- +// disambiguator +// { +// { +// let c:u256 +// let b:u256 +// } +// function f(a:u256, c_1:u256) -> b_1:u256 +// { +// let x:u256 +// } +// { +// let a_1:u256 +// let x_1:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/complex_with_evm.yul b/test/libyul/yulOptimizerTests/expressionInliner/complex_with_evm.yul new file mode 100644 index 00000000..519a2af8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/complex_with_evm.yul @@ -0,0 +1,13 @@ +{ + function f(a) -> x { x := add(a, a) } + let y := f(calldatasize()) +} +// ---- +// expressionInliner +// { +// function f(a) -> x +// { +// x := add(a, a) +// } +// let y := add(calldatasize(), calldatasize()) +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/double_calls.yul b/test/libyul/yulOptimizerTests/expressionInliner/double_calls.yul new file mode 100644 index 00000000..e1da8e07 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/double_calls.yul @@ -0,0 +1,18 @@ +{ + function f(a) -> x { x := add(a, a) } + function g(b, c) -> y { y := mul(mload(c), f(b)) } + let y := g(calldatasize(), 7) +} +// ---- +// expressionInliner +// { +// function f(a) -> x +// { +// x := add(a, a) +// } +// function g(b, c) -> y +// { +// y := mul(mload(c), add(b, b)) +// } +// let y_1 := mul(mload(7), add(calldatasize(), calldatasize())) +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/double_recursive_calls.yul b/test/libyul/yulOptimizerTests/expressionInliner/double_recursive_calls.yul new file mode 100644 index 00000000..082cb53f --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/double_recursive_calls.yul @@ -0,0 +1,18 @@ +{ + function f(a, r) -> x { x := g(a, g(r, r)) } + function g(b, s) -> y { y := f(b, f(s, s)) } + let y := g(calldatasize(), 7) +} +// ---- +// expressionInliner +// { +// function f(a, r) -> x +// { +// x := g(a, f(r, f(r, r))) +// } +// function g(b, s) -> y +// { +// y := f(b, g(s, f(s, f(s, s)))) +// } +// let y_1 := f(calldatasize(), g(7, f(7, f(7, 7)))) +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/no_inline_mload.yul b/test/libyul/yulOptimizerTests/expressionInliner/no_inline_mload.yul new file mode 100644 index 00000000..0fb43a9d --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/no_inline_mload.yul @@ -0,0 +1,14 @@ +// Does not inline because mload could be moved out of sequence +{ + function f(a) -> x { x := a } + let y := f(mload(2)) +} +// ---- +// expressionInliner +// { +// function f(a) -> x +// { +// x := a +// } +// let y := f(mload(2)) +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/no_move_with_sideeffects.yul b/test/libyul/yulOptimizerTests/expressionInliner/no_move_with_sideeffects.yul new file mode 100644 index 00000000..7fdad6c4 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/no_move_with_sideeffects.yul @@ -0,0 +1,27 @@ +// The calls to g and h cannot be moved because g and h are not movable. Therefore, the call +// to f is not inlined. +{ + function f(a, b) -> x { x := add(b, a) } + function g() -> y { y := mload(0) mstore(0, 4) } + function h() -> z { mstore(0, 4) z := mload(0) } + let r := f(g(), h()) +} +// ---- +// expressionInliner +// { +// function f(a, b) -> x +// { +// x := add(b, a) +// } +// function g() -> y +// { +// y := mload(0) +// mstore(0, 4) +// } +// function h() -> z +// { +// mstore(0, 4) +// z := mload(0) +// } +// let r := f(g(), h()) +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/simple.yul b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul new file mode 100644 index 00000000..c186eafd --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/simple.yul @@ -0,0 +1,14 @@ +// yul +{ + function f() -> x:u256 { x := 2:u256 } + let y:u256 := f() +} +// ---- +// expressionInliner +// { +// function f() -> x:u256 +// { +// x := 2:u256 +// } +// let y:u256 := 2:u256 +// } diff --git a/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul new file mode 100644 index 00000000..b5f4d515 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionInliner/with_args.yul @@ -0,0 +1,14 @@ +// yul +{ + function f(a:u256) -> x:u256 { x := a } + let y:u256 := f(7:u256) +} +// ---- +// expressionInliner +// { +// function f(a:u256) -> x:u256 +// { +// x := a +// } +// let y:u256 := 7:u256 +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul b/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul new file mode 100644 index 00000000..a1349511 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/if_condition.yul @@ -0,0 +1,21 @@ +{ + let a := mload(3) + let b := sload(a) + let c := mload(7) + let d := add(c, b) + if d { + let x := mload(3) + let y := add(x, 3) + } + let z := 3 + let t := add(z, 9) +} +// ---- +// expressionJoiner +// { +// if add(mload(7), sload(mload(3))) +// { +// let y := add(mload(3), 3) +// } +// let t := add(3, 9) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul b/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul new file mode 100644 index 00000000..0d407c7c --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/muli_wrong_order3.yul @@ -0,0 +1,13 @@ +{ + let a := mload(3) + let b := mload(6) + let x := mul(add(b, a), mload(2)) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// let a := mload(3) +// let b := mload(6) +// sstore(mul(add(b, a), mload(2)), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul new file mode 100644 index 00000000..fd53ca51 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi.yul @@ -0,0 +1,11 @@ +{ + let a := mload(2) + let b := mload(6) + let x := mul(add(b, a), 2) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// sstore(mul(add(mload(6), mload(2)), 2), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul new file mode 100644 index 00000000..078a12a5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_reference.yul @@ -0,0 +1,11 @@ +{ + // This is not joined because a is referenced multiple times + let a := mload(2) + let b := add(a, a) +} +// ---- +// expressionJoiner +// { +// let a := mload(2) +// let b := add(a, a) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul new file mode 100644 index 00000000..965e07e9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order.yul @@ -0,0 +1,15 @@ +{ + // We have an interleaved "add" here, so we cannot inline "a" + // (note that this component does not analyze whether + // functions are pure or not) + let a := mload(2) + let b := mload(6) + let x := mul(a, add(2, b)) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// let a := mload(2) +// sstore(mul(a, add(2, mload(6))), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul new file mode 100644 index 00000000..c577e182 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/multi_wrong_order2.yul @@ -0,0 +1,12 @@ +{ + let a := mload(2) + let b := mload(6) + let x := mul(add(a, b), 2) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// let a := mload(2) +// sstore(mul(add(a, mload(6)), 2), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul new file mode 100644 index 00000000..a781bb2a --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_across_blocks.yul @@ -0,0 +1,19 @@ +{ + // The component will remove the empty block after + // it has handled the outer block. + // The idea behind this test is that the component + // does not perform replacements across blocks because + // they usually have contents, but adding contents + // will reduce the scope of the test. + let a := mload(2) + let x := calldataload(a) + { + } + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// let x := calldataload(mload(2)) +// sstore(x, 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul new file mode 100644 index 00000000..75218a5c --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition1.yul @@ -0,0 +1,15 @@ +{ + for { let b := mload(1) } b {} {} +} +// ---- +// expressionJoiner +// { +// for { +// let b := mload(1) +// } +// b +// { +// } +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul new file mode 100644 index 00000000..d5f7d8fa --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/no_replacement_in_loop_condition2.yul @@ -0,0 +1,16 @@ +{ + let a := mload(0) + for { } a {} {} +} +// ---- +// expressionJoiner +// { +// let a := mload(0) +// for { +// } +// a +// { +// } +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul b/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul new file mode 100644 index 00000000..c7411211 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/only_assignment.yul @@ -0,0 +1,16 @@ +{ + // This is not joined because a is referenced multiple times + function f(a) -> x { + a := mload(2) + x := add(a, 3) + } +} +// ---- +// expressionJoiner +// { +// function f(a) -> x +// { +// a := mload(2) +// x := add(a, 3) +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul b/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul new file mode 100644 index 00000000..1e502353 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/reassignment.yul @@ -0,0 +1,13 @@ +{ + // This is not joined because a is referenced multiple times + let a := mload(2) + let b := mload(a) + a := 4 +} +// ---- +// expressionJoiner +// { +// let a := mload(2) +// let b := mload(a) +// a := 4 +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul b/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul new file mode 100644 index 00000000..b03bcf45 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/simple.yul @@ -0,0 +1,10 @@ +{ + let a := mload(2) + let x := calldataload(a) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// sstore(calldataload(mload(2)), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul b/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul new file mode 100644 index 00000000..3b433f78 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/single_wrong_order.yul @@ -0,0 +1,13 @@ +{ + let a := mload(3) + let b := sload(a) + let c := mload(7) + let d := add(b, c) + sstore(d, 0) +} +// ---- +// expressionJoiner +// { +// let b := sload(mload(3)) +// sstore(add(b, mload(7)), 0) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul b/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul new file mode 100644 index 00000000..c0e2c6f2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// expressionJoiner +// { +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul b/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul new file mode 100644 index 00000000..0e4e540e --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/switch_expression.yul @@ -0,0 +1,28 @@ +{ + let a := mload(3) + let b := sload(a) + let c := mload(7) + let d := add(c, b) + switch d + case 3 { + let x := mload(3) + let y := add(x, 3) + } + default { + sstore(1, 0) + } + let z := 3 + let t := add(z, 9) +} +// ---- +// expressionJoiner +// { +// switch add(mload(7), sload(mload(3))) +// case 3 { +// let y := add(mload(3), 3) +// } +// default { +// sstore(1, 0) +// } +// let t := add(3, 9) +// } diff --git a/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul b/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul new file mode 100644 index 00000000..7b722be1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionJoiner/triple.yul @@ -0,0 +1,12 @@ +{ + let a := mload(2) + let b := mload(6) + let c := mload(7) + let x := mul(add(c, b), a) + sstore(x, 3) +} +// ---- +// expressionJoiner +// { +// sstore(mul(add(mload(7), mload(6)), mload(2)), 3) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul new file mode 100644 index 00000000..0b55adc5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/constant_propagation.yul @@ -0,0 +1,6 @@ +{ let a := add(7, sub(mload(0), 7)) } +// ---- +// expressionSimplifier +// { +// let a := mload(0) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul new file mode 100644 index 00000000..bd1a5a53 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/constants.yul @@ -0,0 +1,6 @@ +{ let a := add(1, mul(3, 4)) } +// ---- +// expressionSimplifier +// { +// let a := 13 +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul new file mode 100644 index 00000000..f6190622 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_complex.yul @@ -0,0 +1,6 @@ +{ let a := sub(calldataload(0), calldataload(0)) } +// ---- +// expressionSimplifier +// { +// let a := 0 +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul new file mode 100644 index 00000000..e91403cd --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_negative.yul @@ -0,0 +1,6 @@ +{ let a := sub(calldataload(1), calldataload(0)) } +// ---- +// expressionSimplifier +// { +// let a := sub(calldataload(1), calldataload(0)) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul new file mode 100644 index 00000000..d35686cd --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/identity_rules_simple.yul @@ -0,0 +1,10 @@ +{ + let a := mload(0) + let b := sub(a, a) +} +// ---- +// expressionSimplifier +// { +// let a := mload(0) +// let b := 0 +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul new file mode 100644 index 00000000..c2ca504a --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/including_function_calls.yul @@ -0,0 +1,12 @@ +{ + function f() -> a {} + let b := add(7, sub(f(), 7)) +} +// ---- +// expressionSimplifier +// { +// function f() -> a +// { +// } +// let b := f() +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul new file mode 100644 index 00000000..42c37826 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/inside_for.yul @@ -0,0 +1,16 @@ +{ + for { let a := 10 } iszero(eq(a, 0)) { a := add(a, 1) } {} +} +// ---- +// expressionSimplifier +// { +// for { +// let a := 10 +// } +// iszero(iszero(a)) +// { +// a := add(a, 1) +// } +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul new file mode 100644 index 00000000..e6d84552 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/invariant.yul @@ -0,0 +1,10 @@ +{ + let a := mload(sub(7, 7)) + let b := sub(a, 0) +} +// ---- +// expressionSimplifier +// { +// let a := mload(0) +// let b := a +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul new file mode 100644 index 00000000..88714ce0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_1.yul @@ -0,0 +1,8 @@ +{ + mstore(0, mod(calldataload(0), exp(2, 8))) +} +// ---- +// expressionSimplifier +// { +// mstore(0, and(calldataload(0), 255)) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul new file mode 100644 index 00000000..4d52abe8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/mod_and_2.yul @@ -0,0 +1,8 @@ +{ + mstore(0, mod(calldataload(0), exp(2, 255))) +} +// ---- +// expressionSimplifier +// { +// mstore(0, and(calldataload(0), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul new file mode 100644 index 00000000..53270b72 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_arguments.yul @@ -0,0 +1,12 @@ +{ + function f(a) -> b { } + let c := sub(f(0), f(1)) +} +// ---- +// expressionSimplifier +// { +// function f(a) -> b +// { +// } +// let c := sub(f(0), f(1)) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul new file mode 100644 index 00000000..6ab65d29 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_different_names.yul @@ -0,0 +1,16 @@ +{ + function f1() -> a { } + function f2() -> b { } + let c := sub(f1(), f2()) +} +// ---- +// expressionSimplifier +// { +// function f1() -> a +// { +// } +// function f2() -> b +// { +// } +// let c := sub(f1(), f2()) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul new file mode 100644 index 00000000..ab1bd128 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_function_call_equality_not_movable.yul @@ -0,0 +1,13 @@ +// Even if the functions pass the equality check, they are not movable. +{ + function f() -> a { } + let b := sub(f(), f()) +} +// ---- +// expressionSimplifier +// { +// function f() -> a +// { +// } +// let b := sub(f(), f()) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul new file mode 100644 index 00000000..fc61c3df --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/not_applied_removes_non_constant_and_not_movable.yul @@ -0,0 +1,10 @@ +// The first argument of div is not constant. +// keccak256 is not movable. +{ + let a := div(keccak256(0, 0), 0) +} +// ---- +// expressionSimplifier +// { +// let a := div(keccak256(0, 0), 0) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul new file mode 100644 index 00000000..6353cda9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/reversed.yul @@ -0,0 +1,8 @@ +{ + let a := add(0, mload(0)) +} +// ---- +// expressionSimplifier +// { +// let a := mload(0) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul new file mode 100644 index 00000000..88420e92 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// expressionSimplifier +// { +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/control_flow.yul b/test/libyul/yulOptimizerTests/expressionSplitter/control_flow.yul new file mode 100644 index 00000000..d021129f --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/control_flow.yul @@ -0,0 +1,40 @@ +{ + let x := calldataload(0) + if mul(add(x, 2), 3) { + for { let a := 2 } lt(a, mload(a)) { a := add(a, mul(a, 2)) } { + let b := mul(add(a, 2), 4) + sstore(b, mul(b, 2)) + } + } +} +// ---- +// expressionSplitter +// { +// let _1 := 0 +// let x := calldataload(_1) +// let _2 := 3 +// let _3 := 2 +// let _4 := add(x, _3) +// let _5 := mul(_4, _2) +// if _5 +// { +// for { +// let a := 2 +// } +// lt(a, mload(a)) +// { +// let _6 := 2 +// let _7 := mul(a, _6) +// a := add(a, _7) +// } +// { +// let _8 := 4 +// let _9 := 2 +// let _10 := add(a, _9) +// let b := mul(_10, _8) +// let _11 := 2 +// let _12 := mul(b, _11) +// sstore(b, _12) +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/inside_function.yul b/test/libyul/yulOptimizerTests/expressionSplitter/inside_function.yul new file mode 100644 index 00000000..53bbcea7 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/inside_function.yul @@ -0,0 +1,29 @@ +{ + let x := mul(f(0, mload(7)), 3) + function f(a, b) -> c { + c := mul(a, mload(add(b, c))) + } + sstore(x, f(mload(2), mload(2))) +} +// ---- +// expressionSplitter +// { +// let _1 := 3 +// let _2 := 7 +// let _3 := mload(_2) +// let _4 := 0 +// let _5 := f(_4, _3) +// let x := mul(_5, _1) +// function f(a, b) -> c +// { +// let _6 := add(b, c) +// let _7 := mload(_6) +// c := mul(a, _7) +// } +// let _8 := 2 +// let _9 := mload(_8) +// let _10 := 2 +// let _11 := mload(_10) +// let _12 := f(_11, _9) +// sstore(x, _12) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/smoke.yul b/test/libyul/yulOptimizerTests/expressionSplitter/smoke.yul new file mode 100644 index 00000000..f69f60b6 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// expressionSplitter +// { +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/switch.yul b/test/libyul/yulOptimizerTests/expressionSplitter/switch.yul new file mode 100644 index 00000000..aee7976f --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/switch.yul @@ -0,0 +1,33 @@ +{ + let x := 8 + switch add(2, calldataload(0)) + case 0 { sstore(0, mload(2)) } + default { mstore(0, mload(3)) } + x := add(mload(3), 4) +} +// ---- +// expressionSplitter +// { +// let x := 8 +// let _1 := 0 +// let _2 := calldataload(_1) +// let _3 := 2 +// let _4 := add(_3, _2) +// switch _4 +// case 0 { +// let _5 := 2 +// let _6 := mload(_5) +// let _7 := 0 +// sstore(_7, _6) +// } +// default { +// let _8 := 3 +// let _9 := mload(_8) +// let _10 := 0 +// mstore(_10, _9) +// } +// let _11 := 4 +// let _12 := 3 +// let _13 := mload(_12) +// x := add(_13, _11) +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/trivial.yul b/test/libyul/yulOptimizerTests/expressionSplitter/trivial.yul new file mode 100644 index 00000000..bff70cd8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/trivial.yul @@ -0,0 +1,14 @@ +{ + mstore(add(calldataload(2), mload(3)), 8) +} +// ---- +// expressionSplitter +// { +// let _1 := 8 +// let _2 := 3 +// let _3 := mload(_2) +// let _4 := 2 +// let _5 := calldataload(_4) +// let _6 := add(_5, _3) +// mstore(_6, _1) +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul new file mode 100644 index 00000000..ae25e9a3 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul @@ -0,0 +1,32 @@ +// This tests that breaking the expression inside the condition works properly. +{ + if gt(f(mload(1)), mload(0)) { + sstore(0, 2) + } + function f(a) -> r { + a := mload(a) + r := add(a, calldatasize()) + } +} +// ---- +// fullInliner +// { +// { +// let _1 := mload(0) +// let f_a := mload(1) +// let f_r +// { +// f_a := mload(f_a) +// f_r := add(f_a, calldatasize()) +// } +// if gt(f_r, _1) +// { +// sstore(0, 2) +// } +// } +// function f(a) -> r +// { +// a := mload(a) +// r := add(a, calldatasize()) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul new file mode 100644 index 00000000..e1def585 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul @@ -0,0 +1,28 @@ +{ + function f(a, b, c) -> x { + x := add(a, b) + x := mul(x, c) + } + let y := add(mload(1), add(f(mload(2), mload(3), mload(4)), mload(5))) +} +// ---- +// fullInliner +// { +// { +// let _1 := mload(5) +// let f_c := mload(4) +// let f_b := mload(3) +// let f_a := mload(2) +// let f_x +// { +// f_x := add(f_a, f_b) +// f_x := mul(f_x, f_c) +// } +// let y := add(mload(1), add(f_x, _1)) +// } +// function f(a, b, c) -> x +// { +// x := add(a, b) +// x := mul(x, c) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul new file mode 100644 index 00000000..94bbe5dc --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul @@ -0,0 +1,40 @@ +{ + function f(a) -> x { x := add(a, a) } + function g(b, c) -> y { y := mul(mload(c), f(b)) } + let y := g(f(3), 7) +} +// ---- +// fullInliner +// { +// { +// let g_c := 7 +// let f_a_1 := 3 +// let f_x_1 +// { +// f_x_1 := add(f_a_1, f_a_1) +// } +// let g_y +// { +// let g_f_a := f_x_1 +// let g_f_x +// { +// g_f_x := add(g_f_a, g_f_a) +// } +// g_y := mul(mload(g_c), g_f_x) +// } +// let y_1 := g_y +// } +// function f(a) -> x +// { +// x := add(a, a) +// } +// function g(b, c) -> y +// { +// let f_a := b +// let f_x +// { +// f_x := add(f_a, f_a) +// } +// y := mul(mload(c), f_x) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul new file mode 100644 index 00000000..f3c5b0ee --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul @@ -0,0 +1,21 @@ +// The full inliner currently does not work with +// functions returning multiple values. +{ + function f(a) -> x, y { + x := mul(a, a) + y := add(a, x) + } + let a, b := f(mload(0)) +} +// ---- +// fullInliner +// { +// { +// let a_1, b := f(mload(0)) +// } +// function f(a) -> x, y +// { +// x := mul(a, a) +// y := add(a, x) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_return.yul b/test/libyul/yulOptimizerTests/fullInliner/no_return.yul new file mode 100644 index 00000000..53fe3527 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/no_return.yul @@ -0,0 +1,22 @@ +{ + function f(a) { + sstore(a, a) + } + f(mload(0)) +} +// ---- +// fullInliner +// { +// { +// let f_a := mload(0) +// { +// sstore(f_a, f_a) +// } +// { +// } +// } +// function f(a) +// { +// sstore(a, a) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul new file mode 100644 index 00000000..3883c67c --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul @@ -0,0 +1,28 @@ +// This tests that `pop(r)` is removed. +{ + function f(a) -> x { + let r := mul(a, a) + x := add(r, r) + } + pop(add(f(7), 2)) +} +// ---- +// fullInliner +// { +// { +// let _1 := 2 +// let f_a := 7 +// let f_x +// { +// let f_r := mul(f_a, f_a) +// f_x := add(f_r, f_r) +// } +// { +// } +// } +// function f(a) -> x +// { +// let r := mul(a, a) +// x := add(r, r) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/simple.yul b/test/libyul/yulOptimizerTests/fullInliner/simple.yul new file mode 100644 index 00000000..dd1a4e0a --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullInliner/simple.yul @@ -0,0 +1,26 @@ +{ + function f(a) -> x { + let r := mul(a, a) + x := add(r, r) + } + let y := add(f(sload(mload(2))), mload(7)) +} +// ---- +// fullInliner +// { +// { +// let _1 := mload(7) +// let f_a := sload(mload(2)) +// let f_x +// { +// let f_r := mul(f_a, f_a) +// f_x := add(f_r, f_r) +// } +// let y := add(f_x, _1) +// } +// function f(a) -> x +// { +// let r := mul(a, a) +// x := add(r, r) +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul new file mode 100644 index 00000000..f0d49d7b --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/empty_block.yul @@ -0,0 +1,24 @@ +// yul +{ let a:u256 { } function f() -> x:bool { let b:u256 := 4:u256 {} for {} f() {} {} } } +// ---- +// functionGrouper +// { +// { +// let a:u256 +// { +// } +// } +// function f() -> x:bool +// { +// let b:u256 := 4:u256 +// { +// } +// for { +// } +// f() +// { +// } +// { +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul new file mode 100644 index 00000000..c830d5da --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/multi_fun_mixed.yul @@ -0,0 +1,24 @@ +// yul +{ + let a:u256 + function f() { let b:u256 } + let c:u256 function g() { let d:u256 } + let e:u256 +} +// ---- +// functionGrouper +// { +// { +// let a:u256 +// let c:u256 +// let e:u256 +// } +// function f() +// { +// let b:u256 +// } +// function g() +// { +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul new file mode 100644 index 00000000..4a8be86a --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/nested_fun.yul @@ -0,0 +1,27 @@ +// yul +{ + let a:u256 + function f() { + let b:u256 + function g() { + let c:u256 + } + let d:u256 + } +} +// ---- +// functionGrouper +// { +// { +// let a:u256 +// } +// function f() +// { +// let b:u256 +// function g() +// { +// let c:u256 +// } +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul new file mode 100644 index 00000000..149a44eb --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/single_fun.yul @@ -0,0 +1,14 @@ +// yul +{ + let a:u256 function f() {} +} +// ---- +// functionGrouper +// { +// { +// let a:u256 +// } +// function f() +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/smoke.yul b/test/libyul/yulOptimizerTests/functionGrouper/smoke.yul new file mode 100644 index 00000000..650a163e --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/smoke.yul @@ -0,0 +1,7 @@ +{ } +// ---- +// functionGrouper +// { +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul new file mode 100644 index 00000000..6ea9f59d --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionHoister/empty_block.yul @@ -0,0 +1,26 @@ +// yul +{ + let a:u256 + { } + function f() -> x:bool { + let b:u256 := 4:u256 + { } + for {} f() {} {} + } +} +// ---- +// functionHoister +// { +// let a:u256 +// function f() -> x:bool +// { +// let b:u256 := 4:u256 +// for { +// } +// f() +// { +// } +// { +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul new file mode 100644 index 00000000..1e3bc5a1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionHoister/multi_mixed.yul @@ -0,0 +1,23 @@ +// yul +{ + let a:u256 + function f() { let b:u256 } + let c:u256 + function g() { let d:u256 } + let e:u256 +} +// ---- +// functionHoister +// { +// let a:u256 +// let c:u256 +// let e:u256 +// function f() +// { +// let b:u256 +// } +// function g() +// { +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionHoister/nested.yul b/test/libyul/yulOptimizerTests/functionHoister/nested.yul new file mode 100644 index 00000000..20f094f1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionHoister/nested.yul @@ -0,0 +1,23 @@ +// yul +{ + let a:u256 + function f() { + let b:u256 + function g() { let c:u256 } + let d:u256 + } +} +// ---- +// functionHoister +// { +// let a:u256 +// function g() +// { +// let c:u256 +// } +// function f() +// { +// let b:u256 +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionHoister/single.yul b/test/libyul/yulOptimizerTests/functionHoister/single.yul new file mode 100644 index 00000000..ba922612 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionHoister/single.yul @@ -0,0 +1,13 @@ +// yul +{ + let a:u256 + function f() {} +} +// ---- +// functionHoister +// { +// let a:u256 +// function f() +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionHoister/smoke.yul b/test/libyul/yulOptimizerTests/functionHoister/smoke.yul new file mode 100644 index 00000000..35c1ce5f --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionHoister/smoke.yul @@ -0,0 +1,6 @@ +{ +} +// ---- +// functionHoister +// { +// } diff --git a/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul b/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul new file mode 100644 index 00000000..bae6bd48 --- /dev/null +++ b/test/libyul/yulOptimizerTests/mainFunction/empty_block.yul @@ -0,0 +1,33 @@ +// yul +{ + let a:u256 + { } + function f() -> x:bool { + let b:u256 := 4:u256 + {} + for {} f() {} {} + } +} +// ---- +// mainFunction +// { +// function main() +// { +// let a:u256 +// { +// } +// } +// function f() -> x:bool +// { +// let b:u256 := 4:u256 +// { +// } +// for { +// } +// f() +// { +// } +// { +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul b/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul new file mode 100644 index 00000000..dd5caaec --- /dev/null +++ b/test/libyul/yulOptimizerTests/mainFunction/multi_fun_mixed.yul @@ -0,0 +1,26 @@ +// yul +{ + let a:u256 + function f() { let b:u256 } + let c:u256 + function g() { let d:u256 } + let e:u256 +} +// ---- +// mainFunction +// { +// function main() +// { +// let a:u256 +// let c:u256 +// let e:u256 +// } +// function f() +// { +// let b:u256 +// } +// function g() +// { +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul b/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul new file mode 100644 index 00000000..309b97cc --- /dev/null +++ b/test/libyul/yulOptimizerTests/mainFunction/nested_fun.yul @@ -0,0 +1,26 @@ +// yul +{ + let a:u256 + function f() { + let b:u256 + function g() { let c:u256} + let d:u256 + } +} +// ---- +// mainFunction +// { +// function main() +// { +// let a:u256 +// } +// function f() +// { +// let b:u256 +// function g() +// { +// let c:u256 +// } +// let d:u256 +// } +// } diff --git a/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul b/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul new file mode 100644 index 00000000..fa9a8f41 --- /dev/null +++ b/test/libyul/yulOptimizerTests/mainFunction/sigle_fun.yul @@ -0,0 +1,16 @@ +// yul +{ + let a:u256 + function f() {} +} +// ---- +// mainFunction +// { +// function main() +// { +// let a:u256 +// } +// function f() +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/mainFunction/smoke.yul b/test/libyul/yulOptimizerTests/mainFunction/smoke.yul new file mode 100644 index 00000000..7be14746 --- /dev/null +++ b/test/libyul/yulOptimizerTests/mainFunction/smoke.yul @@ -0,0 +1,9 @@ +// yul +{} +// ---- +// mainFunction +// { +// function main() +// { +// } +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul new file mode 100644 index 00000000..dbd1ee63 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul @@ -0,0 +1,21 @@ +{ + let a := 1 + for { pop(a) } a { pop(a) } { + pop(a) + } +} +// ---- +// rematerialiser +// { +// let a := 1 +// for { +// pop(1) +// } +// 1 +// { +// pop(1) +// } +// { +// pop(1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul new file mode 100644 index 00000000..6a52e045 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul @@ -0,0 +1,25 @@ +{ + let a := 1 + for { pop(a) } a { pop(a) } { + a := 7 + let c := a + } + let x := a +} +// ---- +// rematerialiser +// { +// let a := 1 +// for { +// pop(1) +// } +// a +// { +// pop(7) +// } +// { +// a := 7 +// let c := 7 +// } +// let x := a +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul new file mode 100644 index 00000000..fc816419 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul @@ -0,0 +1,23 @@ +{ + let b := 0 + for { let a := 1 pop(a) } a { pop(a) } { + b := 1 pop(a) + } +} +// ---- +// rematerialiser +// { +// let b := 0 +// for { +// let a := 1 +// pop(1) +// } +// 1 +// { +// pop(1) +// } +// { +// b := 1 +// pop(1) +// } +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul new file mode 100644 index 00000000..3d916890 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul @@ -0,0 +1,24 @@ +{ + let b := 0 + for { let a := 1 pop(a) } lt(a, 0) { pop(a) a := add(a, 3) } { + b := 1 pop(a) + } +} +// ---- +// rematerialiser +// { +// let b := 0 +// for { +// let a := 1 +// pop(1) +// } +// lt(a, 0) +// { +// pop(a) +// a := add(a, 3) +// } +// { +// b := 1 +// pop(a) +// } +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul new file mode 100644 index 00000000..c148c2f2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul @@ -0,0 +1,18 @@ +{ + let a := 1 + let b := 2 + if b { pop(b) b := a } + let c := b +} +// ---- +// rematerialiser +// { +// let a := 1 +// let b := 2 +// if 2 +// { +// pop(2) +// b := 1 +// } +// let c := b +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_switch.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_switch.yul new file mode 100644 index 00000000..8f70a79d --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_switch.yul @@ -0,0 +1,24 @@ +{ + let a := 1 + let b := 2 + switch number() + case 1 { b := a } + default { let x := a let y := b b := a } + pop(add(a, b)) +} +// ---- +// rematerialiser +// { +// let a := 1 +// let b := 2 +// switch number() +// case 1 { +// b := 1 +// } +// default { +// let x := 1 +// let y := b +// b := 1 +// } +// pop(add(1, b)) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/do_not_move_out_of_scope.yul b/test/libyul/yulOptimizerTests/rematerialiser/do_not_move_out_of_scope.yul new file mode 100644 index 00000000..891a5043 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/do_not_move_out_of_scope.yul @@ -0,0 +1,19 @@ +// Cannot replace `let b := x` by `let b := a` since a is out of scope. +{ + let x + { + let a := sload(0) + x := a + } + let b := x +} +// ---- +// rematerialiser +// { +// let x +// { +// let a := sload(0) +// x := a +// } +// let b := x +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code1.yul b/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code1.yul new file mode 100644 index 00000000..016fa0d7 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code1.yul @@ -0,0 +1,10 @@ +{ + let x := add(mul(calldataload(2), calldataload(4)), mul(2, calldatasize())) + let b := x +} +// ---- +// rematerialiser +// { +// let x := add(mul(calldataload(2), calldataload(4)), mul(2, calldatasize())) +// let b := x +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code2.yul b/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code2.yul new file mode 100644 index 00000000..d95dc1fc --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code2.yul @@ -0,0 +1,10 @@ +{ + let x := add(mul(calldataload(2), calldataload(4)), calldatasize()) + let b := x +} +// ---- +// rematerialiser +// { +// let x := add(mul(calldataload(2), calldataload(4)), calldatasize()) +// let b := add(mul(calldataload(2), calldataload(4)), calldatasize()) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/expression.yul b/test/libyul/yulOptimizerTests/rematerialiser/expression.yul new file mode 100644 index 00000000..a801677d --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/expression.yul @@ -0,0 +1,10 @@ +{ + let a := add(mul(calldatasize(), 2), number()) + let b := add(a, a) +} +// ---- +// rematerialiser +// { +// let a := add(mul(calldatasize(), 2), number()) +// let b := add(add(mul(calldatasize(), 2), number()), add(mul(calldatasize(), 2), number())) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/non_movable_function.yul b/test/libyul/yulOptimizerTests/rematerialiser/non_movable_function.yul new file mode 100644 index 00000000..9a041dfc --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/non_movable_function.yul @@ -0,0 +1,18 @@ +{ + function f(x) -> y {} + let a := 1 + let b := f(a) + let c := a + mstore(add(a, b), c) +} +// ---- +// rematerialiser +// { +// function f(x) -> y +// { +// } +// let a := 1 +// let b := f(1) +// let c := 1 +// mstore(add(1, b), 1) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/non_movable_instruction.yul b/test/libyul/yulOptimizerTests/rematerialiser/non_movable_instruction.yul new file mode 100644 index 00000000..8767abc9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/non_movable_instruction.yul @@ -0,0 +1,14 @@ +{ + let a := 1 + let b := mload(a) + let c := a + mstore(add(a, b), c) +} +// ---- +// rematerialiser +// { +// let a := 1 +// let b := mload(1) +// let c := 1 +// mstore(add(1, b), 1) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul b/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul new file mode 100644 index 00000000..47124658 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/reassign.yul @@ -0,0 +1,21 @@ +{ + let a := extcodesize(0) + let b := a + let c := b + a := 2 + let d := add(b, c) + pop(a) pop(b) pop(c) pop(d) +} +// ---- +// rematerialiser +// { +// let a := extcodesize(0) +// let b := a +// let c := a +// a := 2 +// let d := add(b, c) +// pop(2) +// pop(b) +// pop(c) +// pop(add(b, c)) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/reassignment.yul b/test/libyul/yulOptimizerTests/rematerialiser/reassignment.yul new file mode 100644 index 00000000..13238780 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/reassignment.yul @@ -0,0 +1,19 @@ +{ + let a := 1 + pop(a) + if a { a := 2 } + let b := mload(a) + pop(b) +} +// ---- +// rematerialiser +// { +// let a := 1 +// pop(1) +// if 1 +// { +// a := 2 +// } +// let b := mload(a) +// pop(b) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/smoke.yul b/test/libyul/yulOptimizerTests/rematerialiser/smoke.yul new file mode 100644 index 00000000..2423db32 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/smoke.yul @@ -0,0 +1,5 @@ +{} +// ---- +// rematerialiser +// { +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/trivial.yul b/test/libyul/yulOptimizerTests/rematerialiser/trivial.yul new file mode 100644 index 00000000..d29ea98a --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/trivial.yul @@ -0,0 +1,12 @@ +{ + let a := 1 + let b := a + mstore(0, b) +} +// ---- +// rematerialiser +// { +// let a := 1 +// let b := 1 +// mstore(0, 1) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul b/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul new file mode 100644 index 00000000..7d35fee0 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/update_asignment_remat.yul @@ -0,0 +1,13 @@ +// We cannot substitute `a` in `let b := a` +{ + let a := extcodesize(0) + a := mul(a, 2) + let b := a +} +// ---- +// rematerialiser +// { +// let a := extcodesize(0) +// a := mul(a, 2) +// let b := a +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/functions.yul b/test/libyul/yulOptimizerTests/unusedPruner/functions.yul new file mode 100644 index 00000000..ec9cdda8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/functions.yul @@ -0,0 +1,8 @@ +{ + function f() { let a := 1 } + function g() { f() } +} +// ---- +// unusedPruner +// { +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul new file mode 100644 index 00000000..4ed6dd2c --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_assignment.yul @@ -0,0 +1,11 @@ +{ + let a := 1 + a := 4 + let b := 1 +} +// ---- +// unusedPruner +// { +// let a := 1 +// a := 4 +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul new file mode 100644 index 00000000..94d101e9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/intermediate_multi_assignment.yul @@ -0,0 +1,16 @@ +{ + let a, b + function f() -> x { } + a := f() + b := 1 +} +// ---- +// unusedPruner +// { +// let a, b +// function f() -> x +// { +// } +// a := f() +// b := 1 +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul new file mode 100644 index 00000000..a14dc28c --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_assign.yul @@ -0,0 +1,16 @@ +{ + let a + let b + function f() -> x, y { } + a, b := f() +} +// ---- +// unusedPruner +// { +// let a +// let b +// function f() -> x, y +// { +// } +// a, b := f() +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul new file mode 100644 index 00000000..fe94edb8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_assignments.yul @@ -0,0 +1,12 @@ +{ + let x, y + x := 1 + y := 2 +} +// ---- +// unusedPruner +// { +// let x, y +// x := 1 +// y := 2 +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul new file mode 100644 index 00000000..3cf35007 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_declarations.yul @@ -0,0 +1,7 @@ +{ + let x, y +} +// ---- +// unusedPruner +// { +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul new file mode 100644 index 00000000..adabac87 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_declare.yul @@ -0,0 +1,12 @@ +{ + function f() -> x, y { } + let a, b := f() +} +// ---- +// unusedPruner +// { +// function f() -> x, y +// { +// } +// let a, b := f() +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul b/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul new file mode 100644 index 00000000..5db0ade9 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/multi_partial_assignments.yul @@ -0,0 +1,10 @@ +{ + let x, y + x := 1 +} +// ---- +// unusedPruner +// { +// let x, y +// x := 1 +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul b/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul new file mode 100644 index 00000000..ca2ed942 --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/smoke.yul @@ -0,0 +1,5 @@ +{ } +// ---- +// unusedPruner +// { +// } diff --git a/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul b/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul new file mode 100644 index 00000000..9b4cf9fd --- /dev/null +++ b/test/libyul/yulOptimizerTests/unusedPruner/trivial.yul @@ -0,0 +1,10 @@ +{ + let a := 1 + let b := 1 + mstore(0, 1) +} +// ---- +// unusedPruner +// { +// mstore(0, 1) +// } -- cgit From 1304361b9c48438d5c55903492b5f11c3dac73e5 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 15 Oct 2018 11:58:51 +0200 Subject: Renaming namespace dev::julia to dev::yul. --- test/libyul/Common.cpp | 10 +++++----- test/libyul/Common.h | 2 +- test/libyul/Inliner.cpp | 4 ++-- test/libyul/YulOptimizerTest.cpp | 4 ++-- test/libyul/YulOptimizerTest.h | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) (limited to 'test/libyul') diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index f23136e6..4c50180a 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -37,10 +37,10 @@ #include using namespace std; -using namespace dev::julia; +using namespace dev::yul; using namespace dev::solidity; -void dev::julia::test::printErrors(ErrorList const& _errors, Scanner const& _scanner) +void dev::yul::test::printErrors(ErrorList const& _errors, Scanner const& _scanner) { SourceReferenceFormatter formatter(cout, [&](std::string const&) -> Scanner const& { return _scanner; }); @@ -52,7 +52,7 @@ void dev::julia::test::printErrors(ErrorList const& _errors, Scanner const& _sca } -pair, shared_ptr> dev::julia::test::parse(string const& _source, bool _yul) +pair, shared_ptr> dev::yul::test::parse(string const& _source, bool _yul) { auto flavour = _yul ? assembly::AsmFlavour::Yul : assembly::AsmFlavour::Strict; ErrorList errors; @@ -83,13 +83,13 @@ pair, shared_ptr> dev::julia::test: return {}; } -assembly::Block dev::julia::test::disambiguate(string const& _source, bool _yul) +assembly::Block dev::yul::test::disambiguate(string const& _source, bool _yul) { auto result = parse(_source, _yul); return boost::get(Disambiguator(*result.second)(*result.first)); } -string dev::julia::test::format(string const& _source, bool _yul) +string dev::yul::test::format(string const& _source, bool _yul) { return assembly::AsmPrinter(_yul)(*parse(_source, _yul).first); } diff --git a/test/libyul/Common.h b/test/libyul/Common.h index b9c3d2fb..ee191494 100644 --- a/test/libyul/Common.h +++ b/test/libyul/Common.h @@ -39,7 +39,7 @@ namespace assembly struct AsmAnalysisInfo; } } -namespace julia +namespace yul { namespace test { diff --git a/test/libyul/Inliner.cpp b/test/libyul/Inliner.cpp index 471b2e2f..44c6411a 100644 --- a/test/libyul/Inliner.cpp +++ b/test/libyul/Inliner.cpp @@ -36,8 +36,8 @@ using namespace std; using namespace dev; -using namespace dev::julia; -using namespace dev::julia::test; +using namespace dev::yul; +using namespace dev::yul::test; using namespace dev::solidity; namespace diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 62a4aa10..8b37830f 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -48,8 +48,8 @@ #include using namespace dev; -using namespace dev::julia; -using namespace dev::julia::test; +using namespace dev::yul; +using namespace dev::yul::test; using namespace dev::solidity; using namespace dev::solidity::test; using namespace std; diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index 8f9a81f7..7db17ceb 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -33,7 +33,7 @@ struct AsmAnalysisInfo; struct Block; } } -namespace julia +namespace yul { namespace test { -- cgit