diff options
-rw-r--r-- | docs/grammar.txt (renamed from libsolidity/grammar.txt) | 0 | ||||
-rw-r--r-- | docs/miscellaneous.rst | 2 | ||||
-rw-r--r-- | libevmasm/ExpressionClasses.cpp | 14 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 23 |
4 files changed, 37 insertions, 2 deletions
diff --git a/libsolidity/grammar.txt b/docs/grammar.txt index 0aa6690b..0aa6690b 100644 --- a/libsolidity/grammar.txt +++ b/docs/grammar.txt diff --git a/docs/miscellaneous.rst b/docs/miscellaneous.rst index 15ff374d..9f733979 100644 --- a/docs/miscellaneous.rst +++ b/docs/miscellaneous.rst @@ -380,4 +380,4 @@ These keywords are reserved in Solidity. They might become part of the syntax in Language Grammar ================ -The entire language grammar is `available here <https://github.com/ethereum/solidity/blob/release/libsolidity/grammar.txt>`_. +.. literalinclude:: grammar.txt diff --git a/libevmasm/ExpressionClasses.cpp b/libevmasm/ExpressionClasses.cpp index e32b2da2..d5ccd7e3 100644 --- a/libevmasm/ExpressionClasses.cpp +++ b/libevmasm/ExpressionClasses.cpp @@ -245,22 +245,25 @@ Rules::Rules() // invariants involving known constants {{Instruction::ADD, {X, 0}}, [=]{ return X; }}, + {{Instruction::SUB, {X, 0}}, [=]{ return X; }}, {{Instruction::MUL, {X, 1}}, [=]{ return X; }}, {{Instruction::DIV, {X, 1}}, [=]{ return X; }}, {{Instruction::SDIV, {X, 1}}, [=]{ return X; }}, {{Instruction::OR, {X, 0}}, [=]{ return X; }}, {{Instruction::XOR, {X, 0}}, [=]{ return X; }}, {{Instruction::AND, {X, ~u256(0)}}, [=]{ return X; }}, + {{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }}, + {{Instruction::DIV, {0, X}}, [=]{ return u256(0); }}, {{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::MOD, {0, X}}, [=]{ return u256(0); }}, - {{Instruction::AND, {X, 0}}, [=]{ return u256(0); }}, {{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }}, {{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }, // operations involving an expression and itself {{Instruction::AND, {X, X}}, [=]{ return X; }}, {{Instruction::OR, {X, X}}, [=]{ return X; }}, + {{Instruction::XOR, {X, X}}, [=]{ return u256(0); }}, {{Instruction::SUB, {X, X}}, [=]{ return u256(0); }}, {{Instruction::EQ, {X, X}}, [=]{ return u256(1); }}, {{Instruction::LT, {X, X}}, [=]{ return u256(0); }}, @@ -270,6 +273,11 @@ Rules::Rules() {{Instruction::MOD, {X, X}}, [=]{ return u256(0); }}, {{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }}, + {{Instruction::XOR, {{{X}, {Instruction::XOR, {X, Y}}}}}, [=]{ return Y; }}, + {{Instruction::OR, {{{X}, {Instruction::AND, {X, Y}}}}}, [=]{ return X; }}, + {{Instruction::AND, {{{X}, {Instruction::OR, {X, Y}}}}}, [=]{ return X; }}, + {{Instruction::AND, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return u256(0); }}, + {{Instruction::OR, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return ~u256(0); }}, }; // Double negation of opcodes with binary result for (auto const& op: vector<Instruction>{ @@ -287,6 +295,10 @@ Rules::Rules() {Instruction::ISZERO, {{Instruction::ISZERO, {{Instruction::ISZERO, {X}}}}}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } }); + m_rules.push_back({ + {Instruction::ISZERO, {{Instruction::XOR, {X, Y}}}}, + [=]() -> Pattern { return { Instruction::EQ, {X, Y} }; } + }); // Associative operations for (auto const& opFun: vector<pair<Instruction,function<u256(u256 const&,u256 const&)>>>{ {Instruction::ADD, plus<u256>()}, diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index 60310555..3c1f465a 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -1305,6 +1305,29 @@ BOOST_AUTO_TEST_CASE(invalid_state_at_control_flow_join) compareVersions("test()"); } +BOOST_AUTO_TEST_CASE(cse_sub_zero) +{ + checkCSE({ + u256(0), + Instruction::DUP2, + Instruction::SUB + }, { + Instruction::DUP1 + }); + + checkCSE({ + Instruction::DUP1, + u256(0), + Instruction::SUB + }, { + u256(0), + Instruction::DUP2, + Instruction::SWAP1, + Instruction::SUB + }); +} + + BOOST_AUTO_TEST_SUITE_END() } |