Add a "full simplify" test that applies multiple elementary transforms.

This commit is contained in:
chriseth 2018-10-11 21:16:37 +02:00
parent a320eec7d3
commit ffe44536fe
17 changed files with 198 additions and 0 deletions

View File

@ -148,6 +148,18 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
disambiguate();
ExpressionSimplifier::run(*m_ast);
}
else if (m_optimizerStep == "fullSimplify")
{
disambiguate();
NameDispenser nameDispenser;
nameDispenser.m_usedNames = NameCollector(*m_ast).names();
ExpressionSplitter{nameDispenser}(*m_ast);
CommonSubexpressionEliminator{}(*m_ast);
ExpressionSimplifier::run(*m_ast);
UnusedPruner::runUntilStabilised(*m_ast);
ExpressionJoiner::run(*m_ast);
ExpressionJoiner::run(*m_ast);
}
else if (m_optimizerStep == "unusedPruner")
{
disambiguate();

View File

@ -0,0 +1,10 @@
{
let a := add(7, sub(mload(0), 7))
mstore(a, 0)
}
// ----
// fullSimplify
// {
// let _2 := 0
// mstore(mload(_2), _2)
// }

View File

@ -0,0 +1,9 @@
{
let a := add(1, mul(3, 4))
mstore(0, a)
}
// ----
// fullSimplify
// {
// mstore(0, 13)
// }

View File

@ -0,0 +1,9 @@
{
let a := sub(calldataload(0), calldataload(0))
mstore(a, 0)
}
// ----
// fullSimplify
// {
// mstore(0, 0)
// }

View File

@ -0,0 +1,10 @@
{
let a := sub(calldataload(1), calldataload(0))
mstore(0, a)
}
// ----
// fullSimplify
// {
// let _1 := 0
// mstore(_1, sub(calldataload(1), calldataload(_1)))
// }

View File

@ -0,0 +1,11 @@
{
let a := mload(0)
mstore(0, sub(a, a))
}
// ----
// fullSimplify
// {
// let _1 := 0
// pop(mload(_1))
// mstore(_1, 0)
// }

View File

@ -0,0 +1,13 @@
{
function f() -> a {}
let b := add(7, sub(f(), 7))
mstore(b, 0)
}
// ----
// fullSimplify
// {
// function f() -> a
// {
// }
// mstore(f(), 0)
// }

View File

@ -0,0 +1,17 @@
{
let x := calldataload(3)
for { let a := 10 } iszero(eq(a, sub(x, calldataload(3)))) { a := add(a, 1) } {}
}
// ----
// fullSimplify
// {
// for {
// let a := 10
// }
// iszero(iszero(a))
// {
// a := add(a, 1)
// }
// {
// }
// }

View File

@ -0,0 +1,17 @@
{
let a := calldataload(sub(7, 7))
let b := sub(a, 0)
// Below, `b` is not eliminated, because
// we run CSE and then Simplify.
// Elimination of `b` would require another
// run of CSE afterwards.
mstore(b, eq(calldataload(0), a))
}
// ----
// fullSimplify
// {
// let a := calldataload(0)
// let _4 := 0
// let b := a
// mstore(b, eq(calldataload(_4), a))
// }

View File

@ -0,0 +1,9 @@
{
mstore(0, mod(calldataload(0), exp(2, 8)))
}
// ----
// fullSimplify
// {
// let _4 := 0
// mstore(_4, and(calldataload(_4), 255))
// }

View File

@ -0,0 +1,9 @@
{
mstore(0, mod(calldataload(0), exp(2, 255)))
}
// ----
// fullSimplify
// {
// let _4 := 0
// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff))
// }

View File

@ -0,0 +1,14 @@
{
function f(a) -> b { }
mstore(0, sub(f(0), f(1)))
}
// ----
// fullSimplify
// {
// function f(a) -> b
// {
// }
// let _2 := f(1)
// let _3 := 0
// mstore(_3, sub(f(_3), _2))
// }

View File

@ -0,0 +1,17 @@
{
function f1() -> a { }
function f2() -> b { }
let c := sub(f1(), f2())
mstore(0, c)
}
// ----
// fullSimplify
// {
// function f1() -> a
// {
// }
// function f2() -> b
// {
// }
// mstore(0, sub(f1(), f2()))
// }

View File

@ -0,0 +1,14 @@
// Even if the functions pass the equality check, they are not movable.
{
function f() -> a { }
let b := sub(f(), f())
mstore(0, b)
}
// ----
// fullSimplify
// {
// function f() -> a
// {
// }
// mstore(0, sub(f(), f()))
// }

View File

@ -0,0 +1,12 @@
// div is eliminated, but keccak256 has side-effects.
{
let a := div(keccak256(0, 0), 0)
mstore(0, a)
}
// ----
// fullSimplify
// {
// let _1 := 0
// pop(keccak256(_1, _1))
// mstore(_1, 0)
// }

View File

@ -0,0 +1,10 @@
{
let a := add(0, mload(0))
mstore(0, a)
}
// ----
// fullSimplify
// {
// let _1 := 0
// mstore(_1, mload(_1))
// }

View File

@ -0,0 +1,5 @@
{ }
// ----
// fullSimplify
// {
// }