diff --git a/Changelog.md b/Changelog.md
index 69bd02624..2ddf6647e 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -12,6 +12,7 @@ Compiler Features:
* SMTChecker: Add ``--model-checker-print-query`` CLI option and ``settings.modelChecker.printQuery`` JSON option to output the SMTChecker queries in the SMTLIB2 format. This requires using `smtlib2` solver only.
* Standard JSON Interface: Add ``ast`` file-level output for Yul input.
* Standard JSON Interface: Add ``irAst`` and ``irOptimizedAst`` contract-level outputs for Solidity input, providing AST in compact JSON format for IR and optimized IR.
+ * Yul Optimizer: Remove experimental `ReasoningBasedSimplifier` optimization step.
* Yul Optimizer: Stack-to-memory mover is now enabled by default whenever possible for via IR code generation and pure Yul compilation.
diff --git a/docs/internals/optimizer.rst b/docs/internals/optimizer.rst
index d3df1b600..cd4624a1a 100644
--- a/docs/internals/optimizer.rst
+++ b/docs/internals/optimizer.rst
@@ -316,7 +316,6 @@ Abbreviation Full name
``L`` :ref:`load-resolver`
``M`` :ref:`loop-invariant-code-motion`
``r`` :ref:`redundant-assign-eliminator`
-``R`` :ref:`reasoning-based-simplifier` - highly experimental
``m`` :ref:`rematerialiser`
``V`` :ref:`SSA-reverser`
``a`` :ref:`SSA-transform`
@@ -330,10 +329,6 @@ Abbreviation Full name
Some steps depend on properties ensured by ``BlockFlattener``, ``FunctionGrouper``, ``ForLoopInitRewriter``.
For this reason the Yul optimizer always applies them before applying any steps supplied by the user.
-The ReasoningBasedSimplifier is an optimizer step that is currently not enabled
-in the default set of steps. It uses an SMT solver to simplify arithmetic expressions
-and boolean conditions. It has not received thorough testing or validation yet and can produce
-non-reproducible results, so please use with care!
Selecting Optimizations
-----------------------
@@ -863,22 +858,6 @@ Works best if the code is in SSA form.
Prerequisite: Disambiguator, ForLoopInitRewriter.
-.. _reasoning-based-simplifier:
-
-ReasoningBasedSimplifier
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-This optimizer uses SMT solvers to check whether ``if`` conditions are constant.
-
-- If ``constraints AND condition`` is UNSAT, the condition is never true and the whole body can be removed.
-- If ``constraints AND NOT condition`` is UNSAT, the condition is always true and can be replaced by ``1``.
-
-The simplifications above can only be applied if the condition is movable.
-
-It is only effective on the EVM dialect, but safe to use on other dialects.
-
-Prerequisite: Disambiguator, SSATransform.
-
Statement-Scale Simplifications
-------------------------------
diff --git a/libyul/CMakeLists.txt b/libyul/CMakeLists.txt
index 2cf02f838..0bb98e467 100644
--- a/libyul/CMakeLists.txt
+++ b/libyul/CMakeLists.txt
@@ -143,8 +143,6 @@ add_library(yul
optimiser/OptimiserStep.h
optimiser/OptimizerUtilities.cpp
optimiser/OptimizerUtilities.h
- optimiser/ReasoningBasedSimplifier.cpp
- optimiser/ReasoningBasedSimplifier.h
optimiser/UnusedAssignEliminator.cpp
optimiser/UnusedAssignEliminator.h
optimiser/UnusedStoreBase.cpp
@@ -153,8 +151,6 @@ add_library(yul
optimiser/UnusedStoreEliminator.h
optimiser/Rematerialiser.cpp
optimiser/Rematerialiser.h
- optimiser/SMTSolver.cpp
- optimiser/SMTSolver.h
optimiser/SSAReverser.cpp
optimiser/SSAReverser.h
optimiser/SSATransform.cpp
diff --git a/libyul/optimiser/ReasoningBasedSimplifier.cpp b/libyul/optimiser/ReasoningBasedSimplifier.cpp
deleted file mode 100644
index 24882d84e..000000000
--- a/libyul/optimiser/ReasoningBasedSimplifier.cpp
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- 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 .
-*/
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-#include
-#include
-
-#include
-
-#include
-
-#include
-#include
-
-using namespace std;
-using namespace solidity;
-using namespace solidity::util;
-using namespace solidity::yul;
-using namespace solidity::smtutil;
-
-void ReasoningBasedSimplifier::run(OptimiserStepContext& _context, Block& _ast)
-{
- set ssaVars = SSAValueTracker::ssaVariables(_ast);
- ReasoningBasedSimplifier{_context.dialect, ssaVars}(_ast);
-}
-
-std::optional ReasoningBasedSimplifier::invalidInCurrentEnvironment()
-{
- // SMTLib2 interface is always available, but we would like to have synchronous answers.
- if (smtutil::SMTPortfolio{}.solvers() <= 1)
- return string{"No SMT solvers available."};
- else
- return nullopt;
-}
-
-void ReasoningBasedSimplifier::operator()(VariableDeclaration& _varDecl)
-{
- SMTSolver::encodeVariableDeclaration(_varDecl);
-}
-
-void ReasoningBasedSimplifier::operator()(If& _if)
-{
- if (!SideEffectsCollector{m_dialect, *_if.condition}.movable())
- return;
-
- smtutil::Expression condition = encodeExpression(*_if.condition);
- m_solver->push();
- m_solver->addAssertion(condition == constantValue(0));
- CheckResult result = m_solver->check({}).first;
- m_solver->pop();
- if (result == CheckResult::UNSATISFIABLE)
- {
- Literal trueCondition = m_dialect.trueLiteral();
- trueCondition.debugData = debugDataOf(*_if.condition);
- _if.condition = make_unique(std::move(trueCondition));
- }
- else
- {
- m_solver->push();
- m_solver->addAssertion(condition != constantValue(0));
- CheckResult result2 = m_solver->check({}).first;
- m_solver->pop();
- if (result2 == CheckResult::UNSATISFIABLE)
- {
- Literal falseCondition = m_dialect.zeroLiteralForType(m_dialect.boolType);
- falseCondition.debugData = debugDataOf(*_if.condition);
- _if.condition = make_unique(std::move(falseCondition));
- _if.body = yul::Block{};
- // Nothing left to be done.
- return;
- }
- }
-
- m_solver->push();
- m_solver->addAssertion(condition != constantValue(0));
-
- ASTModifier::operator()(_if.body);
-
- m_solver->pop();
-}
-
-ReasoningBasedSimplifier::ReasoningBasedSimplifier(
- Dialect const& _dialect,
- set const& _ssaVariables
-):
- SMTSolver(_ssaVariables, _dialect),
- m_dialect(_dialect)
-{
-}
-
-
-smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
- evmasm::Instruction _instruction,
- vector const& _arguments
-)
-{
- vector arguments = applyMap(
- _arguments,
- [this](yul::Expression const& _expr) { return encodeExpression(_expr); }
- );
- switch (_instruction)
- {
- case evmasm::Instruction::ADD:
- return wrap(arguments.at(0) + arguments.at(1));
- case evmasm::Instruction::MUL:
- return wrap(arguments.at(0) * arguments.at(1));
- case evmasm::Instruction::SUB:
- return wrap(arguments.at(0) - arguments.at(1));
- case evmasm::Instruction::DIV:
- return smtutil::Expression::ite(
- arguments.at(1) == constantValue(0),
- constantValue(0),
- arguments.at(0) / arguments.at(1)
- );
- case evmasm::Instruction::SDIV:
- return smtutil::Expression::ite(
- arguments.at(1) == constantValue(0),
- constantValue(0),
- // No `wrap()` needed here, because -2**255 / -1 results
- // in 2**255 which is "converted" to its two's complement
- // representation 2**255 in `signedToTwosComplement`
- signedToTwosComplement(smtutil::signedDivisionEVM(
- twosComplementToSigned(arguments.at(0)),
- twosComplementToSigned(arguments.at(1))
- ))
- );
- case evmasm::Instruction::MOD:
- return smtutil::Expression::ite(
- arguments.at(1) == constantValue(0),
- constantValue(0),
- arguments.at(0) % arguments.at(1)
- );
- case evmasm::Instruction::SMOD:
- return smtutil::Expression::ite(
- arguments.at(1) == constantValue(0),
- constantValue(0),
- signedToTwosComplement(signedModuloEVM(
- twosComplementToSigned(arguments.at(0)),
- twosComplementToSigned(arguments.at(1))
- ))
- );
- case evmasm::Instruction::LT:
- return booleanValue(arguments.at(0) < arguments.at(1));
- case evmasm::Instruction::SLT:
- return booleanValue(twosComplementToSigned(arguments.at(0)) < twosComplementToSigned(arguments.at(1)));
- case evmasm::Instruction::GT:
- return booleanValue(arguments.at(0) > arguments.at(1));
- case evmasm::Instruction::SGT:
- return booleanValue(twosComplementToSigned(arguments.at(0)) > twosComplementToSigned(arguments.at(1)));
- case evmasm::Instruction::EQ:
- return booleanValue(arguments.at(0) == arguments.at(1));
- case evmasm::Instruction::ISZERO:
- return booleanValue(arguments.at(0) == constantValue(0));
- case evmasm::Instruction::AND:
- return smtutil::Expression::ite(
- (arguments.at(0) == 0 || arguments.at(0) == 1) &&
- (arguments.at(1) == 0 || arguments.at(1) == 1),
- booleanValue(arguments.at(0) == 1 && arguments.at(1) == 1),
- bv2int(int2bv(arguments.at(0)) & int2bv(arguments.at(1)))
- );
- case evmasm::Instruction::OR:
- return smtutil::Expression::ite(
- (arguments.at(0) == 0 || arguments.at(0) == 1) &&
- (arguments.at(1) == 0 || arguments.at(1) == 1),
- booleanValue(arguments.at(0) == 1 || arguments.at(1) == 1),
- bv2int(int2bv(arguments.at(0)) | int2bv(arguments.at(1)))
- );
- case evmasm::Instruction::XOR:
- return bv2int(int2bv(arguments.at(0)) ^ int2bv(arguments.at(1)));
- case evmasm::Instruction::NOT:
- return smtutil::Expression(u256(-1)) - arguments.at(0);
- case evmasm::Instruction::SHL:
- return smtutil::Expression::ite(
- arguments.at(0) > 255,
- constantValue(0),
- bv2int(int2bv(arguments.at(1)) << int2bv(arguments.at(0)))
- );
- case evmasm::Instruction::SHR:
- return smtutil::Expression::ite(
- arguments.at(0) > 255,
- constantValue(0),
- bv2int(int2bv(arguments.at(1)) >> int2bv(arguments.at(0)))
- );
- case evmasm::Instruction::SAR:
- return smtutil::Expression::ite(
- arguments.at(0) > 255,
- constantValue(0),
- bv2int(smtutil::Expression::ashr(int2bv(arguments.at(1)), int2bv(arguments.at(0))))
- );
- case evmasm::Instruction::ADDMOD:
- return smtutil::Expression::ite(
- arguments.at(2) == constantValue(0),
- constantValue(0),
- (arguments.at(0) + arguments.at(1)) % arguments.at(2)
- );
- case evmasm::Instruction::MULMOD:
- return smtutil::Expression::ite(
- arguments.at(2) == constantValue(0),
- constantValue(0),
- (arguments.at(0) * arguments.at(1)) % arguments.at(2)
- );
- // TODO SIGNEXTEND
- default:
- break;
- }
- return newRestrictedVariable();
-}
diff --git a/libyul/optimiser/ReasoningBasedSimplifier.h b/libyul/optimiser/ReasoningBasedSimplifier.h
deleted file mode 100644
index c458a36d0..000000000
--- a/libyul/optimiser/ReasoningBasedSimplifier.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- 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 .
-*/
-#pragma once
-
-#include
-#include
-#include
-#include
-
-// because of instruction
-#include
-
-#include