This commit is contained in:
chriseth
2022-03-20 22:34:22 +01:00
parent 797651c74b
commit b4dd0420ca
7 changed files with 141 additions and 43 deletions
+29 -3
View File
@@ -28,6 +28,8 @@
#include <libsolutil/CommonData.h>
#include <libsolutil/BooleanLP.h>
#include <utility>
#include <memory>
@@ -40,7 +42,10 @@ using namespace solidity::smtutil;
void ReasoningBasedSimplifier::run(OptimiserStepContext& _context, Block& _ast)
{
set<YulString> ssaVars = SSAValueTracker::ssaVariables(_ast);
ReasoningBasedSimplifier{_context.dialect, ssaVars}(_ast);
ReasoningBasedSimplifier simpl{_context.dialect, ssaVars};
// Hack to inject the boolean lp solver.
simpl.m_solver = make_unique<BooleanLPSolver>();
simpl(_ast);
}
std::optional<string> ReasoningBasedSimplifier::invalidInCurrentEnvironment()
@@ -120,12 +125,21 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
switch (_instruction)
{
case evmasm::Instruction::ADD:
return wrap(arguments.at(0) + arguments.at(1));
{
auto result = arguments.at(0) + arguments.at(1) - (bigint(1) << 256) * newZeroOneVariable();
restrictToEVMWord(result);
return result;
}
case evmasm::Instruction::MUL:
return wrap(arguments.at(0) * arguments.at(1));
case evmasm::Instruction::SUB:
return wrap(arguments.at(0) - arguments.at(1));
{
auto result = arguments.at(0) - arguments.at(1) + (bigint(1) << 256) * newZeroOneVariable();
restrictToEVMWord(result);
return result;
}
case evmasm::Instruction::DIV:
// TODO add assertion that result is <= input
return smtutil::Expression::ite(
arguments.at(1) == constantValue(0),
constantValue(0),
@@ -224,3 +238,15 @@ smtutil::Expression ReasoningBasedSimplifier::encodeEVMBuiltin(
}
return newRestrictedVariable();
}
smtutil::Expression ReasoningBasedSimplifier::newZeroOneVariable()
{
smtutil::Expression var = newVariable();
m_solver->addAssertion(var == 0 || var == 1);
return var;
}
void ReasoningBasedSimplifier::restrictToEVMWord(smtutil::Expression _value)
{
m_solver->addAssertion(0 <= _value && _value < bigint(1) << 256);
}
@@ -69,6 +69,9 @@ private:
std::vector<Expression> const& _arguments
) override;
smtutil::Expression newZeroOneVariable();
void restrictToEVMWord(smtutil::Expression _value);
Dialect const& m_dialect;
};
+8
View File
@@ -81,6 +81,11 @@ smtutil::Expression SMTSolver::newVariable()
return m_solver->newVariable(uniqueName(), defaultSort());
}
smtutil::Expression SMTSolver::newBooleanVariable()
{
return m_solver->newVariable(uniqueName(), SortProvider::boolSort);
}
smtutil::Expression SMTSolver::newRestrictedVariable(bigint _maxValue)
{
smtutil::Expression var = newVariable();
@@ -100,6 +105,7 @@ shared_ptr<Sort> SMTSolver::defaultSort() const
smtutil::Expression SMTSolver::booleanValue(smtutil::Expression _value)
{
// TODO should not use ite
return smtutil::Expression::ite(_value, constantValue(1), constantValue(0));
}
@@ -115,6 +121,7 @@ smtutil::Expression SMTSolver::literalValue(Literal const& _literal)
smtutil::Expression SMTSolver::twosComplementToSigned(smtutil::Expression _value)
{
// TODO will that work for LP?
return smtutil::Expression::ite(
_value < smtutil::Expression(bigint(1) << 255),
_value,
@@ -136,6 +143,7 @@ smtutil::Expression SMTSolver::wrap(smtutil::Expression _value)
smtutil::Expression rest = newRestrictedVariable();
smtutil::Expression multiplier = newVariable();
m_solver->addAssertion(_value == multiplier * smtutil::Expression(bigint(1) << 256) + rest);
m_solver->addAssertion(0 <= rest && rest < bigint(1) << 256);
return rest;
}
+1
View File
@@ -68,6 +68,7 @@ protected:
static smtutil::Expression bv2int(smtutil::Expression _arg);
smtutil::Expression newVariable();
smtutil::Expression newBooleanVariable();
virtual smtutil::Expression newRestrictedVariable(bigint _maxValue = (bigint(1) << 256) - 1);
std::string uniqueName();