From b50362042e3d9597bad0a8db5d725b8c023dc555 Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 12 May 2015 21:27:04 +0200 Subject: Known state: store tags on stack as unions. --- libsolidity/SolidityOptimizer.cpp | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'libsolidity/SolidityOptimizer.cpp') diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index efc9316b..ce43887e 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -315,6 +315,49 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) BOOST_CHECK_EQUAL(1, numSHA3s); } +BOOST_AUTO_TEST_CASE(store_tags_as_unions) +{ + // This calls the same function from two sources and both calls have a certain sha3 on + // the stack at the same position. + // Without storing tags as unions, the return from the shared function would not know where to + // jump and thus all jumpdests are forced to clear their state and we do not know about the + // sha3 anymore. + // Note that, for now, this only works if the functions have the same number of return + // parameters since otherwise, the return jump addresses are at different stack positions + // which triggers the "unknown jump target" situation. + char const* sourceCode = R"( + contract test { + bytes32 data; + function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { + r_d = sha3(y); + shared(y); + r_d = sha3(y); + r_a = 5; + } + function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) { + r_d = sha3(y); + shared(y); + r_d = bytes32(uint(sha3(y)) + 2); + r_a = 7; + } + function shared(bytes32 y) internal { + data = sha3(y); + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("f()", 7, "abc"); + + m_optimize = true; + bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test"); + size_t numSHA3s = 0; + eth::eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) { + if (_instr == eth::Instruction::SHA3) + numSHA3s++; + }); + BOOST_CHECK_EQUAL(2, numSHA3s); +} + BOOST_AUTO_TEST_CASE(cse_intermediate_swap) { eth::KnownState state; -- cgit v1.2.3 From 7d5bebd464b3ad8a4a66865c9306f7c9c896a06d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 15 May 2015 11:46:32 +0200 Subject: Disable test. --- libsolidity/SolidityOptimizer.cpp | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'libsolidity/SolidityOptimizer.cpp') diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index ce43887e..e8cc2d5b 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -884,18 +884,21 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::SHA3))); } -BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) -{ - eth::KnownState state = createInitialState(AssemblyItems{ - u256(0x12), - u256(0x20), - Instruction::ADD - }); - AssemblyItems input{ - u256(0x12 + 0x20) - }; - checkCSE(input, AssemblyItems{Instruction::DUP1}, state); -} +// ****************************** +// DISABLED DUE TO FAILURE ON OSX +// ****************************** +//BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) +//{ +// eth::KnownState state = createInitialState(AssemblyItems{ +// u256(0x12), +// u256(0x20), +// Instruction::ADD +// }); +// AssemblyItems input{ +// u256(0x12 + 0x20) +// }; +// checkCSE(input, AssemblyItems{Instruction::DUP1}, state); +//} BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack) { -- cgit v1.2.3 From 5f8a5f672d64a626f59f3f190ab835773faa8283 Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 15 May 2015 13:25:44 +0200 Subject: Store copied assembly items in test. Fixes OSX issues. --- libsolidity/SolidityOptimizer.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'libsolidity/SolidityOptimizer.cpp') diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index e8cc2d5b..744fc48a 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -97,7 +97,7 @@ public: { eth::KnownState state; for (auto const& item: addDummyLocations(_input)) - state.feedItem(item); + state.feedItem(item, true); return state; } @@ -884,21 +884,18 @@ BOOST_AUTO_TEST_CASE(cse_sha3_twice_same_content_noninterfering_store_in_between BOOST_CHECK_EQUAL(1, count(output.begin(), output.end(), AssemblyItem(Instruction::SHA3))); } -// ****************************** -// DISABLED DUE TO FAILURE ON OSX -// ****************************** -//BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) -//{ -// eth::KnownState state = createInitialState(AssemblyItems{ -// u256(0x12), -// u256(0x20), -// Instruction::ADD -// }); -// AssemblyItems input{ -// u256(0x12 + 0x20) -// }; -// checkCSE(input, AssemblyItems{Instruction::DUP1}, state); -//} +BOOST_AUTO_TEST_CASE(cse_with_initially_known_stack) +{ + eth::KnownState state = createInitialState(AssemblyItems{ + u256(0x12), + u256(0x20), + Instruction::ADD + }); + AssemblyItems input{ + u256(0x12 + 0x20) + }; + checkCSE(input, AssemblyItems{Instruction::DUP1}, state); +} BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack) { -- cgit v1.2.3