From 684fff34a9c1a714fafe7171292c6b08c4faa51d Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 28 Jul 2020 20:26:22 +0200 Subject: [PATCH] Replace exp by shl. --- Changelog.md | 2 +- libevmasm/RuleList.h | 17 +++++++++++++- .../exp_simplifications.yul | 22 +++++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul diff --git a/Changelog.md b/Changelog.md index 33f2c2ef5..ba393c0ee 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,7 +14,7 @@ Compiler Features: * Yul Optimizer: Inline into functions further down in the call graph first. * Yul Optimizer: Try to simplify function names. * Yul IR Generator: Report source locations related to unimplemented features. - + * Optimizer: Optimize ``exp`` when base is 0, 1 or 2. Bugfixes: * Code generator: Fix internal error on stripping dynamic types from return parameters on EVM versions without ``RETURNDATACOPY``. diff --git a/libevmasm/RuleList.h b/libevmasm/RuleList.h index 4adeb34c9..883de4c9f 100644 --- a/libevmasm/RuleList.h +++ b/libevmasm/RuleList.h @@ -615,12 +615,13 @@ std::vector> evmRuleList( Pattern, Pattern, Pattern, - Pattern, + Pattern X, Pattern, Pattern ) { using Builtins = typename Pattern::Builtins; + using Word = typename Pattern::Word; std::vector> rules; if (_evmVersion.hasSelfBalance()) @@ -629,6 +630,20 @@ std::vector> evmRuleList( []() -> Pattern { return Instruction::SELFBALANCE; } }); + rules.emplace_back( + Builtins::EXP(0, X), + [=]() -> Pattern { return Builtins::ISZERO(X); } + ); + rules.emplace_back( + Builtins::EXP(1, X), + [=]() -> Pattern { return Word(1); } + ); + if (_evmVersion.hasBitwiseShifting()) + rules.emplace_back( + Builtins::EXP(2, X), + [=]() -> Pattern { return Builtins::SHL(X, 1); } + ); + return rules; } diff --git a/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul b/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul new file mode 100644 index 000000000..879b05883 --- /dev/null +++ b/test/libyul/yulOptimizerTests/expressionSimplifier/exp_simplifications.yul @@ -0,0 +1,22 @@ +{ + let t := calldataload(0) + sstore(0, exp(0, t)) + sstore(1, exp(1, t)) + sstore(2, exp(2, t)) + // The following should not be simplified + sstore(3, exp(8, t)) +} +// ==== +// EVMVersion: >=constantinople +// ---- +// step: expressionSimplifier +// +// { +// let _1 := 0 +// let t := calldataload(_1) +// sstore(_1, iszero(t)) +// sstore(1, 1) +// let _8 := 2 +// sstore(_8, shl(t, 1)) +// sstore(3, exp(8, t)) +// }