diff --git a/Changelog.md b/Changelog.md index 15f8325cf..fed2c953f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: * SMTChecker: Do not report underflow/overflow if they always revert. This removes false positives when using ``SafeMath``. * Static Analyzer: Warn about expressions with custom types when they have no effect. * Optimizer: Add rule for shifts with constants for Constantinople. + * Optimizer: Combine multiple shifts with constant shift-by values into one. * Optimizer: Support shifts in the constant optimiser for Constantinople. diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 7b5037057..7cdf5a96f 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -24,6 +24,8 @@ #include #include +#include + #include #include @@ -336,6 +338,20 @@ std::vector> simplificationRuleListPart7( } } + rules.push_back({ + // SHL(B, SHL(A, X)) -> SHL(min(A+B, 256), X) + {Instruction::SHL, {{B}, {Instruction::SHL, {{A}, {X}}}}}, + [=]() -> Pattern { return {Instruction::SHL, {std::min(A.d() + B.d(), u256(256)), X}}; }, + false + }); + + rules.push_back({ + // SHR(B, SHR(A, X)) -> SHR(min(A+B, 256), X) + {Instruction::SHR, {{B}, {Instruction::SHR, {{A}, {X}}}}}, + [=]() -> Pattern { return {Instruction::SHR, {std::min(A.d() + B.d(), u256(256)), X}}; }, + false + }); + return rules; }