diff --git a/Changelog.md b/Changelog.md
index da977bc28..d27b336c8 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -5,6 +5,7 @@ Language Features:
Compiler Features:
+ * Yul Optimizer: Remove ``mstore`` and ``sstore`` operations if the slot already contains the same value.
diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst
index 19bca791e..a7eff7346 100644
--- a/docs/internals/optimizer.rst
+++ b/docs/internals/optimizer.rst
@@ -290,6 +290,7 @@ on the individual steps and their sequence below.
- :ref:`conditional-unsimplifier`.
- :ref:`control-flow-simplifier`.
- :ref:`dead-code-eliminator`.
+- :ref:`equal-store-eliminator`.
- :ref:`equivalent-function-combiner`.
- :ref:`expression-joiner`.
- :ref:`expression-simplifier`.
@@ -938,6 +939,22 @@ we require ForLoopInitRewriter to run before this step.
Prerequisite: ForLoopInitRewriter, Function Hoister, Function Grouper
+.. _equal-store-eliminator:
+
+EqualStoreEliminator
+^^^^^^^^^^^^^^^^^^^^
+
+This steps removes ``mstore(k, v)`` and ``sstore(k, v)`` calls if
+there was a previous call to ``mstore(k, v)`` / ``sstore(k, v)``,
+no other store in between and the values of ``k`` and ``v`` did not change.
+
+This simple step is effective if run after the SSA transform and the
+Common Subexpression Eliminator, because SSA will make sure that the variables
+will not change and the Common Subexpression Eliminator re-uses exactly the same
+variable if the value is known to be the same.
+
+Prerequisites: Disambiguator, ForLoopInitRewriter
+
.. _unused-pruner:
UnusedPruner
diff --git a/libsolidity/interface/OptimiserSettings.h b/libsolidity/interface/OptimiserSettings.h
index 5317acee4..e1c35e9ea 100644
--- a/libsolidity/interface/OptimiserSettings.h
+++ b/libsolidity/interface/OptimiserSettings.h
@@ -44,7 +44,7 @@ struct OptimiserSettings
static char constexpr DefaultYulOptimiserSteps[] =
"dhfoDgvulfnTUtnIf" // None of these can make stack problems worse
"["
- "xa[r]scLM" // Turn into SSA and simplify
+ "xa[r]EscLM" // Turn into SSA and simplify
"cCTUtTOntnfDIul" // Perform structural simplification
"Lcul" // Simplify again
"Vcul [j]" // Reverse SSA
diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt
index 16b68535a..fde673e3d 100644
--- a/libyul/CMakeLists.txt
+++ b/libyul/CMakeLists.txt
@@ -120,6 +120,8 @@ add_library(yul
optimiser/DeadCodeEliminator.h
optimiser/Disambiguator.cpp
optimiser/Disambiguator.h
+ optimiser/EqualStoreEliminator.cpp
+ optimiser/EqualStoreEliminator.h
optimiser/EquivalentFunctionDetector.cpp
optimiser/EquivalentFunctionDetector.h
optimiser/EquivalentFunctionCombiner.cpp
diff --git a/libyul/optimiser/EqualStoreEliminator.cpp b/libyul/optimiser/EqualStoreEliminator.cpp
new file mode 100644
index 000000000..dcba98ce4
--- /dev/null
+++ b/libyul/optimiser/EqualStoreEliminator.cpp
@@ -0,0 +1,70 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+/**
+ * Optimisation stage that removes mstore and sstore operations if they store the same
+ * value that is already known to be in that slot.
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace solidity;
+using namespace solidity::util;
+using namespace solidity::evmasm;
+using namespace solidity::yul;
+
+void EqualStoreEliminator::run(OptimiserStepContext const& _context, Block& _ast)
+{
+ EqualStoreEliminator eliminator{
+ _context.dialect,
+ SideEffectsPropagator::sideEffects(_context.dialect, CallGraphGenerator::callGraph(_ast))
+ };
+ eliminator(_ast);
+
+ StatementRemover remover{eliminator.m_pendingRemovals};
+ remover(_ast);
+}
+
+void EqualStoreEliminator::visit(Statement& _statement)
+{
+ // No need to consider potential changes through complex arguments since
+ // isSimpleStore only returns something if the arguments are identifiers.
+ if (ExpressionStatement const* expression = get_if(&_statement))
+ {
+ if (auto vars = isSimpleStore(StoreLoadLocation::Storage, *expression))
+ {
+ if (auto const* currentValue = valueOrNullptr(m_storage, vars->first))
+ if (*currentValue == vars->second)
+ m_pendingRemovals.insert(&_statement);
+ }
+ else if (auto vars = isSimpleStore(StoreLoadLocation::Memory, *expression))
+ {
+ if (auto const* currentValue = valueOrNullptr(m_memory, vars->first))
+ if (*currentValue == vars->second)
+ m_pendingRemovals.insert(&_statement);
+ }
+ }
+
+ DataFlowAnalyzer::visit(_statement);
+}
diff --git a/libyul/optimiser/EqualStoreEliminator.h b/libyul/optimiser/EqualStoreEliminator.h
new file mode 100644
index 000000000..796fcc538
--- /dev/null
+++ b/libyul/optimiser/EqualStoreEliminator.h
@@ -0,0 +1,60 @@
+/*
+ This file is part of solidity.
+
+ solidity is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ solidity is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with solidity. If not, see .
+*/
+// SPDX-License-Identifier: GPL-3.0
+/**
+ * Optimisation stage that removes mstore and sstore operations if they store the same
+ * value that is already known to be in that slot.
+ */
+
+#pragma once
+
+#include
+#include
+
+namespace solidity::yul
+{
+
+/**
+ * Optimisation stage that removes mstore and sstore operations if they store the same
+ * value that is already known to be in that slot.
+ *
+ * Works best if the code is in SSA form - without literal arguments.
+ *
+ * Prerequisite: Disambiguator, ForLoopInitRewriter.
+ */
+class EqualStoreEliminator: public DataFlowAnalyzer
+{
+public:
+ static constexpr char const* name{"EqualStoreEliminator"};
+ static void run(OptimiserStepContext const&, Block& _ast);
+
+private:
+ EqualStoreEliminator(
+ Dialect const& _dialect,
+ std::map _functionSideEffects
+ ):
+ DataFlowAnalyzer(_dialect, std::move(_functionSideEffects))
+ {}
+
+protected:
+ using ASTModifier::visit;
+ void visit(Statement& _statement) override;
+
+ std::set m_pendingRemovals;
+};
+
+}
diff --git a/libyul/optimiser/OptimizerUtilities.cpp b/libyul/optimiser/OptimizerUtilities.cpp
index 23596a745..ba06b2180 100644
--- a/libyul/optimiser/OptimizerUtilities.cpp
+++ b/libyul/optimiser/OptimizerUtilities.cpp
@@ -57,3 +57,18 @@ optional yul::toEVMInstruction(Dialect const& _dialect, Yul
return builtin->instruction;
return nullopt;
}
+
+void StatementRemover::operator()(Block& _block)
+{
+ util::iterateReplacing(
+ _block.statements,
+ [&](Statement& _statement) -> std::optional>
+ {
+ if (m_toRemove.count(&_statement))
+ return {vector{}};
+ else
+ return nullopt;
+ }
+ );
+ ASTModifier::operator()(_block);
+}
diff --git a/libyul/optimiser/OptimizerUtilities.h b/libyul/optimiser/OptimizerUtilities.h
index d80b16316..b491e57e1 100644
--- a/libyul/optimiser/OptimizerUtilities.h
+++ b/libyul/optimiser/OptimizerUtilities.h
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
@@ -48,4 +49,14 @@ bool isRestrictedIdentifier(Dialect const& _dialect, YulString const& _identifie
/// Helper function that returns the instruction, if the `_name` is a BuiltinFunction
std::optional toEVMInstruction(Dialect const& _dialect, YulString const& _name);
+class StatementRemover: public ASTModifier
+{
+public:
+ explicit StatementRemover(std::set const& _toRemove): m_toRemove(_toRemove) {}
+
+ void operator()(Block& _block) override;
+private:
+ std::set const& m_toRemove;
+};
+
}
diff --git a/libyul/optimiser/Suite.cpp b/libyul/optimiser/Suite.cpp
index 4012fa970..0f2194061 100644
--- a/libyul/optimiser/Suite.cpp
+++ b/libyul/optimiser/Suite.cpp
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -204,6 +205,7 @@ map> const& OptimiserSuite::allSteps()
ConditionalUnsimplifier,
ControlFlowSimplifier,
DeadCodeEliminator,
+ EqualStoreEliminator,
EquivalentFunctionCombiner,
ExpressionInliner,
ExpressionJoiner,
@@ -244,6 +246,7 @@ map const& OptimiserSuite::stepNameToAbbreviationMap()
{ConditionalUnsimplifier::name, 'U'},
{ControlFlowSimplifier::name, 'n'},
{DeadCodeEliminator::name, 'D'},
+ {EqualStoreEliminator::name, 'E'},
{EquivalentFunctionCombiner::name, 'v'},
{ExpressionInliner::name, 'e'},
{ExpressionJoiner::name, 'j'},
diff --git a/libyul/optimiser/UnusedAssignEliminator.cpp b/libyul/optimiser/UnusedAssignEliminator.cpp
index 74dd599a1..273aa6b79 100644
--- a/libyul/optimiser/UnusedAssignEliminator.cpp
+++ b/libyul/optimiser/UnusedAssignEliminator.cpp
@@ -23,6 +23,7 @@
#include
#include
+#include
#include
#include
diff --git a/libyul/optimiser/UnusedStoreBase.cpp b/libyul/optimiser/UnusedStoreBase.cpp
index 27700bdf7..8e34d172f 100644
--- a/libyul/optimiser/UnusedStoreBase.cpp
+++ b/libyul/optimiser/UnusedStoreBase.cpp
@@ -156,18 +156,3 @@ void UnusedStoreBase::merge(TrackedStores& _target, vector&& _sou
merge(_target, move(ts));
_source.clear();
}
-
-void StatementRemover::operator()(Block& _block)
-{
- util::iterateReplacing(
- _block.statements,
- [&](Statement& _statement) -> std::optional>
- {
- if (m_toRemove.count(&_statement))
- return {vector{}};
- else
- return nullopt;
- }
- );
- ASTModifier::operator()(_block);
-}
diff --git a/libyul/optimiser/UnusedStoreBase.h b/libyul/optimiser/UnusedStoreBase.h
index 3bd4e4297..15dccb04a 100644
--- a/libyul/optimiser/UnusedStoreBase.h
+++ b/libyul/optimiser/UnusedStoreBase.h
@@ -105,14 +105,4 @@ protected:
size_t m_forLoopNestingDepth = 0;
};
-class StatementRemover: public ASTModifier
-{
-public:
- explicit StatementRemover(std::set const& _toRemove): m_toRemove(_toRemove) {}
-
- void operator()(Block& _block) override;
-private:
- std::set const& m_toRemove;
-};
-
}
diff --git a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol
index ed9a07f7f..7f5799805 100644
--- a/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol
+++ b/test/libsolidity/semanticTests/externalContracts/deposit_contract.sol
@@ -178,7 +178,7 @@ contract DepositContract is IDepositContract, ERC165 {
// compileViaYul: also
// ----
// constructor()
-// gas irOptimized: 1558001
+// gas irOptimized: 1557137
// gas legacy: 2436584
// gas legacyOptimized: 1776483
// supportsInterface(bytes4): 0x0 -> 0
diff --git a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol
index f01a590eb..d3e2ba075 100644
--- a/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol
+++ b/test/libsolidity/semanticTests/functionCall/mapping_array_internal_argument.sol
@@ -20,7 +20,7 @@ contract test {
// compileViaYul: also
// ----
// set(uint8,uint8,uint8,uint8,uint8): 1, 21, 22, 42, 43 -> 0, 0, 0, 0
-// gas irOptimized: 111965
+// gas irOptimized: 111896
// gas legacy: 113806
// gas legacyOptimized: 111781
// get(uint8): 1 -> 21, 22, 42, 43
diff --git a/test/libsolidity/semanticTests/structs/struct_copy.sol b/test/libsolidity/semanticTests/structs/struct_copy.sol
index 0bbb6489e..f170dca3f 100644
--- a/test/libsolidity/semanticTests/structs/struct_copy.sol
+++ b/test/libsolidity/semanticTests/structs/struct_copy.sol
@@ -38,12 +38,12 @@ contract c {
// compileViaYul: also
// ----
// set(uint256): 7 -> true
-// gas irOptimized: 110011
+// gas irOptimized: 110119
// gas legacy: 110616
// gas legacyOptimized: 110006
// retrieve(uint256): 7 -> 1, 3, 4, 2
// copy(uint256,uint256): 7, 8 -> true
-// gas irOptimized: 118707
+// gas irOptimized: 118698
// gas legacy: 119166
// gas legacyOptimized: 118622
// retrieve(uint256): 7 -> 1, 3, 4, 2
diff --git a/test/libyul/YulOptimizerTestCommon.cpp b/test/libyul/YulOptimizerTestCommon.cpp
index cc315c4b9..bb8458d78 100644
--- a/test/libyul/YulOptimizerTestCommon.cpp
+++ b/test/libyul/YulOptimizerTestCommon.cpp
@@ -28,6 +28,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -236,6 +237,11 @@ YulOptimizerTestCommon::YulOptimizerTestCommon(
ForLoopInitRewriter::run(*m_context, *m_ast);
UnusedAssignEliminator::run(*m_context, *m_ast);
}},
+ {"equalStoreEliminator", [&]() {
+ disambiguate();
+ ForLoopInitRewriter::run(*m_context, *m_ast);
+ EqualStoreEliminator::run(*m_context, *m_ast);
+ }},
{"ssaPlusCleanup", [&]() {
disambiguate();
ForLoopInitRewriter::run(*m_context, *m_ast);
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul
new file mode 100644
index 000000000..63f0d38e4
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/branching.yul
@@ -0,0 +1,25 @@
+{
+ let a := calldataload(0)
+ let b := 20
+ sstore(a, b)
+ if calldataload(32) {
+ sstore(a, b)
+ pop(staticcall(0, 0, 0, 0, 0, 0))
+ sstore(a, b)
+ }
+ sstore(a, b)
+}
+// ====
+// EVMVersion: >=byzantium
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let a := calldataload(0)
+// let b := 20
+// sstore(a, b)
+// if calldataload(32)
+// {
+// pop(staticcall(0, 0, 0, 0, 0, 0))
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/forloop.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/forloop.yul
new file mode 100644
index 000000000..ccd7dd40b
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/forloop.yul
@@ -0,0 +1,20 @@
+{
+ let x := calldataload(0)
+ let y := calldataload(1)
+
+ sstore(x, y)
+ for {let a := 1} lt(a, 10) {a := add(a, 1) } {
+ sstore(x, y)
+ }
+}
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let x := calldataload(0)
+// let y := calldataload(1)
+// sstore(x, y)
+// let a := 1
+// for { } lt(a, 10) { a := add(a, 1) }
+// { sstore(x, y) }
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul
new file mode 100644
index 000000000..68839721c
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/functionbody.yul
@@ -0,0 +1,56 @@
+{
+ f(calldataload(0), calldataload(32))
+ h(calldataload(64), calldataload(96))
+
+ function f(a, b) {
+ // gets removed
+ sstore(a, b)
+ g()
+ sstore(a, b)
+ }
+
+ function g() {
+ pop(staticcall(0, 0, 0, 0, 0, 0))
+ }
+
+ function h(a_, b_) {
+ // cannot be removed
+ sstore(a_, b_)
+ i()
+ sstore(a_, b_)
+ }
+
+ function i() {
+ pop(delegatecall(0, 0, 0, 0, 0, 0))
+ }
+
+
+}
+// ====
+// EVMVersion: >=byzantium
+// ----
+// step: equalStoreEliminator
+//
+// {
+// f(calldataload(0), calldataload(32))
+// h(calldataload(64), calldataload(96))
+// function f(a, b)
+// {
+// sstore(a, b)
+// g()
+// }
+// function g()
+// {
+// pop(staticcall(0, 0, 0, 0, 0, 0))
+// }
+// function h(a_, b_)
+// {
+// sstore(a_, b_)
+// i()
+// sstore(a_, b_)
+// }
+// function i()
+// {
+// pop(delegatecall(0, 0, 0, 0, 0, 0))
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/indirect_inferrence.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/indirect_inferrence.yul
new file mode 100644
index 000000000..2b68e6310
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/indirect_inferrence.yul
@@ -0,0 +1,24 @@
+{
+ let x := calldataload(0)
+ let y := sload(x)
+ // both of these can be removed
+ sstore(x, y)
+ sstore(x, y)
+
+ let a := x
+ let b := mload(a)
+ // both of these can be removed
+ mstore(a, b)
+ mstore(a, b)
+}
+// ====
+// EVMVersion: >=byzantium
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let x := calldataload(0)
+// let y := sload(x)
+// let a := x
+// let b := mload(a)
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/mstore_with_keccak.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/mstore_with_keccak.yul
new file mode 100644
index 000000000..395fea6d0
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/mstore_with_keccak.yul
@@ -0,0 +1,31 @@
+{
+ let var_k := calldataload(0)
+ let _1 := 0x00
+ let _2 := 0x20
+ mstore(_1, var_k)
+ mstore(_2, _1)
+ sstore(keccak256(_1, 0x40), 0x01)
+ mstore(_1, var_k)
+ mstore(_2, _1)
+ sstore(add(keccak256(_1, 0x40), 0x01), 0x03)
+ mstore(_1, var_k)
+ mstore(_2, _1)
+ sstore(add(keccak256(_1, 0x40), 2), 0x04)
+ mstore(_1, var_k)
+ mstore(_2, _1)
+ sstore(add(keccak256(_1, 0x40), 0x03), 2)
+}
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let var_k := calldataload(0)
+// let _1 := 0x00
+// let _2 := 0x20
+// mstore(_1, var_k)
+// mstore(_2, _1)
+// sstore(keccak256(_1, 0x40), 0x01)
+// sstore(add(keccak256(_1, 0x40), 0x01), 0x03)
+// sstore(add(keccak256(_1, 0x40), 2), 0x04)
+// sstore(add(keccak256(_1, 0x40), 0x03), 2)
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/value_change.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/value_change.yul
new file mode 100644
index 000000000..bd1e08bcd
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/value_change.yul
@@ -0,0 +1,18 @@
+{
+ let x := calldataload(0)
+ let y := calldataload(32)
+ sstore(x, y)
+ y := calldataload(64)
+ // cannot be removed
+ sstore(x, y)
+}
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let x := calldataload(0)
+// let y := calldataload(32)
+// sstore(x, y)
+// y := calldataload(64)
+// sstore(x, y)
+// }
diff --git a/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul b/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul
new file mode 100644
index 000000000..fcaddd121
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/equalStoreEliminator/verbatim.yul
@@ -0,0 +1,27 @@
+{
+ let a := calldataload(0)
+ let b := 20
+ sstore(a, b)
+ if calldataload(32) {
+ sstore(a, b)
+ pop(staticcall(0, 0, 0, 0, 0, 0))
+ verbatim_0i_0o("xyz")
+ }
+ sstore(a, b)
+}
+// ====
+// EVMVersion: >=byzantium
+// ----
+// step: equalStoreEliminator
+//
+// {
+// let a := calldataload(0)
+// let b := 20
+// sstore(a, b)
+// if calldataload(32)
+// {
+// pop(staticcall(0, 0, 0, 0, 0, 0))
+// verbatim_0i_0o("xyz")
+// }
+// sstore(a, b)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul
index d670f002f..13683e8e6 100644
--- a/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul
+++ b/test/libyul/yulOptimizerTests/fullSuite/stack_compressor_msize.yul
@@ -55,7 +55,6 @@
// sstore(0, 0)
// sstore(2, _1)
// extcodecopy(_1, msize(), _1, _1)
-// sstore(0, 0)
// sstore(3, _1)
// }
// function gcd(_a, _b) -> out
diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul
index b531842db..ee648f80f 100644
--- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul
+++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_loop.yul
@@ -20,9 +20,7 @@
// f()
// sstore(0, 1)
// f()
-// sstore(0, 1)
// f()
-// sstore(0, 1)
// }
// function f()
// {
diff --git a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul
index 531b1a6ce..68620cc96 100644
--- a/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul
+++ b/test/libyul/yulOptimizerTests/fullSuite/unusedFunctionParameterPruner_simple.yul
@@ -18,9 +18,7 @@
// f()
// sstore(0, 1)
// f()
-// sstore(0, 1)
// f()
-// sstore(0, 1)
// }
// function f()
// {
diff --git a/test/yulPhaser/Chromosome.cpp b/test/yulPhaser/Chromosome.cpp
index 19616cde0..1b1e8bed5 100644
--- a/test/yulPhaser/Chromosome.cpp
+++ b/test/yulPhaser/Chromosome.cpp
@@ -138,7 +138,7 @@ BOOST_AUTO_TEST_CASE(output_operator_should_create_concise_and_unambiguous_strin
BOOST_TEST(chromosome.length() == allSteps.size());
BOOST_TEST(chromosome.optimisationSteps() == allSteps);
- BOOST_TEST(toString(chromosome) == "flcCUnDvejsxIOoighFTLMRmVatrpud");
+ BOOST_TEST(toString(chromosome) == "flcCUnDEvejsxIOoighFTLMRmVatrpud");
}
BOOST_AUTO_TEST_CASE(optimisationSteps_should_translate_chromosomes_genes_to_optimisation_step_names)