From f86c5da20289c444af8f583eab656af8860dc582 Mon Sep 17 00:00:00 2001 From: Daniel Kirchner Date: Thu, 12 Sep 2019 18:17:13 +0200 Subject: [PATCH] Fix SSA reverser in special case of declaration followed by self-assignment. --- libyul/optimiser/SSAReverser.cpp | 30 +++++++++++-------- libyul/optimiser/SSAReverser.h | 7 +++++ .../ssaReverser/self_assign.yul | 8 +++++ 3 files changed, 33 insertions(+), 12 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/ssaReverser/self_assign.yul diff --git a/libyul/optimiser/SSAReverser.cpp b/libyul/optimiser/SSAReverser.cpp index a9a49fdb6..5bc6ab5c6 100644 --- a/libyul/optimiser/SSAReverser.cpp +++ b/libyul/optimiser/SSAReverser.cpp @@ -56,18 +56,24 @@ void SSAReverser::operator()(Block& _block) identifier && identifier->name == varDecl->variables.front().name ) - return make_vector( - Assignment{ - std::move(assignment->location), - assignment->variableNames, - std::move(varDecl->value) - }, - VariableDeclaration{ - std::move(varDecl->location), - std::move(varDecl->variables), - std::make_unique(std::move(assignment->variableNames.front())) - } - ); + { + // in the special case a == a_1, just remove the assignment + if (assignment->variableNames.front().name == identifier->name) + return make_vector(std::move(_stmt1)); + else + return make_vector( + Assignment{ + std::move(assignment->location), + assignment->variableNames, + std::move(varDecl->value) + }, + VariableDeclaration{ + std::move(varDecl->location), + std::move(varDecl->variables), + std::make_unique(std::move(assignment->variableNames.front())) + } + ); + } } // Replaces // let a_1 := E diff --git a/libyul/optimiser/SSAReverser.h b/libyul/optimiser/SSAReverser.h index 67abeb568..7845bff5d 100644 --- a/libyul/optimiser/SSAReverser.h +++ b/libyul/optimiser/SSAReverser.h @@ -40,6 +40,13 @@ class AssignmentCounter; * a := E * let a_1 := a * + * In the special case + * let a := E + * a := a + * + * the redundant assignment "a := a" is removed. + * + * * Secondly, the SSA transform will rewrite * * let a := E diff --git a/test/libyul/yulOptimizerTests/ssaReverser/self_assign.yul b/test/libyul/yulOptimizerTests/ssaReverser/self_assign.yul new file mode 100644 index 000000000..48b9d39cf --- /dev/null +++ b/test/libyul/yulOptimizerTests/ssaReverser/self_assign.yul @@ -0,0 +1,8 @@ +{ + let a := calldataload(0) + a := a +} +// ==== +// step: ssaReverser +// ---- +// { let a := calldataload(0) }