From 05dac999223220fdb54c0d28781b3ef1d621061d Mon Sep 17 00:00:00 2001 From: chriseth Date: Fri, 3 Mar 2017 16:17:00 +0100 Subject: Tests for optimizing constants. --- test/libsolidity/SolidityOptimizer.cpp | 62 ++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'test/libsolidity') diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 2e2e0c6c..bcf6cd49 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -1234,6 +1235,67 @@ BOOST_AUTO_TEST_CASE(computing_constants) ) == optimizedBytecode.cend()); } + +BOOST_AUTO_TEST_CASE(constant_optimization_early_exit) +{ + // This tests that the constant optimizer does not try to find the best representation + // indefinitely but instead stops after some number of iterations. + char const* sourceCode = R"( + pragma solidity ^0.4.0; + + contract HexEncoding { + function hexEncodeTest(address addr) returns (bytes32 ret) { + uint x = uint(addr) / 2**32; + + // Nibble interleave + x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + x = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + x = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + x = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + x = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + x = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + + // Hex encode + uint h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8; + uint i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4; + uint j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2; + x = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030; + + // Store and load next batch + assembly { + mstore(0, x) + } + x = uint(addr) * 2**96; + + // Nibble interleave + x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff; + x = (x | (x * 2**64)) & 0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff; + x = (x | (x * 2**32)) & 0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff; + x = (x | (x * 2**16)) & 0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff; + x = (x | (x * 2** 8)) & 0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff; + x = (x | (x * 2** 4)) & 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f; + + // Hex encode + h = (x & 0x0808080808080808080808080808080808080808080808080808080808080808) / 8; + i = (x & 0x0404040404040404040404040404040404040404040404040404040404040404) / 4; + j = (x & 0x0202020202020202020202020202020202020202020202020202020202020202) / 2; + x = x + (h & (i | j)) * 0x27 + 0x3030303030303030303030303030303030303030303030303030303030303030; + + // Store and hash + assembly { + mstore(32, x) + ret := sha3(0, 40) + } + } + } + )"; + auto start = std::chrono::steady_clock::now(); + compileBothVersions(sourceCode); + double duration = std::chrono::duration(std::chrono::steady_clock::now() - start).count(); + BOOST_CHECK_MESSAGE(duration < 20, "Compilation of constants took longer than 20 seconds."); + compareVersions("hexEncodeTest(address)", u256(0x123456789)); +} + BOOST_AUTO_TEST_CASE(inconsistency) { // This is a test of a bug in the optimizer. -- cgit