diff options
author | chriseth <chris@ethereum.org> | 2019-01-22 20:49:41 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-22 20:49:41 +0800 |
commit | 10d17f245839f208ec5085309022a32cd2502f55 (patch) | |
tree | b2c9f68980d0d418cd6f511e9f3f3f71369abe25 /test/libyul | |
parent | 1df8f40cd2fd7b47698d847907b8ca7b47eb488d (diff) | |
parent | 0ecafe032a84cb6960545dd7f18733430c1f782d (diff) | |
download | dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.tar.gz dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.tar.zst dexon-solidity-10d17f245839f208ec5085309022a32cd2502f55.zip |
Merge pull request #5836 from ethereum/develop
Merge develop into release for 0.5.3.
Diffstat (limited to 'test/libyul')
51 files changed, 2747 insertions, 264 deletions
diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index a337fa8d..ea4d0208 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -41,6 +41,14 @@ using namespace langutil; using namespace yul; using namespace dev::solidity; +namespace +{ +shared_ptr<Dialect> defaultDialect(bool _yul) +{ + return _yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); +} +} + void yul::test::printErrors(ErrorList const& _errors) { SourceReferenceFormatter formatter(cout); @@ -55,7 +63,7 @@ void yul::test::printErrors(ErrorList const& _errors) pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(string const& _source, bool _yul) { - shared_ptr<Dialect> dialect = _yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); + shared_ptr<Dialect> dialect = defaultDialect(_yul); ErrorList errors; ErrorReporter errorReporter(errors); auto scanner = make_shared<Scanner>(CharStream(_source, "")); @@ -87,7 +95,7 @@ pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(strin yul::Block yul::test::disambiguate(string const& _source, bool _yul) { auto result = parse(_source, _yul); - return boost::get<Block>(Disambiguator(*result.second, {})(*result.first)); + return boost::get<Block>(Disambiguator(*defaultDialect(_yul), *result.second, {})(*result.first)); } string yul::test::format(string const& _source, bool _yul) diff --git a/test/libyul/Metrics.cpp b/test/libyul/Metrics.cpp new file mode 100644 index 00000000..185a3755 --- /dev/null +++ b/test/libyul/Metrics.cpp @@ -0,0 +1,116 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ +/** + * Unit tests for the code metrics. + */ + +#include <test/Options.h> + +#include <test/libyul/Common.h> + +#include <libyul/optimiser/Metrics.h> +#include <libyul/AsmData.h> + + +using namespace std; +using namespace langutil; + +namespace yul +{ +namespace test +{ + +namespace +{ + +size_t codeSize(string const& _source) +{ + shared_ptr<Block> ast = parse(_source, false).first; + BOOST_REQUIRE(ast); + return CodeSize::codeSize(*ast); +} + +} + +BOOST_AUTO_TEST_SUITE(YulCodeSize) + +BOOST_AUTO_TEST_CASE(empty_code) +{ + BOOST_CHECK_EQUAL(codeSize("{}"), 0); +} + +BOOST_AUTO_TEST_CASE(nested_blocks) +{ + BOOST_CHECK_EQUAL(codeSize("{ {} {} {{ }} }"), 0); +} + +BOOST_AUTO_TEST_CASE(instruction) +{ + BOOST_CHECK_EQUAL(codeSize("{ pop(calldatasize()) }"), 2); +} + +BOOST_AUTO_TEST_CASE(variables_are_free) +{ + BOOST_CHECK_EQUAL(codeSize("{ let x let y let a, b, c }"), 0); +} + +BOOST_AUTO_TEST_CASE(constants_cost_one) +{ + BOOST_CHECK_EQUAL(codeSize("{ let x := 3 }"), 1); +} + +BOOST_AUTO_TEST_CASE(functions_are_skipped) +{ + BOOST_CHECK_EQUAL(codeSize("{ function f(x) -> r { r := mload(x) } }"), 0); +} + +BOOST_AUTO_TEST_CASE(function_with_arguments) +{ + BOOST_CHECK_EQUAL(codeSize("{ function f(x) { sstore(x, 2) } f(2) }"), 2); +} + +BOOST_AUTO_TEST_CASE(function_with_variables_as_arguments) +{ + BOOST_CHECK_EQUAL(codeSize("{ function f(x) { sstore(x, 2) } let y f(y) }"), 1); +} + +BOOST_AUTO_TEST_CASE(function_with_variables_and_constants_as_arguments) +{ + BOOST_CHECK_EQUAL(codeSize( + "{ function f(x, r) -> z { sstore(x, r) z := r } let y let t := f(y, 2) }" + ), 2); +} + +BOOST_AUTO_TEST_CASE(assignment) +{ + BOOST_CHECK_EQUAL(codeSize("{ let a a := 3 }"), 1); +} + +BOOST_AUTO_TEST_CASE(assignments_between_vars_are_free) +{ + BOOST_CHECK_EQUAL(codeSize("{ let a let b := a a := b }"), 0); +} + +BOOST_AUTO_TEST_CASE(assignment_complex) +{ + BOOST_CHECK_EQUAL(codeSize("{ let a let x := mload(a) a := sload(x) }"), 2); +} + +BOOST_AUTO_TEST_SUITE_END() + +} +} diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index bb88e4da..13a95788 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -250,6 +250,36 @@ BOOST_AUTO_TEST_CASE(to_string) BOOST_CHECK_EQUAL(asmStack.print(), expectation); } +BOOST_AUTO_TEST_CASE(arg_to_dataoffset_must_be_literal) +{ + string code = R"( + object "outer" { + code { let x := "outer" let y := dataoffset(x) } + } + )"; + CHECK_ERROR(code, TypeError, "Function expects direct literals as arguments."); +} + +BOOST_AUTO_TEST_CASE(arg_to_datasize_must_be_literal) +{ + string code = R"( + object "outer" { + code { let x := "outer" let y := datasize(x) } + } + )"; + CHECK_ERROR(code, TypeError, "Function expects direct literals as arguments."); +} + +BOOST_AUTO_TEST_CASE(args_to_datacopy_are_arbitrary) +{ + string code = R"( + object "outer" { + code { let x := 0 let y := 2 let s := 3 datacopy(x, y, s) } + } + )"; + BOOST_CHECK(successParse(code)); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index df7e32a1..84f5c14b 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -304,6 +304,19 @@ BOOST_AUTO_TEST_CASE(if_statement_invalid) BOOST_CHECK(successParse("{ if 42:u256 { } }")); } +BOOST_AUTO_TEST_CASE(switch_case_types) +{ + CHECK_ERROR("{ switch 0:u256 case 0:u256 {} case 1:u32 {} }", TypeError, "Switch cases have non-matching types."); + // The following should be an error in the future, but this is not yet detected. + BOOST_CHECK(successParse("{ switch 0:u256 case 0:u32 {} case 1:u32 {} }")); +} + +BOOST_AUTO_TEST_CASE(switch_duplicate_case) +{ + CHECK_ERROR("{ switch 0:u256 case 0:u256 {} case 0x0:u256 {} }", DeclarationError, "Duplicate case defined."); + BOOST_CHECK(successParse("{ switch 0:u256 case 42:u256 {} case 0x42:u256 {} }")); +} + BOOST_AUTO_TEST_CASE(builtins_parser) { struct SimpleDialect: public Dialect @@ -331,7 +344,7 @@ BOOST_AUTO_TEST_CASE(builtins_analysis) { return _name == "builtin"_yulstring ? &f : nullptr; } - BuiltinFunction f{"builtin"_yulstring, vector<Type>(2), vector<Type>(3), false}; + BuiltinFunction f{"builtin"_yulstring, vector<Type>(2), vector<Type>(3), false, false}; }; shared_ptr<Dialect> dialect = make_shared<SimpleDialect>(); diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp index 9643a1e9..306721a0 100644 --- a/test/libyul/YulOptimizerTest.cpp +++ b/test/libyul/YulOptimizerTest.cpp @@ -26,6 +26,7 @@ #include <libyul/optimiser/Disambiguator.h> #include <libyul/optimiser/CommonSubexpressionEliminator.h> #include <libyul/optimiser/NameCollector.h> +#include <libyul/optimiser/EquivalentFunctionCombiner.h> #include <libyul/optimiser/ExpressionSplitter.h> #include <libyul/optimiser/FunctionGrouper.h> #include <libyul/optimiser/FunctionHoister.h> @@ -37,6 +38,7 @@ #include <libyul/optimiser/ExpressionSimplifier.h> #include <libyul/optimiser/UnusedPruner.h> #include <libyul/optimiser/ExpressionJoiner.h> +#include <libyul/optimiser/SSAReverser.h> #include <libyul/optimiser/SSATransform.h> #include <libyul/optimiser/RedundantAssignEliminator.h> #include <libyul/optimiser/StructuralSimplifier.h> @@ -117,12 +119,12 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con else if (m_optimizerStep == "commonSubexpressionEliminator") { disambiguate(); - (CommonSubexpressionEliminator{})(*m_ast); + (CommonSubexpressionEliminator{*m_dialect})(*m_ast); } else if (m_optimizerStep == "expressionSplitter") { - NameDispenser nameDispenser(*m_ast); - ExpressionSplitter{nameDispenser}(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; + ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); } else if (m_optimizerStep == "expressionJoiner") { @@ -132,8 +134,8 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con else if (m_optimizerStep == "splitJoin") { disambiguate(); - NameDispenser nameDispenser(*m_ast); - ExpressionSplitter{nameDispenser}(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; + ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); ExpressionJoiner::run(*m_ast); ExpressionJoiner::run(*m_ast); } @@ -150,15 +152,15 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con else if (m_optimizerStep == "expressionInliner") { disambiguate(); - ExpressionInliner(*m_ast).run(); + ExpressionInliner(*m_dialect, *m_ast).run(); } else if (m_optimizerStep == "fullInliner") { disambiguate(); (FunctionHoister{})(*m_ast); (FunctionGrouper{})(*m_ast); - NameDispenser nameDispenser(*m_ast); - ExpressionSplitter{nameDispenser}(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; + ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); FullInliner(*m_ast, nameDispenser).run(); ExpressionJoiner::run(*m_ast); } @@ -171,54 +173,76 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con else if (m_optimizerStep == "rematerialiser") { disambiguate(); - (Rematerialiser{})(*m_ast); + Rematerialiser::run(*m_dialect, *m_ast); } else if (m_optimizerStep == "expressionSimplifier") { disambiguate(); - ExpressionSimplifier::run(*m_ast); + ExpressionSimplifier::run(*m_dialect, *m_ast); } else if (m_optimizerStep == "fullSimplify") { disambiguate(); - NameDispenser nameDispenser(*m_ast); - ExpressionSplitter{nameDispenser}(*m_ast); - CommonSubexpressionEliminator{}(*m_ast); - ExpressionSimplifier::run(*m_ast); - UnusedPruner::runUntilStabilised(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; + ExpressionSplitter{*m_dialect, nameDispenser}(*m_ast); + CommonSubexpressionEliminator{*m_dialect}(*m_ast); + ExpressionSimplifier::run(*m_dialect, *m_ast); + UnusedPruner::runUntilStabilised(*m_dialect, *m_ast); ExpressionJoiner::run(*m_ast); ExpressionJoiner::run(*m_ast); } else if (m_optimizerStep == "unusedPruner") { disambiguate(); - UnusedPruner::runUntilStabilised(*m_ast); + UnusedPruner::runUntilStabilised(*m_dialect, *m_ast); } else if (m_optimizerStep == "ssaTransform") { disambiguate(); - NameDispenser nameDispenser(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; SSATransform::run(*m_ast, nameDispenser); } else if (m_optimizerStep == "redundantAssignEliminator") { disambiguate(); - RedundantAssignEliminator::run(*m_ast); + RedundantAssignEliminator::run(*m_dialect, *m_ast); } else if (m_optimizerStep == "ssaPlusCleanup") { disambiguate(); - NameDispenser nameDispenser(*m_ast); + NameDispenser nameDispenser{*m_dialect, *m_ast}; SSATransform::run(*m_ast, nameDispenser); - RedundantAssignEliminator::run(*m_ast); + RedundantAssignEliminator::run(*m_dialect, *m_ast); } else if (m_optimizerStep == "structuralSimplifier") { disambiguate(); - StructuralSimplifier{}(*m_ast); + StructuralSimplifier{*m_dialect}(*m_ast); + } + else if (m_optimizerStep == "equivalentFunctionCombiner") + { + disambiguate(); + EquivalentFunctionCombiner::run(*m_ast); + } + else if (m_optimizerStep == "ssaReverser") + { + disambiguate(); + SSAReverser::run(*m_ast); + } + else if (m_optimizerStep == "ssaAndBack") + { + disambiguate(); + // apply SSA + NameDispenser nameDispenser{*m_dialect, *m_ast}; + SSATransform::run(*m_ast, nameDispenser); + RedundantAssignEliminator::run(*m_dialect, *m_ast); + // reverse SSA + SSAReverser::run(*m_ast); + CommonSubexpressionEliminator{*m_dialect}(*m_ast); + UnusedPruner::runUntilStabilised(*m_dialect, *m_ast); } else if (m_optimizerStep == "fullSuite") - OptimiserSuite::run(*m_ast, *m_analysisInfo); + OptimiserSuite::run(*m_dialect, *m_ast, *m_analysisInfo); else { FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Invalid optimizer step: " << m_optimizerStep << endl; @@ -260,11 +284,11 @@ void YulOptimizerTest::printIndented(ostream& _stream, string const& _output, st bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool const _formatted) { - shared_ptr<yul::Dialect> dialect = m_yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVM(); + m_dialect = m_yul ? yul::Dialect::yul() : yul::EVMDialect::strictAssemblyForEVMObjects(); ErrorList errors; ErrorReporter errorReporter(errors); shared_ptr<Scanner> scanner = make_shared<Scanner>(CharStream(m_source, "")); - m_ast = yul::Parser(errorReporter, dialect).parse(scanner, false); + m_ast = yul::Parser(errorReporter, m_dialect).parse(scanner, false); if (!m_ast || !errorReporter.errors().empty()) { FormattedScope(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl; @@ -277,7 +301,7 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c errorReporter, dev::test::Options::get().evmVersion(), boost::none, - dialect + m_dialect ); if (!analyzer.analyze(*m_ast) || !errorReporter.errors().empty()) { @@ -290,7 +314,7 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c void YulOptimizerTest::disambiguate() { - *m_ast = boost::get<Block>(Disambiguator(*m_analysisInfo)(*m_ast)); + *m_ast = boost::get<Block>(Disambiguator(*m_dialect, *m_analysisInfo)(*m_ast)); m_analysisInfo.reset(); } diff --git a/test/libyul/YulOptimizerTest.h b/test/libyul/YulOptimizerTest.h index 5648e995..5009b82c 100644 --- a/test/libyul/YulOptimizerTest.h +++ b/test/libyul/YulOptimizerTest.h @@ -30,6 +30,7 @@ namespace yul { struct AsmAnalysisInfo; struct Block; +struct Dialect; } namespace yul @@ -64,6 +65,7 @@ private: std::string m_optimizerStep; std::string m_expectation; + std::shared_ptr<Dialect> m_dialect; std::shared_ptr<Block> m_ast; std::shared_ptr<AsmAnalysisInfo> m_analysisInfo; std::string m_obtainedResult; diff --git a/test/libyul/objectCompiler/nested_optimizer.yul b/test/libyul/objectCompiler/nested_optimizer.yul index 7739ce61..2775c346 100644 --- a/test/libyul/objectCompiler/nested_optimizer.yul +++ b/test/libyul/objectCompiler/nested_optimizer.yul @@ -19,31 +19,21 @@ object "a" { // Assembly: // /* "source":60:61 */ // 0x00 -// /* "source":137:138 */ -// dup1 -// /* "source":60:61 */ -// dup2 +// 0x00 // /* "source":47:62 */ // calldataload // /* "source":119:139 */ // sstore -// /* "source":32:143 */ -// pop // stop // // sub_0: assembly { // /* "source":200:201 */ // 0x00 -// /* "source":283:284 */ -// dup1 -// /* "source":200:201 */ -// dup2 +// 0x00 // /* "source":187:202 */ // calldataload // /* "source":265:285 */ // sstore -// /* "source":170:291 */ -// pop // } -// Bytecode: 60008081355550fe -// Opcodes: PUSH1 0x0 DUP1 DUP2 CALLDATALOAD SSTORE POP INVALID +// Bytecode: 600060003555fe +// Opcodes: PUSH1 0x0 PUSH1 0x0 CALLDATALOAD SSTORE INVALID diff --git a/test/libyul/objectCompiler/simple_optimizer.yul b/test/libyul/objectCompiler/simple_optimizer.yul index 43b33553..c757dee7 100644 --- a/test/libyul/objectCompiler/simple_optimizer.yul +++ b/test/libyul/objectCompiler/simple_optimizer.yul @@ -9,15 +9,10 @@ // Assembly: // /* "source":38:39 */ // 0x00 -// /* "source":109:110 */ -// dup1 -// /* "source":38:39 */ -// dup2 +// 0x00 // /* "source":25:40 */ // calldataload // /* "source":91:111 */ // sstore -// /* "source":12:113 */ -// pop -// Bytecode: 60008081355550 -// Opcodes: PUSH1 0x0 DUP1 DUP2 CALLDATALOAD SSTORE POP +// Bytecode: 600060003555 +// Opcodes: PUSH1 0x0 PUSH1 0x0 CALLDATALOAD SSTORE diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul new file mode 100644 index 00000000..5cfa3e6e --- /dev/null +++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/object_access.yul @@ -0,0 +1,23 @@ +{ + // Arguments to ``datasize`` and ``dataoffset`` need to be + // literals. We cannot simplify their arguments, but we can + // simplify them as a full expression. + // ``datacopy`` does not have this restriction. + let r := "abc" + let a := datasize("abc") + let x := dataoffset("abc") + // should be replaced by a + let y := datasize("abc") + datacopy("abc", x, y) + mstore(a, x) +} +// ---- +// commonSubexpressionEliminator +// { +// let r := "abc" +// let a := datasize("abc") +// let x := dataoffset("abc") +// let y := a +// datacopy(r, x, a) +// mstore(a, x) +// } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/multiple_complex.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/multiple_complex.yul new file mode 100644 index 00000000..380f9f03 --- /dev/null +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/multiple_complex.yul @@ -0,0 +1,114 @@ +{ + pop(f(1,2,3)) + pop(g(4,5,6)) + pop(h(7,8,9)) + function f(f1, f2, f3) -> rf + { + switch f1 + case 0 { + if f2 + { + rf := f3 + } + if not(f2) + { + rf := f1 + } + } + default { + rf := 3 + } + } + function g(g1, g2, g3) -> rg + { + switch g1 + case 0 { + if g2 + { + rg := g3 + } + if not(g2) + { + rg := g1 + } + } + default { + rg := 3 + } + } + function h(h1, h2, h3) -> rh + { + switch h1 + case 1 { + if h2 + { + rh := h3 + } + if not(h2) + { + rh := h1 + } + } + default { + rh := 3 + } + } +} +// ---- +// equivalentFunctionCombiner +// { +// pop(f(1, 2, 3)) +// pop(f(4, 5, 6)) +// pop(h(7, 8, 9)) +// function f(f1, f2, f3) -> rf +// { +// switch f1 +// case 0 { +// if f2 +// { +// rf := f3 +// } +// if not(f2) +// { +// rf := f1 +// } +// } +// default { +// rf := 3 +// } +// } +// function g(g1, g2, g3) -> rg +// { +// switch g1 +// case 0 { +// if g2 +// { +// rg := g3 +// } +// if not(g2) +// { +// rg := g1 +// } +// } +// default { +// rg := 3 +// } +// } +// function h(h1, h2, h3) -> rh +// { +// switch h1 +// case 1 { +// if h2 +// { +// rh := h3 +// } +// if not(h2) +// { +// rh := h1 +// } +// } +// default { +// rh := 3 +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple.yul new file mode 100644 index 00000000..2d5b3ef8 --- /dev/null +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple.yul @@ -0,0 +1,20 @@ +{ + f() + g() + function f() { mstore(1, mload(0)) } + function g() { mstore(1, mload(0)) } +} +// ---- +// equivalentFunctionCombiner +// { +// f() +// f() +// function f() +// { +// mstore(1, mload(0)) +// } +// function g() +// { +// mstore(1, mload(0)) +// } +// } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple_different_vars.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple_different_vars.yul new file mode 100644 index 00000000..d38a3d2e --- /dev/null +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/simple_different_vars.yul @@ -0,0 +1,22 @@ +{ + pop(f()) + pop(g()) + function f() -> b { let a := mload(0) b := a } + function g() -> a { let b := mload(0) a := b } +} +// ---- +// equivalentFunctionCombiner +// { +// pop(f()) +// pop(f()) +// function f() -> b +// { +// let a := mload(0) +// b := a +// } +// function g() -> a_1 +// { +// let b_2 := mload(0) +// a_1 := b_2 +// } +// } diff --git a/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/switch_case_order.yul b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/switch_case_order.yul new file mode 100644 index 00000000..4f3cad36 --- /dev/null +++ b/test/libyul/yulOptimizerTests/equivalentFunctionCombiner/switch_case_order.yul @@ -0,0 +1,32 @@ +{ + f(0) + g(1) + function f(x) { switch x case 0 { mstore(0, 42) } case 1 { mstore(1, 42) } } + function g(x) { switch x case 1 { mstore(1, 42) } case 0 { mstore(0, 42) } } +} +// ---- +// equivalentFunctionCombiner +// { +// f(0) +// f(1) +// function f(x) +// { +// switch x +// case 0 { +// mstore(0, 42) +// } +// case 1 { +// mstore(1, 42) +// } +// } +// function g(x_1) +// { +// switch x_1 +// case 1 { +// mstore(1, 42) +// } +// case 0 { +// mstore(0, 42) +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul b/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul new file mode 100644 index 00000000..2689ab6f --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSplitter/object_access.yul @@ -0,0 +1,21 @@ +{ + // We should never split arguments to ``dataoffset`` + // or ``datasize`` because they need to be literals + let x := dataoffset("abc") + let y := datasize("abc") + // datacopy is fine, though + datacopy(mload(0), mload(1), mload(2)) +} +// ---- +// expressionSplitter +// { +// let x := dataoffset("abc") +// let y := datasize("abc") +// let _1 := 2 +// let _2 := mload(_1) +// let _3 := 1 +// let _4 := mload(_3) +// let _5 := 0 +// let _6 := mload(_5) +// datacopy(_6, _4, _2) +// } diff --git a/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul index c00b1163..3a7ee2f3 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul @@ -21,22 +21,28 @@ // { // let a_1 := mload(2) // let a2 := 2 -// let r := f(a_1) -// let f_a := a2 +// let f_a := a_1 // let f_b := 0 // let f_x := mload(f_a) // f_b := sload(f_x) // let f_y := add(f_a, f_x) // sstore(f_y, 10) -// let t := f_b -// let a3 -// let f_a_3 := a3 +// let r := f_b +// let f_a_3 := a2 // let f_b_4 := 0 // let f_x_5 := mload(f_a_3) // f_b_4 := sload(f_x_5) // let f_y_6 := add(f_a_3, f_x_5) // sstore(f_y_6, 10) -// let s := f_b_4 +// let t := f_b_4 +// let a3 +// let f_a_8 := a3 +// let f_b_9 := 0 +// let f_x_10 := mload(f_a_8) +// f_b_9 := sload(f_x_10) +// let f_y_11 := add(f_a_8, f_x_10) +// sstore(f_y_11, 10) +// let s := f_b_9 // } // function f(a) -> b // { diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul index 6e4acb97..dbbc5422 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul @@ -26,13 +26,11 @@ // fullInliner // { // { -// { -// let f_x := 100 -// mstore(0, f_x) -// mstore(7, h()) -// g(10) -// mstore(1, f_x) -// } +// let f_x := 100 +// mstore(0, f_x) +// mstore(7, h()) +// g(10) +// mstore(1, f_x) // } // function f(x) // { diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul index f59e2c11..58922954 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_function.yul @@ -39,6 +39,24 @@ // let f_a_35 := f_b_33 // let f_b_36 := 0 // f_b_36 := sload(mload(f_a_35)) -// x_1 := f(f(f(f(f(f(f(f(f(f(f(f(f_b_36)))))))))))) +// let f_a_38 := f_b_36 +// let f_b_39 := 0 +// f_b_39 := sload(mload(f_a_38)) +// let f_a_41 := f_b_39 +// let f_b_42 := 0 +// f_b_42 := sload(mload(f_a_41)) +// let f_a_44 := f_b_42 +// let f_b_45 := 0 +// f_b_45 := sload(mload(f_a_44)) +// let f_a_47 := f_b_45 +// let f_b_48 := 0 +// f_b_48 := sload(mload(f_a_47)) +// let f_a_50 := f_b_48 +// let f_b_51 := 0 +// f_b_51 := sload(mload(f_a_50)) +// let f_a_53 := f_b_51 +// let f_b_54 := 0 +// f_b_54 := sload(mload(f_a_53)) +// x_1 := f(f(f(f(f(f(f_b_54)))))) // } // } diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul index f20b7221..3dc27b2d 100644 --- a/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul +++ b/test/libyul/yulOptimizerTests/fullInliner/no_inline_into_big_global_context.yul @@ -32,7 +32,25 @@ // let f_a_35 := f_b_33 // let f_b_36 := 0 // f_b_36 := sload(mload(f_a_35)) -// let x_1 := f(f(f(f(f(f(f(f(f(f(f(f(f_b_36)))))))))))) +// let f_a_38 := f_b_36 +// let f_b_39 := 0 +// f_b_39 := sload(mload(f_a_38)) +// let f_a_41 := f_b_39 +// let f_b_42 := 0 +// f_b_42 := sload(mload(f_a_41)) +// let f_a_44 := f_b_42 +// let f_b_45 := 0 +// f_b_45 := sload(mload(f_a_44)) +// let f_a_47 := f_b_45 +// let f_b_48 := 0 +// f_b_48 := sload(mload(f_a_47)) +// let f_a_50 := f_b_48 +// let f_b_51 := 0 +// f_b_51 := sload(mload(f_a_50)) +// let f_a_53 := f_b_51 +// let f_b_54 := 0 +// f_b_54 := sload(mload(f_a_53)) +// let x_1 := f(f(f(f(f(f(f_b_54)))))) // } // function f(a) -> b // { diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi2.yul b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul new file mode 100644 index 00000000..41a52c67 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/abi2.yul @@ -0,0 +1,1144 @@ +{ + // This ignores many of the encoding / decoding functions. Over time, + // we should add them all here. + + let a, b := abi_decode_tuple_t_contract$_Module_$1038t_contract$_Module_$1038(mload(0), mload(1)) + sstore(0, a) + let x0, x1, x2, x3, x4 := abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(mload(7), mload(8)) + sstore(x1, x0) + sstore(x3, x2) + sstore(1, x4) + let r := abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_( + mload(30), + mload(31), + mload(32), + mload(33), + mload(34), + mload(35), + mload(36), + mload(37), + mload(38), + mload(39), + mload(40), + mload(41) + ) + + function abi_decode_t_address(offset, end) -> value + { + value := cleanup_revert_t_address(calldataload(offset)) + } + function abi_decode_t_address_payable(offset_1, end_2) -> value_3 + { + value_3 := cleanup_revert_t_address_payable(calldataload(offset_1)) + } + function abi_decode_t_array$_t_address_$dyn_calldata_ptr(offset_4, end_5) -> arrayPos, length + { + if iszero(slt(add(offset_4, 0x1f), end_5)) + { + revert(0, 0) + } + length := calldataload(offset_4) + if gt(length, 0xffffffffffffffff) + { + revert(0, 0) + } + arrayPos := add(offset_4, 0x20) + if gt(add(arrayPos, mul(length, 0x20)), end_5) + { + revert(0, 0) + } + } + function abi_decode_t_bool_fromMemory(offset_6, end_7) -> value_8 + { + value_8 := cleanup_revert_t_bool(mload(offset_6)) + } + function abi_decode_t_bytes32(offset_9, end_10) -> value_11 + { + value_11 := cleanup_revert_t_bytes32(calldataload(offset_9)) + } + function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 + { + if iszero(slt(add(offset_12, 0x1f), end_13)) + { + revert(0, 0) + } + length_15 := calldataload(offset_12) + if gt(length_15, 0xffffffffffffffff) + { + revert(0, 0) + } + arrayPos_14 := add(offset_12, 0x20) + if gt(add(arrayPos_14, mul(length_15, 0x1)), end_13) + { + revert(0, 0) + } + } + function abi_decode_t_bytes_memory_ptr(offset_16, end_17) -> array + { + if iszero(slt(add(offset_16, 0x1f), end_17)) + { + revert(0, 0) + } + let length_18 := calldataload(offset_16) + array := allocateMemory(array_allocation_size_t_bytes_memory_ptr(length_18)) + mstore(array, length_18) + let src := add(offset_16, 0x20) + let dst := add(array, 0x20) + if gt(add(src, length_18), end_17) + { + revert(0, 0) + } + copy_calldata_to_memory(src, dst, length_18) + } + function abi_decode_t_contract$_Module_$1038(offset_19, end_20) -> value_21 + { + value_21 := cleanup_revert_t_contract$_Module_$1038(calldataload(offset_19)) + } + function abi_decode_t_enum$_Operation_$1949(offset_22, end_23) -> value_24 + { + value_24 := cleanup_revert_t_enum$_Operation_$1949(calldataload(offset_22)) + } + function abi_decode_t_uint256(offset_25, end_26) -> value_27 + { + value_27 := cleanup_revert_t_uint256(calldataload(offset_25)) + } + function abi_decode_tuple_t_address(headStart, dataEnd) -> value0 + { + if slt(sub(dataEnd, headStart), 32) + { + revert(0, 0) + } + { + let offset_28 := 0 + value0 := abi_decode_t_address(add(headStart, offset_28), dataEnd) + } + } + function abi_decode_tuple_t_addresst_addresst_address(headStart_29, dataEnd_30) -> value0_31, value1, value2 + { + if slt(sub(dataEnd_30, headStart_29), 96) + { + revert(0, 0) + } + { + let offset_32 := 0 + value0_31 := abi_decode_t_address(add(headStart_29, offset_32), dataEnd_30) + } + { + let offset_33 := 32 + value1 := abi_decode_t_address(add(headStart_29, offset_33), dataEnd_30) + } + { + let offset_34 := 64 + value2 := abi_decode_t_address(add(headStart_29, offset_34), dataEnd_30) + } + } + function abi_decode_tuple_t_addresst_addresst_uint256(headStart_35, dataEnd_36) -> value0_37, value1_38, value2_39 + { + if slt(sub(dataEnd_36, headStart_35), 96) + { + revert(0, 0) + } + { + let offset_40 := 0 + value0_37 := abi_decode_t_address(add(headStart_35, offset_40), dataEnd_36) + } + { + let offset_41 := 32 + value1_38 := abi_decode_t_address(add(headStart_35, offset_41), dataEnd_36) + } + { + let offset_42 := 64 + value2_39 := abi_decode_t_uint256(add(headStart_35, offset_42), dataEnd_36) + } + } + function abi_decode_tuple_t_addresst_bytes32(headStart_43, dataEnd_44) -> value0_45, value1_46 + { + if slt(sub(dataEnd_44, headStart_43), 64) + { + revert(0, 0) + } + { + let offset_47 := 0 + value0_45 := abi_decode_t_address(add(headStart_43, offset_47), dataEnd_44) + } + { + let offset_48 := 32 + value1_46 := abi_decode_t_bytes32(add(headStart_43, offset_48), dataEnd_44) + } + } + function abi_decode_tuple_t_addresst_uint256(headStart_49, dataEnd_50) -> value0_51, value1_52 + { + if slt(sub(dataEnd_50, headStart_49), 64) + { + revert(0, 0) + } + { + let offset_53 := 0 + value0_51 := abi_decode_t_address(add(headStart_49, offset_53), dataEnd_50) + } + { + let offset_54 := 32 + value1_52 := abi_decode_t_uint256(add(headStart_49, offset_54), dataEnd_50) + } + } + function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(headStart_55, dataEnd_56) -> value0_57, value1_58, value2_59, value3, value4 + { + if slt(sub(dataEnd_56, headStart_55), 128) + { + revert(0, 0) + } + { + let offset_60 := 0 + value0_57 := abi_decode_t_address(add(headStart_55, offset_60), dataEnd_56) + } + { + let offset_61 := 32 + value1_58 := abi_decode_t_uint256(add(headStart_55, offset_61), dataEnd_56) + } + { + let offset_62 := calldataload(add(headStart_55, 64)) + if gt(offset_62, 0xffffffffffffffff) + { + revert(0, 0) + } + value2_59, value3 := abi_decode_t_bytes_calldata_ptr(add(headStart_55, offset_62), dataEnd_56) + } + { + let offset_63 := 96 + value4 := abi_decode_t_enum$_Operation_$1949(add(headStart_55, offset_63), dataEnd_56) + } + } + function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949t_uint256t_uint256t_uint256t_addresst_address_payablet_bytes_calldata_ptr(headStart_64, dataEnd_65) -> value0_66, value1_67, value2_68, value3_69, value4_70, value5, value6, value7, value8, value9, value10, value11 + { + if slt(sub(dataEnd_65, headStart_64), 320) + { + revert(0, 0) + } + { + let offset_71 := 0 + value0_66 := abi_decode_t_address(add(headStart_64, offset_71), dataEnd_65) + } + { + let offset_72 := 32 + value1_67 := abi_decode_t_uint256(add(headStart_64, offset_72), dataEnd_65) + } + { + let offset_73 := calldataload(add(headStart_64, 64)) + if gt(offset_73, 0xffffffffffffffff) + { + revert(0, 0) + } + value2_68, value3_69 := abi_decode_t_bytes_calldata_ptr(add(headStart_64, offset_73), dataEnd_65) + } + { + let offset_74 := 96 + value4_70 := abi_decode_t_enum$_Operation_$1949(add(headStart_64, offset_74), dataEnd_65) + } + { + let offset_75 := 128 + value5 := abi_decode_t_uint256(add(headStart_64, offset_75), dataEnd_65) + } + { + let offset_76 := 160 + value6 := abi_decode_t_uint256(add(headStart_64, offset_76), dataEnd_65) + } + { + let offset_77 := 192 + value7 := abi_decode_t_uint256(add(headStart_64, offset_77), dataEnd_65) + } + { + let offset_78 := 224 + value8 := abi_decode_t_address(add(headStart_64, offset_78), dataEnd_65) + } + { + let offset_79 := 256 + value9 := abi_decode_t_address_payable(add(headStart_64, offset_79), dataEnd_65) + } + { + let offset_80 := calldataload(add(headStart_64, 288)) + if gt(offset_80, 0xffffffffffffffff) + { + revert(0, 0) + } + value10, value11 := abi_decode_t_bytes_calldata_ptr(add(headStart_64, offset_80), dataEnd_65) + } + } + function abi_decode_tuple_t_addresst_uint256t_bytes_memory_ptrt_enum$_Operation_$1949(headStart_81, dataEnd_82) -> value0_83, value1_84, value2_85, value3_86 + { + if slt(sub(dataEnd_82, headStart_81), 128) + { + revert(0, 0) + } + { + let offset_87 := 0 + value0_83 := abi_decode_t_address(add(headStart_81, offset_87), dataEnd_82) + } + { + let offset_88 := 32 + value1_84 := abi_decode_t_uint256(add(headStart_81, offset_88), dataEnd_82) + } + { + let offset_89 := calldataload(add(headStart_81, 64)) + if gt(offset_89, 0xffffffffffffffff) + { + revert(0, 0) + } + value2_85 := abi_decode_t_bytes_memory_ptr(add(headStart_81, offset_89), dataEnd_82) + } + { + let offset_90 := 96 + value3_86 := abi_decode_t_enum$_Operation_$1949(add(headStart_81, offset_90), dataEnd_82) + } + } + function abi_decode_tuple_t_addresst_uint256t_bytes_memory_ptrt_enum$_Operation_$1949t_uint256t_uint256t_uint256t_addresst_addresst_uint256(headStart_91, dataEnd_92) -> value0_93, value1_94, value2_95, value3_96, value4_97, value5_98, value6_99, value7_100, value8_101, value9_102 + { + if slt(sub(dataEnd_92, headStart_91), 320) + { + revert(0, 0) + } + { + let offset_103 := 0 + value0_93 := abi_decode_t_address(add(headStart_91, offset_103), dataEnd_92) + } + { + let offset_104 := 32 + value1_94 := abi_decode_t_uint256(add(headStart_91, offset_104), dataEnd_92) + } + { + let offset_105 := calldataload(add(headStart_91, 64)) + if gt(offset_105, 0xffffffffffffffff) + { + revert(0, 0) + } + value2_95 := abi_decode_t_bytes_memory_ptr(add(headStart_91, offset_105), dataEnd_92) + } + { + let offset_106 := 96 + value3_96 := abi_decode_t_enum$_Operation_$1949(add(headStart_91, offset_106), dataEnd_92) + } + { + let offset_107 := 128 + value4_97 := abi_decode_t_uint256(add(headStart_91, offset_107), dataEnd_92) + } + { + let offset_108 := 160 + value5_98 := abi_decode_t_uint256(add(headStart_91, offset_108), dataEnd_92) + } + { + let offset_109 := 192 + value6_99 := abi_decode_t_uint256(add(headStart_91, offset_109), dataEnd_92) + } + { + let offset_110 := 224 + value7_100 := abi_decode_t_address(add(headStart_91, offset_110), dataEnd_92) + } + { + let offset_111 := 256 + value8_101 := abi_decode_t_address(add(headStart_91, offset_111), dataEnd_92) + } + { + let offset_112 := 288 + value9_102 := abi_decode_t_uint256(add(headStart_91, offset_112), dataEnd_92) + } + } + function abi_decode_tuple_t_array$_t_address_$dyn_calldata_ptrt_uint256t_addresst_bytes_calldata_ptr(headStart_113, dataEnd_114) -> value0_115, value1_116, value2_117, value3_118, value4_119, value5_120 + { + if slt(sub(dataEnd_114, headStart_113), 128) + { + revert(0, 0) + } + { + let offset_121 := calldataload(add(headStart_113, 0)) + if gt(offset_121, 0xffffffffffffffff) + { + revert(0, 0) + } + value0_115, value1_116 := abi_decode_t_array$_t_address_$dyn_calldata_ptr(add(headStart_113, offset_121), dataEnd_114) + } + { + let offset_122 := 32 + value2_117 := abi_decode_t_uint256(add(headStart_113, offset_122), dataEnd_114) + } + { + let offset_123 := 64 + value3_118 := abi_decode_t_address(add(headStart_113, offset_123), dataEnd_114) + } + { + let offset_124 := calldataload(add(headStart_113, 96)) + if gt(offset_124, 0xffffffffffffffff) + { + revert(0, 0) + } + value4_119, value5_120 := abi_decode_t_bytes_calldata_ptr(add(headStart_113, offset_124), dataEnd_114) + } + } + function abi_decode_tuple_t_bool_fromMemory(headStart_125, dataEnd_126) -> value0_127 + { + if slt(sub(dataEnd_126, headStart_125), 32) + { + revert(0, 0) + } + { + let offset_128 := 0 + value0_127 := abi_decode_t_bool_fromMemory(add(headStart_125, offset_128), dataEnd_126) + } + } + function abi_decode_tuple_t_bytes32(headStart_129, dataEnd_130) -> value0_131 + { + if slt(sub(dataEnd_130, headStart_129), 32) + { + revert(0, 0) + } + { + let offset_132 := 0 + value0_131 := abi_decode_t_bytes32(add(headStart_129, offset_132), dataEnd_130) + } + } + function abi_decode_tuple_t_bytes_calldata_ptr(headStart_133, dataEnd_134) -> value0_135, value1_136 + { + if slt(sub(dataEnd_134, headStart_133), 32) + { + revert(0, 0) + } + { + let offset_137 := calldataload(add(headStart_133, 0)) + if gt(offset_137, 0xffffffffffffffff) + { + revert(0, 0) + } + value0_135, value1_136 := abi_decode_t_bytes_calldata_ptr(add(headStart_133, offset_137), dataEnd_134) + } + } + function abi_decode_tuple_t_bytes_calldata_ptrt_bytes_calldata_ptr(headStart_138, dataEnd_139) -> value0_140, value1_141, value2_142, value3_143 + { + if slt(sub(dataEnd_139, headStart_138), 64) + { + revert(0, 0) + } + { + let offset_144 := calldataload(add(headStart_138, 0)) + if gt(offset_144, 0xffffffffffffffff) + { + revert(0, 0) + } + value0_140, value1_141 := abi_decode_t_bytes_calldata_ptr(add(headStart_138, offset_144), dataEnd_139) + } + { + let offset_145 := calldataload(add(headStart_138, 32)) + if gt(offset_145, 0xffffffffffffffff) + { + revert(0, 0) + } + value2_142, value3_143 := abi_decode_t_bytes_calldata_ptr(add(headStart_138, offset_145), dataEnd_139) + } + } + function abi_decode_tuple_t_bytes_memory_ptr(headStart_146, dataEnd_147) -> value0_148 + { + if slt(sub(dataEnd_147, headStart_146), 32) + { + revert(0, 0) + } + { + let offset_149 := calldataload(add(headStart_146, 0)) + if gt(offset_149, 0xffffffffffffffff) + { + revert(0, 0) + } + value0_148 := abi_decode_t_bytes_memory_ptr(add(headStart_146, offset_149), dataEnd_147) + } + } + function abi_decode_tuple_t_contract$_Module_$1038(headStart_150, dataEnd_151) -> value0_152 + { + if slt(sub(dataEnd_151, headStart_150), 32) + { + revert(0, 0) + } + { + let offset_153 := 0 + value0_152 := abi_decode_t_contract$_Module_$1038(add(headStart_150, offset_153), dataEnd_151) + } + } + function abi_decode_tuple_t_contract$_Module_$1038t_contract$_Module_$1038(headStart_154, dataEnd_155) -> value0_156, value1_157 + { + if slt(sub(dataEnd_155, headStart_154), 64) + { + revert(0, 0) + } + { + let offset_158 := 0 + value0_156 := abi_decode_t_contract$_Module_$1038(add(headStart_154, offset_158), dataEnd_155) + } + { + let offset_159 := 32 + value1_157 := abi_decode_t_contract$_Module_$1038(add(headStart_154, offset_159), dataEnd_155) + } + } + function abi_decode_tuple_t_uint256(headStart_160, dataEnd_161) -> value0_162 + { + if slt(sub(dataEnd_161, headStart_160), 32) + { + revert(0, 0) + } + { + let offset_163 := 0 + value0_162 := abi_decode_t_uint256(add(headStart_160, offset_163), dataEnd_161) + } + } + function abi_encode_t_address_to_t_address(value_164, pos) + { + mstore(pos, cleanup_assert_t_address(value_164)) + } + function abi_encode_t_array$_t_address_$dyn_memory_ptr_to_t_array$_t_address_$dyn_memory_ptr(value_165, pos_166) -> end_167 + { + let length_168 := array_length_t_array$_t_address_$dyn_memory_ptr(value_165) + mstore(pos_166, length_168) + pos_166 := add(pos_166, 0x20) + let srcPtr := array_dataslot_t_array$_t_address_$dyn_memory_ptr(value_165) + for { + let i := 0 + } + lt(i, length_168) + { + i := add(i, 1) + } + { + abi_encode_t_address_to_t_address(mload(srcPtr), pos_166) + srcPtr := array_nextElement_t_array$_t_address_$dyn_memory_ptr(srcPtr) + pos_166 := add(pos_166, 0x20) + } + end_167 := pos_166 + } + function abi_encode_t_bool_to_t_bool(value_169, pos_170) + { + mstore(pos_170, cleanup_assert_t_bool(value_169)) + } + function abi_encode_t_bytes32_to_t_bytes32(value_171, pos_172) + { + mstore(pos_172, cleanup_assert_t_bytes32(value_171)) + } + function abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr(value_173, pos_174) -> end_175 + { + let length_176 := array_length_t_bytes_memory_ptr(value_173) + mstore(pos_174, length_176) + copy_memory_to_memory(add(value_173, 0x20), add(pos_174, 0x20), length_176) + end_175 := add(add(pos_174, 0x20), round_up_to_mul_of_32(length_176)) + } + function abi_encode_t_contract$_GnosisSafe_$710_to_t_address_payable(value_177, pos_178) + { + mstore(pos_178, convert_t_contract$_GnosisSafe_$710_to_t_address_payable(value_177)) + } + function abi_encode_t_contract$_Module_$1038_to_t_address(value_179, pos_180) + { + mstore(pos_180, convert_t_contract$_Module_$1038_to_t_address(value_179)) + } + function abi_encode_t_enum$_Operation_$1949_to_t_uint8(value_181, pos_182) + { + mstore(pos_182, convert_t_enum$_Operation_$1949_to_t_uint8(value_181)) + } + function abi_encode_t_string_memory_ptr_to_t_string_memory_ptr(value_183, pos_184) -> end_185 + { + let length_186 := array_length_t_string_memory_ptr(value_183) + mstore(pos_184, length_186) + copy_memory_to_memory(add(value_183, 0x20), add(pos_184, 0x20), length_186) + end_185 := add(add(pos_184, 0x20), round_up_to_mul_of_32(length_186)) + } + function abi_encode_t_string_memory_to_t_string_memory_ptr(value_187, pos_188) -> end_189 + { + let length_190 := array_length_t_string_memory(value_187) + mstore(pos_188, length_190) + copy_memory_to_memory(add(value_187, 0x20), add(pos_188, 0x20), length_190) + end_189 := add(add(pos_188, 0x20), round_up_to_mul_of_32(length_190)) + } + function abi_encode_t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87_to_t_string_memory_ptr(pos_191) -> end_192 + { + mstore(pos_191, 36) + mstore(add(pos_191, 32), 0x496e76616c6964206d617374657220636f707920616464726573732070726f76) + mstore(add(pos_191, 64), 0x6964656400000000000000000000000000000000000000000000000000000000) + end_192 := add(pos_191, 96) + } + function abi_encode_t_stringliteral_1e0428ffa69bff65645154a36d5017c238f946ddaf89430d30eec813f30bdd77_to_t_string_memory_ptr(pos_193) -> end_194 + { + mstore(pos_193, 37) + mstore(add(pos_193, 32), 0x4d6f64756c6573206861766520616c7265616479206265656e20696e69746961) + mstore(add(pos_193, 64), 0x6c697a6564000000000000000000000000000000000000000000000000000000) + end_194 := add(pos_193, 96) + } + function abi_encode_t_stringliteral_21a1cd38818adb750881fbf07c26ce7223dde608fdd9dadd31a0d41afeca2094_to_t_string_memory_ptr(pos_195) -> end_196 + { + mstore(pos_195, 30) + mstore(add(pos_195, 32), 0x496e76616c6964206f776e657220616464726573732070726f76696465640000) + end_196 := add(pos_195, 64) + } + function abi_encode_t_stringliteral_5caa315f9c5cf61be71c182eef2dc9ef7b6ce6b42c320d36694e1d23e09c287e_to_t_string_memory_ptr(pos_197) -> end_198 + { + mstore(pos_197, 40) + mstore(add(pos_197, 32), 0x496e76616c696420707265764d6f64756c652c206d6f64756c65207061697220) + mstore(add(pos_197, 64), 0x70726f7669646564000000000000000000000000000000000000000000000000) + end_198 := add(pos_197, 96) + } + function abi_encode_t_stringliteral_60f21058f4a7689ef29853b3c9c17c9bf69856a949794649bb68878f00552475_to_t_string_memory_ptr(pos_199) -> end_200 + { + mstore(pos_199, 30) + mstore(add(pos_199, 32), 0x4f6e6c79206f776e6572732063616e20617070726f7665206120686173680000) + end_200 := add(pos_199, 64) + } + function abi_encode_t_stringliteral_63d26a9feb8568677e5c255c04e4da88e86a25137d5152a9a089790b7e710e86_to_t_string_memory_ptr(pos_201) -> end_202 + { + mstore(pos_201, 35) + mstore(add(pos_201, 32), 0x5468726573686f6c642063616e6e6f7420657863656564206f776e657220636f) + mstore(add(pos_201, 64), 0x756e740000000000000000000000000000000000000000000000000000000000) + end_202 := add(pos_201, 96) + } + function abi_encode_t_stringliteral_7913a3f9168bf3e458e3f42eb08db5c4b33f44228d345660887090b75e24c6aa_to_t_string_memory_ptr(pos_203) -> end_204 + { + mstore(pos_203, 31) + mstore(add(pos_203, 32), 0x436f756c64206e6f742066696e69736820696e697469616c697a6174696f6e00) + end_204 := add(pos_203, 64) + } + function abi_encode_t_stringliteral_839b4c4db845de24ec74ef067d85431087d6987a4c904418ee4f6ec699c02482_to_t_string_memory_ptr(pos_205) -> end_206 + { + mstore(pos_205, 53) + mstore(add(pos_205, 32), 0x4e6577206f776e657220636f756e74206e6565647320746f206265206c617267) + mstore(add(pos_205, 64), 0x6572207468616e206e6577207468726573686f6c640000000000000000000000) + end_206 := add(pos_205, 96) + } + function abi_encode_t_stringliteral_8560a13547eca5648355c8db1a9f8653b6f657d31d476c36bca25e47b45b08f4_to_t_string_memory_ptr(pos_207) -> end_208 + { + mstore(pos_207, 34) + mstore(add(pos_207, 32), 0x436f756c64206e6f74207061792067617320636f737473207769746820746f6b) + mstore(add(pos_207, 64), 0x656e000000000000000000000000000000000000000000000000000000000000) + end_208 := add(pos_207, 96) + } + function abi_encode_t_stringliteral_85bcea44c930431ef19052d068cc504a81260341ae6c5ee84bb5a38ec55acf05_to_t_string_memory_ptr(pos_209) -> end_210 + { + mstore(pos_209, 27) + mstore(add(pos_209, 32), 0x496e76616c6964207369676e6174757265732070726f76696465640000000000) + end_210 := add(pos_209, 64) + } + function abi_encode_t_stringliteral_8c2199b479423c52a835dfe8b0f2e9eb4c1ec1069ba198ccc38077a4a88a5c00_to_t_string_memory_ptr(pos_211) -> end_212 + { + mstore(pos_211, 31) + mstore(add(pos_211, 32), 0x496e76616c6964206d6f64756c6520616464726573732070726f766964656400) + end_212 := add(pos_211, 64) + } + function abi_encode_t_stringliteral_960698caed81fce71c9b7d572ab2e035b6014a5b812b51df8462ea9817fc4ebc_to_t_string_memory_ptr(pos_213) -> end_214 + { + mstore(pos_213, 38) + mstore(add(pos_213, 32), 0x496e76616c696420707265764f776e65722c206f776e65722070616972207072) + mstore(add(pos_213, 64), 0x6f76696465640000000000000000000000000000000000000000000000000000) + end_214 := add(pos_213, 96) + } + function abi_encode_t_stringliteral_9a45ae898fbe2bd07a0b33b5a6c421f76198e9deb66843b8d827b0b9e4a16f86_to_t_string_memory_ptr(pos_215) -> end_216 + { + mstore(pos_215, 30) + mstore(add(pos_215, 32), 0x4f776e657273206861766520616c7265616479206265656e2073657475700000) + end_216 := add(pos_215, 64) + } + function abi_encode_t_stringliteral_9d461d71e19b25cd406798d062d7e61f961ad52541d3077a543e857810427d47_to_t_string_memory_ptr(pos_217) -> end_218 + { + mstore(pos_217, 27) + mstore(add(pos_217, 32), 0x4164647265737320697320616c726561647920616e206f776e65720000000000) + end_218 := add(pos_217, 64) + } + function abi_encode_t_stringliteral_a2e1f2db9cd32eaa6a2caa3d6caa726a30dc0417d866440bfe13d6a6d030e5e2_to_t_string_memory_ptr(pos_219) -> end_220 + { + mstore(pos_219, 29) + mstore(add(pos_219, 32), 0x446f6d61696e20536570617261746f7220616c72656164792073657421000000) + end_220 := add(pos_219, 64) + } + function abi_encode_t_stringliteral_a803fa289679098e38a7f1f6fe43056918c5ab5af07441cb8db77b949c165ca1_to_t_string_memory_ptr(pos_221) -> end_222 + { + mstore(pos_221, 32) + mstore(add(pos_221, 32), 0x4475706c6963617465206f776e657220616464726573732070726f7669646564) + end_222 := add(pos_221, 64) + } + function abi_encode_t_stringliteral_ae2b4ea52eaf6de3fb2d8a64b7555be2dfd285b837a62821bf24e7dc6f329450_to_t_string_memory_ptr(pos_223) -> end_224 + { + mstore(pos_223, 29) + mstore(add(pos_223, 32), 0x4d6f64756c652068617320616c7265616479206265656e206164646564000000) + end_224 := add(pos_223, 64) + } + function abi_encode_t_stringliteral_b995394ed6031392a784e6dd5e04285cca83077a8dc3873d2fb7fcb090297ab4_to_t_string_memory_ptr(pos_225) -> end_226 + { + mstore(pos_225, 36) + mstore(add(pos_225, 32), 0x5468726573686f6c64206e6565647320746f2062652067726561746572207468) + mstore(add(pos_225, 64), 0x616e203000000000000000000000000000000000000000000000000000000000) + end_226 := add(pos_225, 96) + } + function abi_encode_t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733_to_t_string_memory_ptr(pos_227) -> end_228 + { + mstore(pos_227, 44) + mstore(add(pos_227, 32), 0x4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d2074) + mstore(add(pos_227, 64), 0x68697320636f6e74726163740000000000000000000000000000000000000000) + end_228 := add(pos_227, 96) + } + function abi_encode_t_stringliteral_cd36462b17a97c5a3df33333c859d5933a4fb7f5e1a0750f5def8eb51f3272e4_to_t_string_memory_ptr(pos_229) -> end_230 + { + mstore(pos_229, 48) + mstore(add(pos_229, 32), 0x4d6574686f642063616e206f6e6c792062652063616c6c65642066726f6d2061) + mstore(add(pos_229, 64), 0x6e20656e61626c6564206d6f64756c6500000000000000000000000000000000) + end_230 := add(pos_229, 96) + } + function abi_encode_t_stringliteral_e2a11e15f7be1214c1340779ad55027af8aa33aee6cb521776a28a0a44aea377_to_t_string_memory_ptr(pos_231) -> end_232 + { + mstore(pos_231, 34) + mstore(add(pos_231, 32), 0x436f756c64206e6f74207061792067617320636f737473207769746820657468) + mstore(add(pos_231, 64), 0x6572000000000000000000000000000000000000000000000000000000000000) + end_232 := add(pos_231, 96) + } + function abi_encode_t_stringliteral_e7ccb05a0f2c66d12451cdfc6bbab488c38ab704d0f6af9ad18763542e9e5f18_to_t_string_memory_ptr(pos_233) -> end_234 + { + mstore(pos_233, 42) + mstore(add(pos_233, 32), 0x4e6f7420656e6f7567682067617320746f206578656375746520736166652074) + mstore(add(pos_233, 64), 0x72616e73616374696f6e00000000000000000000000000000000000000000000) + end_234 := add(pos_233, 96) + } + function abi_encode_t_uint256_to_t_uint256(value_235, pos_236) + { + mstore(pos_236, cleanup_assert_t_uint256(value_235)) + } + function abi_encode_tuple_t_address__to_t_address_(headStart_237, value0_238) -> tail + { + tail := add(headStart_237, 32) + abi_encode_t_address_to_t_address(value0_238, add(headStart_237, 0)) + } + function abi_encode_tuple_t_address_t_uint256__to_t_address_t_uint256_(headStart_239, value1_240, value0_241) -> tail_242 + { + tail_242 := add(headStart_239, 64) + abi_encode_t_address_to_t_address(value0_241, add(headStart_239, 0)) + abi_encode_t_uint256_to_t_uint256(value1_240, add(headStart_239, 32)) + } + function abi_encode_tuple_t_array$_t_address_$dyn_memory_ptr__to_t_array$_t_address_$dyn_memory_ptr_(headStart_243, value0_244) -> tail_245 + { + tail_245 := add(headStart_243, 32) + mstore(add(headStart_243, 0), sub(tail_245, headStart_243)) + tail_245 := abi_encode_t_array$_t_address_$dyn_memory_ptr_to_t_array$_t_address_$dyn_memory_ptr(value0_244, tail_245) + } + function abi_encode_tuple_t_bool__to_t_bool_(headStart_246, value0_247) -> tail_248 + { + tail_248 := add(headStart_246, 32) + abi_encode_t_bool_to_t_bool(value0_247, add(headStart_246, 0)) + } + function abi_encode_tuple_t_bytes32__to_t_bytes32_(headStart_249, value0_250) -> tail_251 + { + tail_251 := add(headStart_249, 32) + abi_encode_t_bytes32_to_t_bytes32(value0_250, add(headStart_249, 0)) + } + function abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(headStart_252, value10_253, value9_254, value8_255, value7_256, value6_257, value5_258, value4_259, value3_260, value2_261, value1_262, value0_263) -> tail_264 + { + tail_264 := add(headStart_252, 352) + abi_encode_t_bytes32_to_t_bytes32(value0_263, add(headStart_252, 0)) + abi_encode_t_address_to_t_address(value1_262, add(headStart_252, 32)) + abi_encode_t_uint256_to_t_uint256(value2_261, add(headStart_252, 64)) + abi_encode_t_bytes32_to_t_bytes32(value3_260, add(headStart_252, 96)) + abi_encode_t_enum$_Operation_$1949_to_t_uint8(value4_259, add(headStart_252, 128)) + abi_encode_t_uint256_to_t_uint256(value5_258, add(headStart_252, 160)) + abi_encode_t_uint256_to_t_uint256(value6_257, add(headStart_252, 192)) + abi_encode_t_uint256_to_t_uint256(value7_256, add(headStart_252, 224)) + abi_encode_t_address_to_t_address(value8_255, add(headStart_252, 256)) + abi_encode_t_address_to_t_address(value9_254, add(headStart_252, 288)) + abi_encode_t_uint256_to_t_uint256(value10_253, add(headStart_252, 320)) + } + function abi_encode_tuple_t_bytes32_t_bytes32__to_t_bytes32_t_bytes32_(headStart_265, value1_266, value0_267) -> tail_268 + { + tail_268 := add(headStart_265, 64) + abi_encode_t_bytes32_to_t_bytes32(value0_267, add(headStart_265, 0)) + abi_encode_t_bytes32_to_t_bytes32(value1_266, add(headStart_265, 32)) + } + function abi_encode_tuple_t_bytes32_t_contract$_GnosisSafe_$710__to_t_bytes32_t_address_payable_(headStart_269, value1_270, value0_271) -> tail_272 + { + tail_272 := add(headStart_269, 64) + abi_encode_t_bytes32_to_t_bytes32(value0_271, add(headStart_269, 0)) + abi_encode_t_contract$_GnosisSafe_$710_to_t_address_payable(value1_270, add(headStart_269, 32)) + } + function abi_encode_tuple_t_bytes_memory_ptr__to_t_bytes_memory_ptr_(headStart_273, value0_274) -> tail_275 + { + tail_275 := add(headStart_273, 32) + mstore(add(headStart_273, 0), sub(tail_275, headStart_273)) + tail_275 := abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr(value0_274, tail_275) + } + function abi_encode_tuple_t_bytes_memory_ptr_t_bytes_memory_ptr__to_t_bytes_memory_ptr_t_bytes_memory_ptr_(headStart_276, value1_277, value0_278) -> tail_279 + { + tail_279 := add(headStart_276, 64) + mstore(add(headStart_276, 0), sub(tail_279, headStart_276)) + tail_279 := abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr(value0_278, tail_279) + mstore(add(headStart_276, 32), sub(tail_279, headStart_276)) + tail_279 := abi_encode_t_bytes_memory_ptr_to_t_bytes_memory_ptr(value1_277, tail_279) + } + function abi_encode_tuple_t_contract$_Module_$1038__to_t_address_(headStart_280, value0_281) -> tail_282 + { + tail_282 := add(headStart_280, 32) + abi_encode_t_contract$_Module_$1038_to_t_address(value0_281, add(headStart_280, 0)) + } + function abi_encode_tuple_t_string_memory__to_t_string_memory_ptr_(headStart_283, value0_284) -> tail_285 + { + tail_285 := add(headStart_283, 32) + mstore(add(headStart_283, 0), sub(tail_285, headStart_283)) + tail_285 := abi_encode_t_string_memory_to_t_string_memory_ptr(value0_284, tail_285) + } + function abi_encode_tuple_t_string_memory_ptr__to_t_string_memory_ptr_(headStart_286, value0_287) -> tail_288 + { + tail_288 := add(headStart_286, 32) + mstore(add(headStart_286, 0), sub(tail_288, headStart_286)) + tail_288 := abi_encode_t_string_memory_ptr_to_t_string_memory_ptr(value0_287, tail_288) + } + function abi_encode_tuple_t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87__to_t_string_memory_ptr_(headStart_289) -> tail_290 + { + tail_290 := add(headStart_289, 32) + mstore(add(headStart_289, 0), sub(tail_290, headStart_289)) + tail_290 := abi_encode_t_stringliteral_108d84599042957b954e89d43b52f80be89321dfc114a37800028eba58dafc87_to_t_string_memory_ptr(tail_290) + } + function abi_encode_tuple_t_stringliteral_1e0428ffa69bff65645154a36d5017c238f946ddaf89430d30eec813f30bdd77__to_t_string_memory_ptr_(headStart_291) -> tail_292 + { + tail_292 := add(headStart_291, 32) + mstore(add(headStart_291, 0), sub(tail_292, headStart_291)) + tail_292 := abi_encode_t_stringliteral_1e0428ffa69bff65645154a36d5017c238f946ddaf89430d30eec813f30bdd77_to_t_string_memory_ptr(tail_292) + } + function abi_encode_tuple_t_stringliteral_21a1cd38818adb750881fbf07c26ce7223dde608fdd9dadd31a0d41afeca2094__to_t_string_memory_ptr_(headStart_293) -> tail_294 + { + tail_294 := add(headStart_293, 32) + mstore(add(headStart_293, 0), sub(tail_294, headStart_293)) + tail_294 := abi_encode_t_stringliteral_21a1cd38818adb750881fbf07c26ce7223dde608fdd9dadd31a0d41afeca2094_to_t_string_memory_ptr(tail_294) + } + function abi_encode_tuple_t_stringliteral_5caa315f9c5cf61be71c182eef2dc9ef7b6ce6b42c320d36694e1d23e09c287e__to_t_string_memory_ptr_(headStart_295) -> tail_296 + { + tail_296 := add(headStart_295, 32) + mstore(add(headStart_295, 0), sub(tail_296, headStart_295)) + tail_296 := abi_encode_t_stringliteral_5caa315f9c5cf61be71c182eef2dc9ef7b6ce6b42c320d36694e1d23e09c287e_to_t_string_memory_ptr(tail_296) + } + function abi_encode_tuple_t_stringliteral_60f21058f4a7689ef29853b3c9c17c9bf69856a949794649bb68878f00552475__to_t_string_memory_ptr_(headStart_297) -> tail_298 + { + tail_298 := add(headStart_297, 32) + mstore(add(headStart_297, 0), sub(tail_298, headStart_297)) + tail_298 := abi_encode_t_stringliteral_60f21058f4a7689ef29853b3c9c17c9bf69856a949794649bb68878f00552475_to_t_string_memory_ptr(tail_298) + } + function abi_encode_tuple_t_stringliteral_63d26a9feb8568677e5c255c04e4da88e86a25137d5152a9a089790b7e710e86__to_t_string_memory_ptr_(headStart_299) -> tail_300 + { + tail_300 := add(headStart_299, 32) + mstore(add(headStart_299, 0), sub(tail_300, headStart_299)) + tail_300 := abi_encode_t_stringliteral_63d26a9feb8568677e5c255c04e4da88e86a25137d5152a9a089790b7e710e86_to_t_string_memory_ptr(tail_300) + } + function abi_encode_tuple_t_stringliteral_7913a3f9168bf3e458e3f42eb08db5c4b33f44228d345660887090b75e24c6aa__to_t_string_memory_ptr_(headStart_301) -> tail_302 + { + tail_302 := add(headStart_301, 32) + mstore(add(headStart_301, 0), sub(tail_302, headStart_301)) + tail_302 := abi_encode_t_stringliteral_7913a3f9168bf3e458e3f42eb08db5c4b33f44228d345660887090b75e24c6aa_to_t_string_memory_ptr(tail_302) + } + function abi_encode_tuple_t_stringliteral_839b4c4db845de24ec74ef067d85431087d6987a4c904418ee4f6ec699c02482__to_t_string_memory_ptr_(headStart_303) -> tail_304 + { + tail_304 := add(headStart_303, 32) + mstore(add(headStart_303, 0), sub(tail_304, headStart_303)) + tail_304 := abi_encode_t_stringliteral_839b4c4db845de24ec74ef067d85431087d6987a4c904418ee4f6ec699c02482_to_t_string_memory_ptr(tail_304) + } + function abi_encode_tuple_t_stringliteral_8560a13547eca5648355c8db1a9f8653b6f657d31d476c36bca25e47b45b08f4__to_t_string_memory_ptr_(headStart_305) -> tail_306 + { + tail_306 := add(headStart_305, 32) + mstore(add(headStart_305, 0), sub(tail_306, headStart_305)) + tail_306 := abi_encode_t_stringliteral_8560a13547eca5648355c8db1a9f8653b6f657d31d476c36bca25e47b45b08f4_to_t_string_memory_ptr(tail_306) + } + function abi_encode_tuple_t_stringliteral_85bcea44c930431ef19052d068cc504a81260341ae6c5ee84bb5a38ec55acf05__to_t_string_memory_ptr_(headStart_307) -> tail_308 + { + tail_308 := add(headStart_307, 32) + mstore(add(headStart_307, 0), sub(tail_308, headStart_307)) + tail_308 := abi_encode_t_stringliteral_85bcea44c930431ef19052d068cc504a81260341ae6c5ee84bb5a38ec55acf05_to_t_string_memory_ptr(tail_308) + } + function abi_encode_tuple_t_stringliteral_8c2199b479423c52a835dfe8b0f2e9eb4c1ec1069ba198ccc38077a4a88a5c00__to_t_string_memory_ptr_(headStart_309) -> tail_310 + { + tail_310 := add(headStart_309, 32) + mstore(add(headStart_309, 0), sub(tail_310, headStart_309)) + tail_310 := abi_encode_t_stringliteral_8c2199b479423c52a835dfe8b0f2e9eb4c1ec1069ba198ccc38077a4a88a5c00_to_t_string_memory_ptr(tail_310) + } + function abi_encode_tuple_t_stringliteral_960698caed81fce71c9b7d572ab2e035b6014a5b812b51df8462ea9817fc4ebc__to_t_string_memory_ptr_(headStart_311) -> tail_312 + { + tail_312 := add(headStart_311, 32) + mstore(add(headStart_311, 0), sub(tail_312, headStart_311)) + tail_312 := abi_encode_t_stringliteral_960698caed81fce71c9b7d572ab2e035b6014a5b812b51df8462ea9817fc4ebc_to_t_string_memory_ptr(tail_312) + } + function abi_encode_tuple_t_stringliteral_9a45ae898fbe2bd07a0b33b5a6c421f76198e9deb66843b8d827b0b9e4a16f86__to_t_string_memory_ptr_(headStart_313) -> tail_314 + { + tail_314 := add(headStart_313, 32) + mstore(add(headStart_313, 0), sub(tail_314, headStart_313)) + tail_314 := abi_encode_t_stringliteral_9a45ae898fbe2bd07a0b33b5a6c421f76198e9deb66843b8d827b0b9e4a16f86_to_t_string_memory_ptr(tail_314) + } + function abi_encode_tuple_t_stringliteral_9d461d71e19b25cd406798d062d7e61f961ad52541d3077a543e857810427d47__to_t_string_memory_ptr_(headStart_315) -> tail_316 + { + tail_316 := add(headStart_315, 32) + mstore(add(headStart_315, 0), sub(tail_316, headStart_315)) + tail_316 := abi_encode_t_stringliteral_9d461d71e19b25cd406798d062d7e61f961ad52541d3077a543e857810427d47_to_t_string_memory_ptr(tail_316) + } + function abi_encode_tuple_t_stringliteral_a2e1f2db9cd32eaa6a2caa3d6caa726a30dc0417d866440bfe13d6a6d030e5e2__to_t_string_memory_ptr_(headStart_317) -> tail_318 + { + tail_318 := add(headStart_317, 32) + mstore(add(headStart_317, 0), sub(tail_318, headStart_317)) + tail_318 := abi_encode_t_stringliteral_a2e1f2db9cd32eaa6a2caa3d6caa726a30dc0417d866440bfe13d6a6d030e5e2_to_t_string_memory_ptr(tail_318) + } + function abi_encode_tuple_t_stringliteral_a803fa289679098e38a7f1f6fe43056918c5ab5af07441cb8db77b949c165ca1__to_t_string_memory_ptr_(headStart_319) -> tail_320 + { + tail_320 := add(headStart_319, 32) + mstore(add(headStart_319, 0), sub(tail_320, headStart_319)) + tail_320 := abi_encode_t_stringliteral_a803fa289679098e38a7f1f6fe43056918c5ab5af07441cb8db77b949c165ca1_to_t_string_memory_ptr(tail_320) + } + function abi_encode_tuple_t_stringliteral_ae2b4ea52eaf6de3fb2d8a64b7555be2dfd285b837a62821bf24e7dc6f329450__to_t_string_memory_ptr_(headStart_321) -> tail_322 + { + tail_322 := add(headStart_321, 32) + mstore(add(headStart_321, 0), sub(tail_322, headStart_321)) + tail_322 := abi_encode_t_stringliteral_ae2b4ea52eaf6de3fb2d8a64b7555be2dfd285b837a62821bf24e7dc6f329450_to_t_string_memory_ptr(tail_322) + } + function abi_encode_tuple_t_stringliteral_b995394ed6031392a784e6dd5e04285cca83077a8dc3873d2fb7fcb090297ab4__to_t_string_memory_ptr_(headStart_323) -> tail_324 + { + tail_324 := add(headStart_323, 32) + mstore(add(headStart_323, 0), sub(tail_324, headStart_323)) + tail_324 := abi_encode_t_stringliteral_b995394ed6031392a784e6dd5e04285cca83077a8dc3873d2fb7fcb090297ab4_to_t_string_memory_ptr(tail_324) + } + function abi_encode_tuple_t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733__to_t_string_memory_ptr_(headStart_325) -> tail_326 + { + tail_326 := add(headStart_325, 32) + mstore(add(headStart_325, 0), sub(tail_326, headStart_325)) + tail_326 := abi_encode_t_stringliteral_c4780ef0a1d41d59bac8c510cf9ada421bccf2b90f75a8e4ba2e8c09e8d72733_to_t_string_memory_ptr(tail_326) + } + function abi_encode_tuple_t_stringliteral_cd36462b17a97c5a3df33333c859d5933a4fb7f5e1a0750f5def8eb51f3272e4__to_t_string_memory_ptr_(headStart_327) -> tail_328 + { + tail_328 := add(headStart_327, 32) + mstore(add(headStart_327, 0), sub(tail_328, headStart_327)) + tail_328 := abi_encode_t_stringliteral_cd36462b17a97c5a3df33333c859d5933a4fb7f5e1a0750f5def8eb51f3272e4_to_t_string_memory_ptr(tail_328) + } + function abi_encode_tuple_t_stringliteral_e2a11e15f7be1214c1340779ad55027af8aa33aee6cb521776a28a0a44aea377__to_t_string_memory_ptr_(headStart_329) -> tail_330 + { + tail_330 := add(headStart_329, 32) + mstore(add(headStart_329, 0), sub(tail_330, headStart_329)) + tail_330 := abi_encode_t_stringliteral_e2a11e15f7be1214c1340779ad55027af8aa33aee6cb521776a28a0a44aea377_to_t_string_memory_ptr(tail_330) + } + function abi_encode_tuple_t_stringliteral_e7ccb05a0f2c66d12451cdfc6bbab488c38ab704d0f6af9ad18763542e9e5f18__to_t_string_memory_ptr_(headStart_331) -> tail_332 + { + tail_332 := add(headStart_331, 32) + mstore(add(headStart_331, 0), sub(tail_332, headStart_331)) + tail_332 := abi_encode_t_stringliteral_e7ccb05a0f2c66d12451cdfc6bbab488c38ab704d0f6af9ad18763542e9e5f18_to_t_string_memory_ptr(tail_332) + } + function abi_encode_tuple_t_uint256__to_t_uint256_(headStart_333, value0_334) -> tail_335 + { + tail_335 := add(headStart_333, 32) + abi_encode_t_uint256_to_t_uint256(value0_334, add(headStart_333, 0)) + } + function allocateMemory(size) -> memPtr + { + memPtr := mload(64) + let newFreePtr := add(memPtr, size) + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) + { + revert(0, 0) + } + mstore(64, newFreePtr) + } + function array_allocation_size_t_bytes_memory_ptr(length_336) -> size_337 + { + if gt(length_336, 0xffffffffffffffff) + { + revert(0, 0) + } + size_337 := and(add(length_336, 0x1f), not(0x1f)) + size_337 := add(size_337, 0x20) + } + function array_dataslot_t_array$_t_address_$dyn_memory_ptr(memPtr_338) -> dataPtr + { + dataPtr := add(memPtr_338, 0x20) + } + function array_length_t_array$_t_address_$dyn_memory_ptr(value_339) -> length_340 + { + length_340 := mload(value_339) + } + function array_length_t_bytes_memory_ptr(value_341) -> length_342 + { + length_342 := mload(value_341) + } + function array_length_t_string_memory(value_343) -> length_344 + { + length_344 := mload(value_343) + } + function array_length_t_string_memory_ptr(value_345) -> length_346 + { + length_346 := mload(value_345) + } + function array_nextElement_t_array$_t_address_$dyn_memory_ptr(memPtr_347) -> nextPtr + { + nextPtr := add(memPtr_347, 0x20) + } + function cleanup_assert_t_address(value_348) -> cleaned + { + cleaned := cleanup_assert_t_uint160(value_348) + } + function cleanup_assert_t_bool(value_349) -> cleaned_350 + { + cleaned_350 := iszero(iszero(value_349)) + } + function cleanup_assert_t_bytes32(value_351) -> cleaned_352 + { + cleaned_352 := value_351 + } + function cleanup_assert_t_enum$_Operation_$1949(value_353) -> cleaned_354 + { + if iszero(lt(value_353, 3)) + { + invalid() + } + cleaned_354 := value_353 + } + function cleanup_assert_t_uint160(value_355) -> cleaned_356 + { + cleaned_356 := and(value_355, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) + } + function cleanup_assert_t_uint256(value_357) -> cleaned_358 + { + cleaned_358 := value_357 + } + function cleanup_revert_t_address(value_359) -> cleaned_360 + { + cleaned_360 := cleanup_assert_t_uint160(value_359) + } + function cleanup_revert_t_address_payable(value_361) -> cleaned_362 + { + cleaned_362 := cleanup_assert_t_uint160(value_361) + } + function cleanup_revert_t_bool(value_363) -> cleaned_364 + { + cleaned_364 := iszero(iszero(value_363)) + } + function cleanup_revert_t_bytes32(value_365) -> cleaned_366 + { + cleaned_366 := value_365 + } + function cleanup_revert_t_contract$_Module_$1038(value_367) -> cleaned_368 + { + cleaned_368 := cleanup_assert_t_address(value_367) + } + function cleanup_revert_t_enum$_Operation_$1949(value_369) -> cleaned_370 + { + if iszero(lt(value_369, 3)) + { + revert(0, 0) + } + cleaned_370 := value_369 + } + function cleanup_revert_t_uint256(value_371) -> cleaned_372 + { + cleaned_372 := value_371 + } + function convert_t_contract$_GnosisSafe_$710_to_t_address_payable(value_373) -> converted + { + converted := convert_t_contract$_GnosisSafe_$710_to_t_uint160(value_373) + } + function convert_t_contract$_GnosisSafe_$710_to_t_uint160(value_374) -> converted_375 + { + converted_375 := cleanup_assert_t_uint160(value_374) + } + function convert_t_contract$_Module_$1038_to_t_address(value_376) -> converted_377 + { + converted_377 := convert_t_contract$_Module_$1038_to_t_uint160(value_376) + } + function convert_t_contract$_Module_$1038_to_t_uint160(value_378) -> converted_379 + { + converted_379 := cleanup_assert_t_uint160(value_378) + } + function convert_t_enum$_Operation_$1949_to_t_uint8(value_380) -> converted_381 + { + converted_381 := cleanup_assert_t_enum$_Operation_$1949(value_380) + } + function copy_calldata_to_memory(src_382, dst_383, length_384) + { + calldatacopy(dst_383, src_382, length_384) + mstore(add(dst_383, length_384), 0) + } + function copy_memory_to_memory(src_385, dst_386, length_387) + { + let i_388 := 0 + for { + } + lt(i_388, length_387) + { + i_388 := add(i_388, 32) + } + { + mstore(add(dst_386, i_388), mload(add(src_385, i_388))) + } + if gt(i_388, length_387) + { + mstore(add(dst_386, length_387), 0) + } + } + function round_up_to_mul_of_32(value_389) -> result + { + result := and(add(value_389, 31), not(31)) + } +} +// ---- +// fullSuite +// { +// let _2 := mload(1) +// let _153 := mload(0) +// if slt(sub(_2, _153), 64) +// { +// revert(0, 0) +// } +// sstore(0, and(calldataload(_153), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) +// let x0, x1, x2, x3, x4 := abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(mload(7), mload(8)) +// sstore(x1, x0) +// sstore(x3, x2) +// sstore(1, x4) +// pop(abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(mload(30), mload(31), mload(32), mload(33), mload(34), mload(35), mload(36), mload(37), mload(38), mload(39), mload(40), mload(41))) +// function abi_decode_tuple_t_addresst_uint256t_bytes_calldata_ptrt_enum$_Operation_$1949(headStart_55, dataEnd_56) -> value0_57, value1_58, value2_59, value3, value4 +// { +// if slt(sub(dataEnd_56, headStart_55), 128) +// { +// revert(value4, value4) +// } +// value0_57 := and(calldataload(add(headStart_55, value4)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) +// value1_58 := calldataload(add(headStart_55, 32)) +// let offset_62 := calldataload(add(headStart_55, 64)) +// let _201 := 0xffffffffffffffff +// if gt(offset_62, _201) +// { +// revert(value4, value4) +// } +// let _203 := add(headStart_55, offset_62) +// if iszero(slt(add(_203, 0x1f), dataEnd_56)) +// { +// revert(value4, value4) +// } +// let abi_decode_length_15_246 := calldataload(_203) +// if gt(abi_decode_length_15_246, _201) +// { +// revert(value4, value4) +// } +// if gt(add(add(_203, abi_decode_length_15_246), 32), dataEnd_56) +// { +// revert(value4, value4) +// } +// value2_59 := add(_203, 32) +// value3 := abi_decode_length_15_246 +// let _206 := calldataload(add(headStart_55, 96)) +// if iszero(lt(_206, 3)) +// { +// revert(value4, value4) +// } +// value4 := _206 +// } +// function abi_encode_tuple_t_bytes32_t_address_t_uint256_t_bytes32_t_enum$_Operation_$1949_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256__to_t_bytes32_t_address_t_uint256_t_bytes32_t_uint8_t_uint256_t_uint256_t_uint256_t_address_t_address_t_uint256_(headStart_252, value10_253, value9_254, value8_255, value7_256, value6_257, value5_258, value4_259, value3_260, value2_261, value1_262, value0_263) -> tail_264 +// { +// tail_264 := add(headStart_252, 352) +// mstore(headStart_252, value0_263) +// let _413 := 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +// mstore(add(headStart_252, 32), and(value1_262, _413)) +// mstore(add(headStart_252, 64), value2_261) +// mstore(add(headStart_252, 96), value3_260) +// if iszero(lt(value4_259, 3)) +// { +// invalid() +// } +// mstore(add(headStart_252, 128), value4_259) +// mstore(add(headStart_252, 160), value5_258) +// mstore(add(headStart_252, 192), value6_257) +// mstore(add(headStart_252, 224), value7_256) +// mstore(add(headStart_252, 256), and(value8_255, _413)) +// mstore(add(headStart_252, 288), and(value9_254, _413)) +// mstore(add(headStart_252, 320), value10_253) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul index efb846f2..d38025ae 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/abi_example1.yul @@ -458,47 +458,62 @@ // ---- // fullSuite // { +// let _1 := 0x20 +// let _2 := 0 +// let _218 := mload(_2) +// let abi_encode_pos := _1 +// let abi_encode_length_68 := mload(_218) +// mstore(_1, abi_encode_length_68) +// abi_encode_pos := 64 +// let abi_encode_srcPtr := add(_218, _1) +// let abi_encode_i_69 := _2 +// for { +// } +// lt(abi_encode_i_69, abi_encode_length_68) +// { +// abi_encode_i_69 := add(abi_encode_i_69, 1) +// } // { -// let _1 := 0x20 -// let _2 := 0 -// let _485 := mload(_2) -// let abi_encode_pos := _1 -// let abi_encode_length_68 := mload(_485) -// mstore(_1, abi_encode_length_68) -// abi_encode_pos := 64 -// let abi_encode_srcPtr := add(_485, _1) -// let abi_encode_i_69 := _2 +// let _580 := mload(abi_encode_srcPtr) +// let abi_encode_pos_71_672 := abi_encode_pos +// let abi_encode_srcPtr_73_674 := _580 +// let abi_encode_i_74_675 := _2 // for { // } -// lt(abi_encode_i_69, abi_encode_length_68) +// lt(abi_encode_i_74_675, 0x3) // { -// abi_encode_i_69 := add(abi_encode_i_69, 1) +// abi_encode_i_74_675 := add(abi_encode_i_74_675, 1) // } // { -// let _863 := mload(abi_encode_srcPtr) -// let abi_encode_pos_71_971 := abi_encode_pos -// let abi_encode_length_72_972 := 0x3 -// let abi_encode_srcPtr_73_973 := _863 -// let abi_encode_i_74_974 := _2 -// for { -// } -// lt(abi_encode_i_74_974, abi_encode_length_72_972) -// { -// abi_encode_i_74_974 := add(abi_encode_i_74_974, 1) -// } -// { -// mstore(abi_encode_pos_71_971, and(mload(abi_encode_srcPtr_73_973), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) -// abi_encode_srcPtr_73_973 := add(abi_encode_srcPtr_73_973, _1) -// abi_encode_pos_71_971 := add(abi_encode_pos_71_971, _1) -// } -// abi_encode_srcPtr := add(abi_encode_srcPtr, _1) -// abi_encode_pos := add(abi_encode_pos, 0x60) +// mstore(abi_encode_pos_71_672, and(mload(abi_encode_srcPtr_73_674), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) +// abi_encode_srcPtr_73_674 := add(abi_encode_srcPtr_73_674, _1) +// abi_encode_pos_71_672 := add(abi_encode_pos_71_672, _1) // } -// let a, b, c, d := abi_decode_tuple_t_uint256t_uint256t_array$_t_uint256_$dyn_memory_ptrt_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(mload(_1), mload(0x40)) -// sstore(a, b) -// sstore(c, d) -// sstore(_2, abi_encode_pos) +// abi_encode_srcPtr := add(abi_encode_srcPtr, _1) +// abi_encode_pos := add(abi_encode_pos, 0x60) +// } +// let _220 := mload(64) +// let _221 := mload(_1) +// if slt(sub(_220, _221), 128) +// { +// revert(_2, _2) // } +// let abi_decode_offset_64 := calldataload(add(_221, 64)) +// let abi_decode__74 := 0xffffffffffffffff +// if gt(abi_decode_offset_64, abi_decode__74) +// { +// revert(_2, _2) +// } +// let abi_decode_value2_317 := abi_decode_t_array$_t_uint256_$dyn_memory_ptr(add(_221, abi_decode_offset_64), _220) +// let abi_decode_offset_65 := calldataload(add(_221, 96)) +// if gt(abi_decode_offset_65, abi_decode__74) +// { +// revert(_2, _2) +// } +// let abi_decode_value3_318 := abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(add(_221, abi_decode_offset_65), _220) +// sstore(calldataload(_221), calldataload(add(_221, _1))) +// sstore(abi_decode_value2_317, abi_decode_value3_318) +// sstore(_2, abi_encode_pos) // function abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(offset_3, end_4) -> array_5 // { // if iszero(slt(add(offset_3, 0x1f), end_4)) @@ -506,19 +521,15 @@ // revert(array_5, array_5) // } // let length_6 := calldataload(offset_3) -// let array_5_254 := allocateMemory(array_allocation_size_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(length_6)) -// array_5 := array_5_254 -// let dst_7 := array_5_254 -// mstore(array_5_254, length_6) -// let _36 := 0x20 -// let offset_3_256 := add(offset_3, _36) -// dst_7 := add(array_5_254, _36) -// let src_8 := offset_3_256 -// let _38 := 0x40 -// if gt(add(add(offset_3, mul(length_6, _38)), _36), end_4) +// array_5 := allocateMemory(array_allocation_size_t_array$_t_address_$dyn_memory(length_6)) +// let dst_7 := array_5 +// mstore(array_5, length_6) +// let _16 := 0x20 +// dst_7 := add(array_5, _16) +// let src_8 := add(offset_3, _16) +// if gt(add(add(offset_3, mul(length_6, 0x40)), _16), end_4) // { -// let _42 := 0 -// revert(_42, _42) +// revert(0, 0) // } // let i_9 := 0 // for { @@ -528,40 +539,33 @@ // i_9 := add(i_9, 1) // } // { -// mstore(dst_7, abi_decode_t_array$_t_uint256_$2_memory(src_8, end_4)) -// dst_7 := add(dst_7, _36) -// src_8 := add(src_8, _38) -// } -// } -// function abi_decode_t_array$_t_uint256_$2_memory(offset_11, end_12) -> array_13 -// { -// if iszero(slt(add(offset_11, 0x1f), end_12)) -// { -// revert(array_13, array_13) -// } -// let length_14 := 0x2 -// let array_allo__559 := 0x20 -// let array_allo_size_95_605 := 64 -// let array_13_263 := allocateMemory(array_allo_size_95_605) -// array_13 := array_13_263 -// let dst_15 := array_13_263 -// let src_16 := offset_11 -// if gt(add(offset_11, array_allo_size_95_605), end_12) -// { -// let _59 := 0 -// revert(_59, _59) -// } -// let i_17 := 0 -// for { -// } -// lt(i_17, length_14) -// { -// i_17 := add(i_17, 1) -// } -// { -// mstore(dst_15, calldataload(src_16)) -// dst_15 := add(dst_15, array_allo__559) -// src_16 := add(src_16, array_allo__559) +// if iszero(slt(add(src_8, 0x1f), end_4)) +// { +// revert(0, 0) +// } +// let abi_decode_dst_15 := allocateMemory(array_allocation_size_t_array$_t_uint256_$2_memory(0x2)) +// let abi_decode_dst_15_1155 := abi_decode_dst_15 +// let abi_decode_src_16 := src_8 +// let abi_decode__239 := add(src_8, 0x40) +// if gt(abi_decode__239, end_4) +// { +// revert(0, 0) +// } +// let abi_decode_i_17 := 0 +// for { +// } +// lt(abi_decode_i_17, 0x2) +// { +// abi_decode_i_17 := add(abi_decode_i_17, 1) +// } +// { +// mstore(abi_decode_dst_15, calldataload(abi_decode_src_16)) +// abi_decode_dst_15 := add(abi_decode_dst_15, _16) +// abi_decode_src_16 := add(abi_decode_src_16, _16) +// } +// mstore(dst_7, abi_decode_dst_15_1155) +// dst_7 := add(dst_7, _16) +// src_8 := abi_decode__239 // } // } // function abi_decode_t_array$_t_uint256_$dyn_memory_ptr(offset_27, end_28) -> array_29 @@ -571,18 +575,15 @@ // revert(array_29, array_29) // } // let length_30 := calldataload(offset_27) -// let array_29_279 := allocateMemory(array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length_30)) -// array_29 := array_29_279 -// let dst_31 := array_29_279 -// mstore(array_29_279, length_30) -// let _91 := 0x20 -// let offset_27_281 := add(offset_27, _91) -// dst_31 := add(array_29_279, _91) -// let src_32 := offset_27_281 -// if gt(add(add(offset_27, mul(length_30, _91)), _91), end_28) +// array_29 := allocateMemory(array_allocation_size_t_array$_t_address_$dyn_memory(length_30)) +// let dst_31 := array_29 +// mstore(array_29, length_30) +// let _52 := 0x20 +// dst_31 := add(array_29, _52) +// let src_32 := add(offset_27, _52) +// if gt(add(add(offset_27, mul(length_30, _52)), _52), end_28) // { -// let _97 := 0 -// revert(_97, _97) +// revert(0, 0) // } // let i_33 := 0 // for { @@ -593,68 +594,34 @@ // } // { // mstore(dst_31, calldataload(src_32)) -// dst_31 := add(dst_31, _91) -// src_32 := add(src_32, _91) -// } -// } -// function abi_decode_tuple_t_uint256t_uint256t_array$_t_uint256_$dyn_memory_ptrt_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(headStart_58, dataEnd_59) -> value0_60, value1_61, value2, value3 -// { -// if slt(sub(dataEnd_59, headStart_58), 128) -// { -// revert(value2, value2) -// } -// { -// value0_60 := calldataload(add(headStart_58, value2)) -// } -// { -// value1_61 := calldataload(add(headStart_58, 32)) -// } -// { -// let offset_64 := calldataload(add(headStart_58, 64)) -// if gt(offset_64, 0xffffffffffffffff) -// { -// revert(value2, value2) -// } -// value2 := abi_decode_t_array$_t_uint256_$dyn_memory_ptr(add(headStart_58, offset_64), dataEnd_59) -// } -// { -// let offset_65 := calldataload(add(headStart_58, 96)) -// if gt(offset_65, 0xffffffffffffffff) -// { -// revert(value3, value3) -// } -// value3 := abi_decode_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(add(headStart_58, offset_65), dataEnd_59) +// dst_31 := add(dst_31, _52) +// src_32 := add(src_32, _52) // } // } // function allocateMemory(size) -> memPtr // { -// let _199 := 64 -// let memPtr_315 := mload(_199) -// memPtr := memPtr_315 -// let newFreePtr := add(memPtr_315, size) -// if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr_315)) +// memPtr := mload(64) +// let newFreePtr := add(memPtr, size) +// if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) // { -// let _204 := 0 -// revert(_204, _204) +// revert(0, 0) // } -// mstore(_199, newFreePtr) +// mstore(64, newFreePtr) // } -// function array_allocation_size_t_array$_t_array$_t_uint256_$2_memory_$dyn_memory_ptr(length_92) -> size_93 +// function array_allocation_size_t_array$_t_address_$dyn_memory(length_90) -> size_91 // { -// if gt(length_92, 0xffffffffffffffff) +// if gt(length_90, 0xffffffffffffffff) // { -// revert(size_93, size_93) +// revert(0, 0) // } -// let _217 := 0x20 -// size_93 := add(mul(length_92, _217), _217) +// size_91 := add(mul(length_90, 0x20), 0x20) // } -// function array_allocation_size_t_array$_t_uint256_$dyn_memory_ptr(length_98) -> size_99 +// function array_allocation_size_t_array$_t_uint256_$2_memory(length_94) -> size_95 // { -// if gt(length_98, 0xffffffffffffffff) +// if gt(length_94, 0xffffffffffffffff) // { -// revert(size_99, size_99) +// revert(0, 0) // } -// let _234 := 0x20 -// size_99 := add(mul(length_98, _234), _234) +// size_95 := mul(length_94, 0x20) // } // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/aztec.yul b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul new file mode 100644 index 00000000..868c6b01 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/aztec.yul @@ -0,0 +1,410 @@ +/** + * @title Library to validate AZTEC zero-knowledge proofs + * @author Zachary Williamson, AZTEC + * @dev Don't include this as an internal library. This contract uses a static memory table to cache elliptic curve primitives and hashes. + * Calling this internally from another function will lead to memory mutation and undefined behaviour. + * The intended use case is to call this externally via `staticcall`. External calls to OptimizedAZTEC can be treated as pure functions as this contract contains no storage and makes no external calls (other than to precompiles) + * Copyright Spilbury Holdings Ltd 2018. All rights reserved. + * We will be releasing AZTEC as an open-source protocol that provides efficient transaction privacy for Ethereum. + * This will include our bespoke AZTEC decentralized exchange, allowing for cross-asset transfers with full transaction privacy + * and interopability with public decentralized exchanges. + * Stay tuned for updates! + * + * Permission to use as test case in the Solidity compiler granted by the author: + * https://github.com/ethereum/solidity/pull/5713#issuecomment-449042830 +**/ +{ + validateJoinSplit() + // should not get here + mstore(0x00, 404) + revert(0x00, 0x20) + + + function validateJoinSplit() { + mstore(0x80, 7673901602397024137095011250362199966051872585513276903826533215767972925880) // h_x + mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) // h_y + let notes := add(0x04, calldataload(0x04)) + let m := calldataload(0x24) + let n := calldataload(notes) + let gen_order := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 + let challenge := mod(calldataload(0x44), gen_order) + + // validate m <= n + if gt(m, n) { mstore(0x00, 404) revert(0x00, 0x20) } + + // recover k_{public} and calculate k_{public} + let kn := calldataload(sub(calldatasize(), 0xc0)) + + // add kn and m to final hash table + mstore(0x2a0, caller()) + mstore(0x2c0, kn) + mstore(0x2e0, m) + kn := mulmod(sub(gen_order, kn), challenge, gen_order) // we actually want c*k_{public} + hashCommitments(notes, n) + let b := add(0x300, mul(n, 0x80)) + + // Iterate over every note and calculate the blinding factor B_i = \gamma_i^{kBar}h^{aBar}\sigma_i^{-c}. + // We use the AZTEC protocol pairing optimization to reduce the number of pairing comparisons to 1, which adds some minor alterations + for { let i := 0 } lt(i, n) { i := add(i, 0x01) } { + + // Get the calldata index of this note + let noteIndex := add(add(notes, 0x20), mul(i, 0xc0)) + + + let k + let a := calldataload(add(noteIndex, 0x20)) + let c := challenge + + switch eq(add(i, 0x01), n) + case 1 { + k := kn + + // if all notes are input notes, invert k + if eq(m, n) { + k := sub(gen_order, k) + } + } + case 0 { k := calldataload(noteIndex) } + + // Check this commitment is well formed... + validateCommitment(noteIndex, k, a) + + // If i > m then this is an output note. + // Set k = kx_j, a = ax_j, c = cx_j, where j = i - (m+1) + switch gt(add(i, 0x01), m) + case 1 { + + // before we update k, update kn = \sum_{i=0}^{m-1}k_i - \sum_{i=m}^{n-1}k_i + kn := addmod(kn, sub(gen_order, k), gen_order) + let x := mod(mload(0x00), gen_order) + k := mulmod(k, x, gen_order) + a := mulmod(a, x, gen_order) + c := mulmod(challenge, x, gen_order) + + // calculate x_{j+1} + mstore(0x00, keccak256(0x00, 0x20)) + } + case 0 { + + // nothing to do here except update kn = \sum_{i=0}^{m-1}k_i - \sum_{i=m}^{n-1}k_i + kn := addmod(kn, k, gen_order) + } + + calldatacopy(0xe0, add(noteIndex, 0x80), 0x40) + calldatacopy(0x20, add(noteIndex, 0x40), 0x40) + mstore(0x120, sub(gen_order, c)) + mstore(0x60, k) + mstore(0xc0, a) + + // Using call instead of staticcall here to make it work on all targets. + let result := call(gas(), 7, 0, 0xe0, 0x60, 0x1a0, 0x40) + result := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x120, 0x40)) + result := and(result, call(gas(), 7, 0, 0x80, 0x60, 0x160, 0x40)) + + result := and(result, call(gas(), 6, 0, 0x120, 0x80, 0x160, 0x40)) + + result := and(result, call(gas(), 6, 0, 0x160, 0x80, b, 0x40)) + + if eq(i, m) { + mstore(0x260, mload(0x20)) + mstore(0x280, mload(0x40)) + mstore(0x1e0, mload(0xe0)) + mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) + } + + if gt(i, m) { + mstore(0x60, c) + result := and(result, call(gas(), 7, 0, 0x20, 0x60, 0x220, 0x40)) + + result := and(result, call(gas(), 6, 0, 0x220, 0x80, 0x260, 0x40)) + result := and(result, call(gas(), 6, 0, 0x1a0, 0x80, 0x1e0, 0x40)) + } + + if iszero(result) { mstore(0x00, 400) revert(0x00, 0x20) } + b := add(b, 0x40) // increase B pointer by 2 words + } + + if lt(m, n) { + validatePairing(0x64) + } + + let expected := mod(keccak256(0x2a0, sub(b, 0x2a0)), gen_order) + if iszero(eq(expected, challenge)) { + + // No! Bad! No soup for you! + mstore(0x00, 404) + revert(0x00, 0x20) + } + + // Great! All done. This is a valid proof so return ```true``` + mstore(0x00, 0x01) + return(0x00, 0x20) + } + + function validatePairing(t2) { + let field_order := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 + let t2_x_1 := calldataload(t2) + let t2_x_2 := calldataload(add(t2, 0x20)) + let t2_y_1 := calldataload(add(t2, 0x40)) + let t2_y_2 := calldataload(add(t2, 0x60)) + + // check provided setup pubkey is not zero or g2 + if or(or(or(or(or(or(or( + iszero(t2_x_1), + iszero(t2_x_2)), + iszero(t2_y_1)), + iszero(t2_y_2)), + eq(t2_x_1, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed)), + eq(t2_x_2, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2)), + eq(t2_y_1, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa)), + eq(t2_y_2, 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b)) + { + mstore(0x00, 400) + revert(0x00, 0x20) + } + + mstore(0x20, mload(0x1e0)) // sigma accumulator x + mstore(0x40, mload(0x200)) // sigma accumulator y + mstore(0x80, 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed) + mstore(0x60, 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2) + mstore(0xc0, 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa) + mstore(0xa0, 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b) + mstore(0xe0, mload(0x260)) // gamma accumulator x + mstore(0x100, mload(0x280)) // gamma accumulator y + mstore(0x140, t2_x_1) + mstore(0x120, t2_x_2) + mstore(0x180, t2_y_1) + mstore(0x160, t2_y_2) + + let success := call(gas(), 8, 0, 0x20, 0x180, 0x20, 0x20) + + if or(iszero(success), iszero(mload(0x20))) { + mstore(0x00, 400) + revert(0x00, 0x20) + } + } + + function validateCommitment(note, k, a) { + let gen_order := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 + let field_order := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 + let gammaX := calldataload(add(note, 0x40)) + let gammaY := calldataload(add(note, 0x60)) + let sigmaX := calldataload(add(note, 0x80)) + let sigmaY := calldataload(add(note, 0xa0)) + if iszero( + and( + and( + and( + eq(mod(a, gen_order), a), // a is modulo generator order? + gt(a, 1) // can't be 0 or 1 either! + ), + and( + eq(mod(k, gen_order), k), // k is modulo generator order? + gt(k, 1) // and not 0 or 1 + ) + ), + and( + eq( // y^2 ?= x^3 + 3 + addmod(mulmod(mulmod(sigmaX, sigmaX, field_order), sigmaX, field_order), 3, field_order), + mulmod(sigmaY, sigmaY, field_order) + ), + eq( // y^2 ?= x^3 + 3 + addmod(mulmod(mulmod(gammaX, gammaX, field_order), gammaX, field_order), 3, field_order), + mulmod(gammaY, gammaY, field_order) + ) + ) + ) + ) { + mstore(0x00, 400) + revert(0x00, 0x20) + } + } + + function hashCommitments(notes, n) { + for { let i := 0 } lt(i, n) { i := add(i, 0x01) } { + let index := add(add(notes, mul(i, 0xc0)), 0x60) + calldatacopy(add(0x300, mul(i, 0x80)), index, 0x80) + } + mstore(0x00, keccak256(0x300, mul(n, 0x80))) + } +} +// ---- +// fullSuite +// { +// let validateJo__6 := 0x80 +// mstore(validateJo__6, 7673901602397024137095011250362199966051872585513276903826533215767972925880) +// mstore(0xa0, 8489654445897228341090914135473290831551238522473825886865492707826370766375) +// let validateJo__10 := calldataload(0x04) +// let validateJo_notes := add(0x04, validateJo__10) +// let validateJo_m := calldataload(0x24) +// let validateJo_n := calldataload(validateJo_notes) +// let validateJo_gen_order := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 +// let validateJo_challenge := mod(calldataload(0x44), validateJo_gen_order) +// if gt(validateJo_m, validateJo_n) +// { +// mstore(0x00, 404) +// revert(0x00, 0x20) +// } +// let validateJo_kn := calldataload(add(calldatasize(), 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40)) +// let validateJo__24 := 0x2a0 +// mstore(validateJo__24, caller()) +// mstore(0x2c0, validateJo_kn) +// mstore(0x2e0, validateJo_m) +// validateJo_kn := mulmod(sub(validateJo_gen_order, validateJo_kn), validateJo_challenge, validateJo_gen_order) +// hashCommitments(validateJo_notes, validateJo_n) +// let validateJo_b := add(0x300, mul(validateJo_n, validateJo__6)) +// let validateJo_i := 0 +// let validateJo_i_1306 := validateJo_i +// for { +// } +// lt(validateJo_i, validateJo_n) +// { +// validateJo_i := add(validateJo_i, 0x01) +// } +// { +// let validateJo__34 := 0x20 +// let validateJo__351 := add(validateJo__10, mul(validateJo_i, 0xc0)) +// let validateJo_noteIndex := add(validateJo__351, 0x24) +// let validateJo_k := validateJo_i_1306 +// let validateJo_a := calldataload(add(validateJo__351, 0x44)) +// let validateJo_c := validateJo_challenge +// let validateJo__39 := add(validateJo_i, 0x01) +// switch eq(validateJo__39, validateJo_n) +// case 1 { +// validateJo_k := validateJo_kn +// if eq(validateJo_m, validateJo_n) +// { +// validateJo_k := sub(validateJo_gen_order, validateJo_kn) +// } +// } +// case 0 { +// validateJo_k := calldataload(validateJo_noteIndex) +// } +// validateCommitment(validateJo_noteIndex, validateJo_k, validateJo_a) +// switch gt(validateJo__39, validateJo_m) +// case 1 { +// validateJo_kn := addmod(validateJo_kn, sub(validateJo_gen_order, validateJo_k), validateJo_gen_order) +// let validateJo_x := mod(mload(validateJo_i_1306), validateJo_gen_order) +// validateJo_k := mulmod(validateJo_k, validateJo_x, validateJo_gen_order) +// validateJo_a := mulmod(validateJo_a, validateJo_x, validateJo_gen_order) +// validateJo_c := mulmod(validateJo_challenge, validateJo_x, validateJo_gen_order) +// mstore(validateJo_i_1306, keccak256(validateJo_i_1306, validateJo__34)) +// } +// case 0 { +// validateJo_kn := addmod(validateJo_kn, validateJo_k, validateJo_gen_order) +// } +// let validateJo__52 := 0x40 +// calldatacopy(0xe0, add(validateJo__351, 164), validateJo__52) +// calldatacopy(validateJo__34, add(validateJo__351, 100), validateJo__52) +// let validateJo__61 := 0x120 +// mstore(validateJo__61, sub(validateJo_gen_order, validateJo_c)) +// let validateJo__62 := 0x60 +// mstore(validateJo__62, validateJo_k) +// mstore(0xc0, validateJo_a) +// let validateJo__65 := 0x1a0 +// let validateJo_result := call(gas(), 7, validateJo_i_1306, 0xe0, validateJo__62, validateJo__65, validateJo__52) +// let validateJo_result_303 := and(validateJo_result, call(gas(), 7, validateJo_i_1306, validateJo__34, validateJo__62, validateJo__61, validateJo__52)) +// let validateJo__80 := 0x160 +// let validateJo_result_304 := and(validateJo_result_303, call(gas(), 7, validateJo_i_1306, validateJo__6, validateJo__62, validateJo__80, validateJo__52)) +// let validateJo_result_305 := and(validateJo_result_304, call(gas(), 6, validateJo_i_1306, validateJo__61, validateJo__6, validateJo__80, validateJo__52)) +// validateJo_result := and(validateJo_result_305, call(gas(), 6, validateJo_i_1306, validateJo__80, validateJo__6, validateJo_b, validateJo__52)) +// if eq(validateJo_i, validateJo_m) +// { +// mstore(0x260, mload(validateJo__34)) +// mstore(0x280, mload(validateJo__52)) +// mstore(0x1e0, mload(0xe0)) +// mstore(0x200, sub(0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47, mload(0x100))) +// } +// if gt(validateJo_i, validateJo_m) +// { +// mstore(validateJo__62, validateJo_c) +// let validateJo__120 := 0x220 +// let validateJo_result_307 := and(validateJo_result, call(gas(), 7, validateJo_i_1306, validateJo__34, validateJo__62, validateJo__120, validateJo__52)) +// let validateJo_result_308 := and(validateJo_result_307, call(gas(), 6, validateJo_i_1306, validateJo__120, validateJo__6, 0x260, validateJo__52)) +// validateJo_result := and(validateJo_result_308, call(gas(), 6, validateJo_i_1306, validateJo__65, validateJo__6, 0x1e0, validateJo__52)) +// } +// if iszero(validateJo_result) +// { +// mstore(validateJo_i_1306, 400) +// revert(validateJo_i_1306, validateJo__34) +// } +// validateJo_b := add(validateJo_b, validateJo__52) +// } +// if lt(validateJo_m, validateJo_n) +// { +// validatePairing(0x64) +// } +// if iszero(eq(mod(keccak256(validateJo__24, add(validateJo_b, 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd60)), validateJo_gen_order), validateJo_challenge)) +// { +// mstore(validateJo_i_1306, 404) +// revert(validateJo_i_1306, 0x20) +// } +// mstore(validateJo_i_1306, 0x01) +// return(validateJo_i_1306, 0x20) +// mstore(validateJo_i_1306, 404) +// revert(validateJo_i_1306, 0x20) +// function validatePairing(t2) +// { +// let t2_x_1 := calldataload(t2) +// let _165 := 0x20 +// let t2_x_2 := calldataload(add(t2, _165)) +// let t2_y_1 := calldataload(add(t2, 0x40)) +// let t2_y_2 := calldataload(add(t2, 0x60)) +// let _171 := 0x90689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b +// let _173 := 0x12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa +// let _175 := 0x198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2 +// let _177 := 0x1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed +// if or(or(or(or(or(or(or(iszero(t2_x_1), iszero(t2_x_2)), iszero(t2_y_1)), iszero(t2_y_2)), eq(t2_x_1, _177)), eq(t2_x_2, _175)), eq(t2_y_1, _173)), eq(t2_y_2, _171)) +// { +// mstore(0x00, 400) +// revert(0x00, _165) +// } +// mstore(_165, mload(0x1e0)) +// mstore(0x40, mload(0x200)) +// mstore(0x80, _177) +// mstore(0x60, _175) +// mstore(0xc0, _173) +// mstore(0xa0, _171) +// mstore(0xe0, mload(0x260)) +// mstore(0x100, mload(0x280)) +// mstore(0x140, t2_x_1) +// mstore(0x120, t2_x_2) +// let _216 := 0x180 +// mstore(_216, t2_y_1) +// mstore(0x160, t2_y_2) +// let success := call(gas(), 8, 0, _165, _216, _165, _165) +// if or(iszero(success), iszero(mload(_165))) +// { +// mstore(0, 400) +// revert(0, _165) +// } +// } +// function validateCommitment(note, k_1, a_2) +// { +// let gen_order_3 := 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001 +// let field_order_4 := 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 +// let gammaX := calldataload(add(note, 0x40)) +// let gammaY := calldataload(add(note, 0x60)) +// let sigmaX := calldataload(add(note, 0x80)) +// let sigmaY := calldataload(add(note, 0xa0)) +// if iszero(and(and(and(eq(mod(a_2, gen_order_3), a_2), gt(a_2, 1)), and(eq(mod(k_1, gen_order_3), k_1), gt(k_1, 1))), and(eq(addmod(mulmod(mulmod(sigmaX, sigmaX, field_order_4), sigmaX, field_order_4), 3, field_order_4), mulmod(sigmaY, sigmaY, field_order_4)), eq(addmod(mulmod(mulmod(gammaX, gammaX, field_order_4), gammaX, field_order_4), 3, field_order_4), mulmod(gammaY, gammaY, field_order_4))))) +// { +// mstore(0x00, 400) +// revert(0x00, 0x20) +// } +// } +// function hashCommitments(notes_5, n_6) +// { +// let i_7 := 0 +// for { +// } +// lt(i_7, n_6) +// { +// i_7 := add(i_7, 0x01) +// } +// { +// calldatacopy(add(0x300, mul(i_7, 0x80)), add(add(notes_5, mul(i_7, 0xc0)), 0x60), 0x80) +// } +// mstore(0, keccak256(0x300, mul(n_6, 0x80))) +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/medium.yul b/test/libyul/yulOptimizerTests/fullSuite/medium.yul index fbe243d4..1d07cd03 100644 --- a/test/libyul/yulOptimizerTests/fullSuite/medium.yul +++ b/test/libyul/yulOptimizerTests/fullSuite/medium.yul @@ -19,13 +19,10 @@ // ---- // fullSuite // { -// { -// let _1 := 0x20 -// let allocate__19 := 0x40 -// mstore(allocate__19, add(mload(allocate__19), _1)) -// let allocate_p_24_41 := mload(allocate__19) -// mstore(allocate__19, add(allocate_p_24_41, allocate__19)) -// mstore(add(allocate_p_24_41, 96), 2) -// mstore(allocate__19, _1) -// } +// let allocate__19 := 0x40 +// mstore(allocate__19, add(mload(allocate__19), 0x20)) +// let allocate_p_35_39 := mload(allocate__19) +// mstore(allocate__19, add(allocate_p_35_39, allocate__19)) +// mstore(add(allocate_p_35_39, 96), 2) +// mstore(allocate__19, 0x20) // } diff --git a/test/libyul/yulOptimizerTests/fullSuite/ssaReverse.yul b/test/libyul/yulOptimizerTests/fullSuite/ssaReverse.yul new file mode 100644 index 00000000..204b444e --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/ssaReverse.yul @@ -0,0 +1,62 @@ +{ + // This is an abi decode function with the SSA transform applied once. + // This test is supposed to verify that the SSA transform is correctly reversed by the full suite. + function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 + { + if iszero(slt(add(offset_12, 0x1f), end_13)) + { + revert(0, 0) + } + let length_15_1 := calldataload(offset_12) + length_15 := length_15_1 + if gt(length_15_1, 0xffffffffffffffff) + { + revert(0, 0) + } + let arrayPos_14_2 := add(offset_12, 0x20) + arrayPos_14 := arrayPos_14_2 + if gt(add(arrayPos_14_2, mul(length_15_1, 0x1)), end_13) + { + revert(0, 0) + } + } + + // prevent inlining + let a,b := abi_decode_t_bytes_calldata_ptr(mload(0),mload(1)) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + a,b := abi_decode_t_bytes_calldata_ptr(a,b) + mstore(a,b) +} +// ---- +// fullSuite +// { +// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1)) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// a, b := abi_decode_t_bytes_calldata_ptr(a, b) +// mstore(a, b) +// function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 +// { +// if iszero(slt(add(offset_12, 0x1f), end_13)) +// { +// revert(0, 0) +// } +// length_15 := calldataload(offset_12) +// if gt(length_15, 0xffffffffffffffff) +// { +// revert(0, 0) +// } +// arrayPos_14 := add(offset_12, 0x20) +// if gt(add(add(offset_12, length_15), 0x20), end_13) +// { +// revert(0, 0) +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/fullSuite/ssaReverseComplex.yul b/test/libyul/yulOptimizerTests/fullSuite/ssaReverseComplex.yul new file mode 100644 index 00000000..2e178f31 --- /dev/null +++ b/test/libyul/yulOptimizerTests/fullSuite/ssaReverseComplex.yul @@ -0,0 +1,23 @@ +{ + let a := mload(0) + let b := mload(1) + if mload(2) { + a := mload(b) + b := mload(a) + a := mload(b) + b := mload(a) + } + mstore(a, b) +} +// ---- +// fullSuite +// { +// let a := mload(0) +// let b := mload(1) +// if mload(2) +// { +// a := mload(mload(mload(b))) +// b := mload(a) +// } +// mstore(a, b) +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul b/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul new file mode 100644 index 00000000..42e8a48e --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/already_grouped.yul @@ -0,0 +1,17 @@ +{ + { + let x := 2 + } + function f() -> y { y := 8 } +} +// ---- +// functionGrouper +// { +// { +// let x := 2 +// } +// function f() -> y +// { +// y := 8 +// } +// } diff --git a/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul b/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul new file mode 100644 index 00000000..0abb5d87 --- /dev/null +++ b/test/libyul/yulOptimizerTests/functionGrouper/grouped_but_not_ordered.yul @@ -0,0 +1,19 @@ +{ + function f() -> y { y := 8 } + { + let x := 2 + } +} +// ---- +// functionGrouper +// { +// { +// { +// let x := 2 +// } +// } +// function f() -> y +// { +// y := 8 +// } +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul index dbd1ee63..3160381f 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for1.yul @@ -1,5 +1,5 @@ { - let a := 1 + let a := caller() for { pop(a) } a { pop(a) } { pop(a) } @@ -7,15 +7,15 @@ // ---- // rematerialiser // { -// let a := 1 +// let a := caller() // for { -// pop(1) +// pop(caller()) // } -// 1 +// caller() // { -// pop(1) +// pop(caller()) // } // { -// pop(1) +// pop(caller()) // } // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul index 6a52e045..eb092e95 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for2.yul @@ -1,7 +1,7 @@ { - let a := 1 + let a := caller() for { pop(a) } a { pop(a) } { - a := 7 + a := address() let c := a } let x := a @@ -9,17 +9,17 @@ // ---- // rematerialiser // { -// let a := 1 +// let a := caller() // for { -// pop(1) +// pop(caller()) // } // a // { -// pop(7) +// pop(address()) // } // { -// a := 7 -// let c := 7 +// a := address() +// let c := address() // } // 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 index fc816419..e7c689ca 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init1.yul @@ -1,6 +1,6 @@ { let b := 0 - for { let a := 1 pop(a) } a { pop(a) } { + for { let a := caller() pop(a) } a { pop(a) } { b := 1 pop(a) } } @@ -9,15 +9,15 @@ // { // let b := 0 // for { -// let a := 1 -// pop(1) +// let a := caller() +// pop(caller()) // } -// 1 +// caller() // { -// pop(1) +// pop(caller()) // } // { // b := 1 -// pop(1) +// pop(caller()) // } // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul index 3d916890..80ee9233 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_for_declared_in_init2.yul @@ -1,6 +1,6 @@ { let b := 0 - for { let a := 1 pop(a) } lt(a, 0) { pop(a) a := add(a, 3) } { + for { let a := caller() pop(a) } lt(a, 0) { pop(a) a := add(a, 3) } { b := 1 pop(a) } } @@ -9,8 +9,8 @@ // { // let b := 0 // for { -// let a := 1 -// pop(1) +// let a := caller() +// pop(caller()) // } // lt(a, 0) // { diff --git a/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul b/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul index c148c2f2..2aff06d4 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/branches_if.yul @@ -1,18 +1,18 @@ { - let a := 1 - let b := 2 + let a := caller() + let b := address() if b { pop(b) b := a } let c := b } // ---- // rematerialiser // { -// let a := 1 -// let b := 2 -// if 2 +// let a := caller() +// let b := address() +// if address() // { -// pop(2) -// b := 1 +// pop(address()) +// b := caller() // } // let c := b // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/cheap_caller.yul b/test/libyul/yulOptimizerTests/rematerialiser/cheap_caller.yul new file mode 100644 index 00000000..7e99e428 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/cheap_caller.yul @@ -0,0 +1,16 @@ +{ + // The caller opcode is cheap, so inline it, + // no matter how often it is used + let a := caller() + mstore(a, a) + mstore(add(a, a), mload(a)) + sstore(a, sload(a)) +} +// ---- +// rematerialiser +// { +// let a := caller() +// mstore(caller(), caller()) +// mstore(add(caller(), caller()), mload(caller())) +// sstore(caller(), sload(caller())) +// } 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 deleted file mode 100644 index d95dc1fc..00000000 --- a/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code2.yul +++ /dev/null @@ -1,10 +0,0 @@ -{ - 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/do_not_remat_large_amounts_of_code1.yul b/test/libyul/yulOptimizerTests/rematerialiser/do_remat_large_amounts_of_code_if_used_once.yul index 016fa0d7..e464d404 100644 --- a/test/libyul/yulOptimizerTests/rematerialiser/do_not_remat_large_amounts_of_code1.yul +++ b/test/libyul/yulOptimizerTests/rematerialiser/do_remat_large_amounts_of_code_if_used_once.yul @@ -6,5 +6,5 @@ // rematerialiser // { // let x := add(mul(calldataload(2), calldataload(4)), mul(2, calldatasize())) -// let b := x +// let b := add(mul(calldataload(2), calldataload(4)), mul(2, calldatasize())) // } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/expression.yul b/test/libyul/yulOptimizerTests/rematerialiser/expression.yul deleted file mode 100644 index a801677d..00000000 --- a/test/libyul/yulOptimizerTests/rematerialiser/expression.yul +++ /dev/null @@ -1,10 +0,0 @@ -{ - 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/large_constant.yul b/test/libyul/yulOptimizerTests/rematerialiser/large_constant.yul new file mode 100644 index 00000000..9c7c66f1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/large_constant.yul @@ -0,0 +1,12 @@ +{ + // Constants cost depending on their magnitude. + // Do not rematerialize large constants. + let a := 0xffffffffffffffffffffff + mstore(a, a) +} +// ---- +// rematerialiser +// { +// let a := 0xffffffffffffffffffffff +// mstore(a, a) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/large_constant_used_once.yul b/test/libyul/yulOptimizerTests/rematerialiser/large_constant_used_once.yul new file mode 100644 index 00000000..b8a861aa --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/large_constant_used_once.yul @@ -0,0 +1,13 @@ +{ + // Constants cost depending on their magnitude. + // Do not rematerialize large constants, + // unless they are used exactly once. + let a := 0xffffffffffffffffffffff + mstore(0, a) +} +// ---- +// rematerialiser +// { +// let a := 0xffffffffffffffffffffff +// mstore(0, 0xffffffffffffffffffffff) +// } diff --git a/test/libyul/yulOptimizerTests/rematerialiser/medium_sized_constant.yul b/test/libyul/yulOptimizerTests/rematerialiser/medium_sized_constant.yul new file mode 100644 index 00000000..98cdbd09 --- /dev/null +++ b/test/libyul/yulOptimizerTests/rematerialiser/medium_sized_constant.yul @@ -0,0 +1,25 @@ +{ + // Constants cost depending on their magnitude. + // Rematerialize small constants only if they are + // not used too often. + // b is used 5 times + let b := 2 + mstore(b, b) + mstore(add(b, b), b) + // a is used 7 times + let a := 1 + mstore(a, a) + mstore(add(a, a), a) + mstore(a, mload(a)) +} +// ---- +// rematerialiser +// { +// let b := 2 +// mstore(2, 2) +// mstore(add(2, 2), 2) +// let a := 1 +// mstore(a, a) +// mstore(add(a, a), a) +// mstore(a, mload(a)) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul b/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul new file mode 100644 index 00000000..18498e61 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/for_loop.yul @@ -0,0 +1,36 @@ +{ + for { + let a := mload(0) + let b := mload(1) + } + lt(mload(a),mload(b)) + { + a := mload(b) + } + { + b := mload(a) + a := mload(b) + a := mload(b) + a := mload(b) + b := mload(a) + } +} +// ---- +// ssaAndBack +// { +// for { +// let a := mload(0) +// let b := mload(1) +// } +// lt(mload(a), mload(b)) +// { +// a := mload(b) +// } +// { +// let b_3 := mload(a) +// pop(mload(b_3)) +// pop(mload(b_3)) +// let a_6 := mload(b_3) +// b := mload(a_6) +// } +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul new file mode 100644 index 00000000..23c433d1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign.yul @@ -0,0 +1,18 @@ +{ + let a := mload(0) + a := mload(1) + a := mload(2) + a := mload(3) + a := mload(4) + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// pop(mload(0)) +// pop(mload(1)) +// pop(mload(2)) +// pop(mload(3)) +// let a_5 := mload(4) +// mstore(a_5, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul new file mode 100644 index 00000000..fd5981ef --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_if.yul @@ -0,0 +1,22 @@ +{ + let a := mload(0) + if mload(1) + { + a := mload(1) + a := mload(2) + a := mload(3) + } + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// if mload(1) +// { +// pop(mload(1)) +// pop(mload(2)) +// a := mload(3) +// } +// mstore(a, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul new file mode 100644 index 00000000..b0b3efb5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_if.yul @@ -0,0 +1,25 @@ +{ + let a := mload(0) + let b := mload(1) + if mload(2) { + a := mload(b) + b := mload(a) + a := mload(b) + b := mload(a) + } + mstore(a, b) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// let b := mload(1) +// if mload(2) +// { +// let a_3 := mload(b) +// let b_4 := mload(a_3) +// a := mload(b_4) +// b := mload(a) +// } +// mstore(a, b) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul new file mode 100644 index 00000000..50f56b87 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_multi_var_switch.yul @@ -0,0 +1,38 @@ +{ + let a := mload(0) + let b := mload(1) + switch mload(2) + case 0 { + a := mload(b) + b := mload(a) + a := mload(b) + b := mload(a) + } + default { + b := mload(a) + a := mload(b) + b := mload(a) + a := mload(b) + } + mstore(a, b) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// let b := mload(1) +// switch mload(2) +// case 0 { +// let a_3 := mload(b) +// let b_4 := mload(a_3) +// a := mload(b_4) +// b := mload(a) +// } +// default { +// let b_7 := mload(a) +// let a_8 := mload(b_7) +// b := mload(a_8) +// a := mload(b) +// } +// mstore(a, b) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul new file mode 100644 index 00000000..1efbbde7 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/multi_assign_switch.yul @@ -0,0 +1,32 @@ +{ + let a := mload(0) + switch mload(1) + case 0 { + a := mload(1) + a := mload(2) + a := mload(3) + } + default { + a := mload(4) + a := mload(5) + a := mload(6) + } + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// switch mload(1) +// case 0 { +// pop(mload(1)) +// pop(mload(2)) +// a := mload(3) +// } +// default { +// pop(mload(4)) +// pop(mload(5)) +// a := mload(6) +// } +// mstore(a, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul b/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul new file mode 100644 index 00000000..912940c5 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/simple.yul @@ -0,0 +1,12 @@ +{ + let a := mload(0) + a := mload(1) + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// pop(mload(0)) +// let a_2 := mload(1) +// mstore(a_2, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul new file mode 100644 index 00000000..5185245c --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_if.yul @@ -0,0 +1,18 @@ +{ + let a := mload(0) + if mload(1) + { + a := mload(1) + } + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// if mload(1) +// { +// a := mload(1) +// } +// mstore(a, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul new file mode 100644 index 00000000..e0e53b3f --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/single_assign_switch.yul @@ -0,0 +1,24 @@ +{ + let a := mload(0) + switch mload(1) + case 0 { + a := mload(1) + } + default { + a := mload(2) + } + mstore(a, 0) +} +// ---- +// ssaAndBack +// { +// let a := mload(0) +// switch mload(1) +// case 0 { +// a := mload(1) +// } +// default { +// a := mload(2) +// } +// mstore(a, 0) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul b/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul new file mode 100644 index 00000000..d2ba6471 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/ssaReverse.yul @@ -0,0 +1,45 @@ +{ + function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 + { + if iszero(slt(add(offset_12, 0x1f), end_13)) + { + revert(0, 0) + } + length_15 := calldataload(offset_12) + if gt(length_15, 0xffffffffffffffff) + { + revert(0, 0) + } + arrayPos_14 := add(offset_12, 0x20) + if gt(add(add(offset_12, length_15), 0x20), end_13) + { + revert(0, 0) + } + } + // prevent removal of the function + let a,b := abi_decode_t_bytes_calldata_ptr(mload(0),mload(1)) + mstore(a,b) +} +// ---- +// ssaAndBack +// { +// function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 +// { +// if iszero(slt(add(offset_12, 0x1f), end_13)) +// { +// revert(arrayPos_14, arrayPos_14) +// } +// length_15 := calldataload(offset_12) +// if gt(length_15, 0xffffffffffffffff) +// { +// revert(arrayPos_14, arrayPos_14) +// } +// arrayPos_14 := add(offset_12, 0x20) +// if gt(add(add(offset_12, length_15), 0x20), end_13) +// { +// revert(0, 0) +// } +// } +// let a, b := abi_decode_t_bytes_calldata_ptr(mload(0), mload(1)) +// mstore(a, b) +// } diff --git a/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul b/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul new file mode 100644 index 00000000..9f2a046e --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaAndBack/two_vars.yul @@ -0,0 +1,20 @@ +{ + let a := mload(0) + let b := mload(a) + a := mload(b) + b := mload(a) + a := mload(b) + b := mload(a) + mstore(a, b) +} +// ---- +// ssaAndBack +// { +// let a_1 := mload(0) +// let b_2 := mload(a_1) +// let a_3 := mload(b_2) +// let b_4 := mload(a_3) +// let a_5 := mload(b_4) +// let b_6 := mload(a_5) +// mstore(a_5, b_6) +// } diff --git a/test/libyul/yulOptimizerTests/ssaReverser/abi_example.yul b/test/libyul/yulOptimizerTests/ssaReverser/abi_example.yul new file mode 100644 index 00000000..923a42ba --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaReverser/abi_example.yul @@ -0,0 +1,44 @@ +{ + function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 + { + if iszero(slt(add(offset_12, 0x1f), end_13)) + { + revert(0, 0) + } + let length_15_1 := calldataload(offset_12) + length_15 := length_15_1 + if gt(length_15_1, 0xffffffffffffffff) + { + revert(0, 0) + } + let arrayPos_14_2 := add(offset_12, 0x20) + arrayPos_14 := arrayPos_14_2 + if gt(add(arrayPos_14_2, mul(length_15_1, 0x1)), end_13) + { + revert(0, 0) + } + } +} +// ---- +// ssaReverser +// { +// function abi_decode_t_bytes_calldata_ptr(offset_12, end_13) -> arrayPos_14, length_15 +// { +// if iszero(slt(add(offset_12, 0x1f), end_13)) +// { +// revert(0, 0) +// } +// length_15 := calldataload(offset_12) +// let length_15_1 := length_15 +// if gt(length_15_1, 0xffffffffffffffff) +// { +// revert(0, 0) +// } +// arrayPos_14 := add(offset_12, 0x20) +// let arrayPos_14_2 := arrayPos_14 +// if gt(add(arrayPos_14_2, mul(length_15_1, 0x1)), end_13) +// { +// revert(0, 0) +// } +// } +// } diff --git a/test/libyul/yulOptimizerTests/ssaReverser/simple.yul b/test/libyul/yulOptimizerTests/ssaReverser/simple.yul new file mode 100644 index 00000000..eba1f5f1 --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaReverser/simple.yul @@ -0,0 +1,14 @@ +{ + let a := mload(1) + let a_1 := mload(0) + a := a_1 + mstore(a_1, 0) +} +// ---- +// ssaReverser +// { +// let a := mload(1) +// a := mload(0) +// let a_1 := a +// mstore(a_1, 0) +// } |