mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
encoding
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user