aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/cmdlineTests.sh8
-rw-r--r--test/libyul/Common.cpp2
-rw-r--r--test/libyul/YulOptimizerTest.cpp21
-rw-r--r--test/libyul/yulOptimizerTests/commonSubexpressionEliminator/scopes.yul25
-rw-r--r--test/libyul/yulOptimizerTests/disambiguator/long_names.yul12
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/double_inline.yul30
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul10
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul43
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul36
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/long_names.yul25
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul17
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul31
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul62
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/multi_return.yul13
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/no_return.yul6
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul43
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/pop_result.yul13
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/recursion.yul18
-rw-r--r--test/libyul/yulOptimizerTests/fullInliner/simple.yul10
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul10
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/constants.yul9
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul9
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul10
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul11
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul13
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul17
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/invariant.yul17
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul9
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul9
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul14
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul17
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul14
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul12
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/reversed.yul10
-rw-r--r--test/libyul/yulOptimizerTests/fullSimplify/smoke.yul5
35 files changed, 550 insertions, 61 deletions
diff --git a/test/cmdlineTests.sh b/test/cmdlineTests.sh
index 20254ef4..a8261693 100755
--- a/test/cmdlineTests.sh
+++ b/test/cmdlineTests.sh
@@ -292,6 +292,14 @@ SOLTMPDIR=$(mktemp -d)
if [[ "$result" != 0 ]] ; then
exit 1
fi
+
+ # This should not fail
+ set +e
+ output=$(echo '' | "$SOLC" --ast - 2>/dev/null)
+ set -e
+ if [[ $? != 0 ]] ; then
+ exit 1
+ fi
)
printTask "Testing soljson via the fuzzer..."
diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp
index 4c50180a..d224bdcd 100644
--- a/test/libyul/Common.cpp
+++ b/test/libyul/Common.cpp
@@ -86,7 +86,7 @@ pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::yul::test::p
assembly::Block dev::yul::test::disambiguate(string const& _source, bool _yul)
{
auto result = parse(_source, _yul);
- return boost::get<Block>(Disambiguator(*result.second)(*result.first));
+ return boost::get<Block>(Disambiguator(*result.second, {})(*result.first));
}
string dev::yul::test::format(string const& _source, bool _yul)
diff --git a/test/libyul/YulOptimizerTest.cpp b/test/libyul/YulOptimizerTest.cpp
index ea8e4b5e..fabc05ca 100644
--- a/test/libyul/YulOptimizerTest.cpp
+++ b/test/libyul/YulOptimizerTest.cpp
@@ -106,8 +106,7 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
}
else if (m_optimizerStep == "expressionSplitter")
{
- NameDispenser nameDispenser;
- nameDispenser.m_usedNames = NameCollector(*m_ast).names();
+ NameDispenser nameDispenser(*m_ast);
ExpressionSplitter{nameDispenser}(*m_ast);
}
else if (m_optimizerStep == "functionGrouper")
@@ -130,7 +129,10 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
disambiguate();
(FunctionHoister{})(*m_ast);
(FunctionGrouper{})(*m_ast);
- FullInliner(*m_ast).run();
+ NameDispenser nameDispenser(*m_ast);
+ ExpressionSplitter{nameDispenser}(*m_ast);
+ FullInliner(*m_ast, nameDispenser).run();
+ ExpressionJoiner::run(*m_ast);
}
else if (m_optimizerStep == "mainFunction")
{
@@ -146,7 +148,18 @@ bool YulOptimizerTest::run(ostream& _stream, string const& _linePrefix, bool con
else if (m_optimizerStep == "expressionSimplifier")
{
disambiguate();
- (ExpressionSimplifier{})(*m_ast);
+ ExpressionSimplifier::run(*m_ast);
+ }
+ else if (m_optimizerStep == "fullSimplify")
+ {
+ disambiguate();
+ NameDispenser nameDispenser(*m_ast);
+ 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")
{
diff --git a/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/scopes.yul b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/scopes.yul
new file mode 100644
index 00000000..49b4c916
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/commonSubexpressionEliminator/scopes.yul
@@ -0,0 +1,25 @@
+{
+ let a := 10
+ let x := 20
+ {
+ let b := calldataload(0)
+ let d := calldataload(1)
+ x := d
+ }
+ // We had a bug where "calldataload(0)" was incorrectly replaced by "b"
+ mstore(0, calldataload(0))
+ mstore(0, x)
+}
+// ----
+// commonSubexpressionEliminator
+// {
+// let a := 10
+// let x := 20
+// {
+// let b := calldataload(0)
+// let d := calldataload(1)
+// x := d
+// }
+// mstore(0, calldataload(0))
+// mstore(0, x)
+// }
diff --git a/test/libyul/yulOptimizerTests/disambiguator/long_names.yul b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul
new file mode 100644
index 00000000..933e1e8f
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/disambiguator/long_names.yul
@@ -0,0 +1,12 @@
+// yul
+{ { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } { let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256 } }
+// ----
+// disambiguator
+// {
+// {
+// let aanteuhdaoneudbrgkjiuaothduiathudaoeuh:u256
+// }
+// {
+// let aanteuhdaoneudbrgkjiuaothduiathudaoeuh_1:u256
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul b/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul
new file mode 100644
index 00000000..dd1c1f8a
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/double_inline.yul
@@ -0,0 +1,30 @@
+{
+ function f(a) -> b, c { let x := mload(a) b := sload(x) c := 3 }
+ let a1 := calldataload(0)
+ let b3, c3 := f(a1)
+ let b4, c4 := f(c3)
+}
+// ----
+// fullInliner
+// {
+// {
+// let f_a := calldataload(0)
+// let f_b
+// let f_c
+// f_b := sload(mload(f_a))
+// f_c := 3
+// let b3 := f_b
+// let f_a_1 := f_c
+// let f_b_1
+// let f_c_1
+// f_b_1 := sload(mload(f_a_1))
+// f_c_1 := 3
+// let b4 := f_b_1
+// let c4 := f_c_1
+// }
+// function f(a) -> b, c
+// {
+// b := sload(mload(a))
+// c := 3
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul
index 76b6054b..00bb6577 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/inside_condition.yul
@@ -12,14 +12,12 @@
// fullInliner
// {
// {
-// let _1 := mload(0)
+// let _2 := mload(0)
// let f_a := mload(1)
// let f_r
-// {
-// f_a := mload(f_a)
-// f_r := add(f_a, calldatasize())
-// }
-// if gt(f_r, _1)
+// f_a := mload(f_a)
+// f_r := add(f_a, calldatasize())
+// if gt(f_r, _2)
// {
// sstore(0, 2)
// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul
new file mode 100644
index 00000000..0972ac56
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/large_function_multi_use.yul
@@ -0,0 +1,43 @@
+{
+ function f(a) -> b {
+ let x := mload(a)
+ b := sload(x)
+ let c := 3
+ mstore(mul(a, b), mload(x))
+ let y := add(a, x)
+ sstore(y, 10)
+ }
+ let a := mload(2)
+ let a2 := 2
+ // This should not be inlined because it is not a constant
+ let r := f(a)
+ // This should be inlined because it is a constant
+ let t := f(a2)
+}
+// ----
+// fullInliner
+// {
+// {
+// let a_1 := mload(2)
+// let a2 := 2
+// let r := f(a_1)
+// let f_a := a2
+// let f_b
+// let f_x := mload(f_a)
+// f_b := sload(f_x)
+// let f_c := 3
+// mstore(mul(f_a, f_b), mload(f_x))
+// let f_y := add(f_a, f_x)
+// sstore(f_y, 10)
+// let t := f_b
+// }
+// function f(a) -> b
+// {
+// let x := mload(a)
+// b := sload(x)
+// let c := 3
+// mstore(mul(a, b), mload(x))
+// let y := add(a, x)
+// sstore(y, 10)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul b/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul
new file mode 100644
index 00000000..3302a35c
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/large_function_single_use.yul
@@ -0,0 +1,36 @@
+{
+ function f(a) -> b {
+ let x := mload(a)
+ b := sload(x)
+ let c := 3
+ mstore(mul(a, b), mload(x))
+ let y := add(a, x)
+ sstore(y, 10)
+ }
+ // Single-use functions are always inlined.
+ let r := f(mload(1))
+}
+// ----
+// fullInliner
+// {
+// {
+// let f_a := mload(1)
+// let f_b
+// let f_x := mload(f_a)
+// f_b := sload(f_x)
+// let f_c := 3
+// mstore(mul(f_a, f_b), mload(f_x))
+// let f_y := add(f_a, f_x)
+// sstore(f_y, 10)
+// let r := f_b
+// }
+// function f(a) -> b
+// {
+// let x := mload(a)
+// b := sload(x)
+// let c := 3
+// mstore(mul(a, b), mload(x))
+// let y := add(a, x)
+// sstore(y, 10)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/long_names.yul b/test/libyul/yulOptimizerTests/fullInliner/long_names.yul
new file mode 100644
index 00000000..644e9126
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/long_names.yul
@@ -0,0 +1,25 @@
+{
+ function verylongfunctionname(verylongvariablename) -> verylongvariablename2 {
+ verylongvariablename2 := add(verylongvariablename, verylongvariablename)
+ }
+ // same long name
+ let verylongvariablename2 := 3
+ mstore(0, verylongfunctionname(verylongvariablename2))
+ mstore(1, verylongvariablename2)
+}
+// ----
+// fullInliner
+// {
+// {
+// let verylongvariablename2_1 := 3
+// let verylongfu_verylongvariablename := verylongvariablename2_1
+// let verylongfu_verylongvariablename2
+// verylongfu_verylongvariablename2 := add(verylongfu_verylongvariablename, verylongfu_verylongvariablename)
+// mstore(0, verylongfu_verylongvariablename2)
+// mstore(1, verylongvariablename2_1)
+// }
+// function verylongfunctionname(verylongvariablename) -> verylongvariablename2
+// {
+// verylongvariablename2 := add(verylongvariablename, verylongvariablename)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul
index e1def585..f3d0b286 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/move_up_rightwards_argument.yul
@@ -9,16 +9,17 @@
// fullInliner
// {
// {
-// let _1 := mload(5)
-// let f_c := mload(4)
-// let f_b := mload(3)
+// let _2 := mload(5)
+// let _4 := mload(4)
+// let _6 := mload(3)
// let f_a := mload(2)
+// let f_b := _6
+// let f_c := _4
// let f_x
-// {
-// f_x := add(f_a, f_b)
-// f_x := mul(f_x, f_c)
-// }
-// let y := add(mload(1), add(f_x, _1))
+// f_x := add(f_a, f_b)
+// f_x := mul(f_x, f_c)
+// let _10 := add(f_x, _2)
+// let y := add(mload(1), _10)
// }
// function f(a, b, c) -> x
// {
diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul
index 94bbe5dc..c704944d 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun.yul
@@ -7,21 +7,14 @@
// fullInliner
// {
// {
-// let g_c := 7
-// let f_a_1 := 3
-// let f_x_1
-// {
-// f_x_1 := add(f_a_1, f_a_1)
-// }
+// let _1 := 7
+// let f_a := 3
+// let f_x
+// f_x := add(f_a, f_a)
+// let g_b := f_x
+// let g_c := _1
// let g_y
-// {
-// let g_f_a := f_x_1
-// let g_f_x
-// {
-// g_f_x := add(g_f_a, g_f_a)
-// }
-// g_y := mul(mload(g_c), g_f_x)
-// }
+// g_y := mul(mload(g_c), f(g_b))
// let y_1 := g_y
// }
// function f(a) -> x
@@ -30,11 +23,9 @@
// }
// function g(b, c) -> y
// {
-// let f_a := b
-// let f_x
-// {
-// f_x := add(f_a, f_a)
-// }
-// y := mul(mload(c), f_x)
+// let f_a_1 := b
+// let f_x_1
+// f_x_1 := add(f_a_1, f_a_1)
+// y := mul(mload(c), f_x_1)
// }
// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul
new file mode 100644
index 00000000..bcdba8e0
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/multi_fun_callback.yul
@@ -0,0 +1,62 @@
+{
+ // This is a test for an older version where
+ // inlining was performed on a function
+ // just being called. This is a problem
+ // because the statemenst of the original
+ // function might be in an invalid state.
+
+ function f(x) {
+ mstore(0, x)
+ mstore(7, h())
+ g(10)
+ mstore(1, x)
+ }
+ function g(x) {
+ f(1)
+ }
+ function h() -> t {
+ t := 2
+
+ }
+ {
+ f(100)
+ }
+}
+// ----
+// fullInliner
+// {
+// {
+// {
+// let f_x := 100
+// mstore(0, f_x)
+// mstore(7, h())
+// g(10)
+// mstore(1, f_x)
+// }
+// }
+// function f(x)
+// {
+// mstore(0, x)
+// let h_t
+// h_t := 2
+// mstore(7, h_t)
+// let g_x_1 := 10
+// f(1)
+// mstore(1, x)
+// }
+// function g(x_1)
+// {
+// let f_x_1 := 1
+// mstore(0, f_x_1)
+// let f_h_t
+// f_h_t := 2
+// mstore(7, f_h_t)
+// let f_g_x_1 := 10
+// f(1)
+// mstore(1, f_x_1)
+// }
+// function h() -> t
+// {
+// t := 2
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul
index f3c5b0ee..eebdec38 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/multi_return.yul
@@ -1,17 +1,22 @@
-// The full inliner currently does not work with
-// functions returning multiple values.
{
function f(a) -> x, y {
x := mul(a, a)
y := add(a, x)
}
- let a, b := f(mload(0))
+ let r, s := f(mload(0))
+ mstore(r, s)
}
// ----
// fullInliner
// {
// {
-// let a_1, b := f(mload(0))
+// let f_a := mload(0)
+// let f_x
+// let f_y
+// f_x := mul(f_a, f_a)
+// f_y := add(f_a, f_x)
+// let r := f_x
+// mstore(r, f_y)
// }
// function f(a) -> x, y
// {
diff --git a/test/libyul/yulOptimizerTests/fullInliner/no_return.yul b/test/libyul/yulOptimizerTests/fullInliner/no_return.yul
index 53fe3527..3708c557 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/no_return.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/no_return.yul
@@ -9,11 +9,7 @@
// {
// {
// let f_a := mload(0)
-// {
-// sstore(f_a, f_a)
-// }
-// {
-// }
+// sstore(f_a, f_a)
// }
// function f(a)
// {
diff --git a/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul b/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul
new file mode 100644
index 00000000..44fc7b21
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/not_inside_for.yul
@@ -0,0 +1,43 @@
+{
+ for { let x := f(0) } f(x) { x := f(x) }
+ {
+ let t := f(x)
+ }
+ function f(a) -> r {
+ sstore(a, 0)
+ r := a
+ }
+}
+// ----
+// fullInliner
+// {
+// {
+// for {
+// let f_a := 0
+// let f_r
+// sstore(f_a, 0)
+// f_r := f_a
+// let x := f_r
+// }
+// f(x)
+// {
+// let f_a_1 := x
+// let f_r_1
+// sstore(f_a_1, 0)
+// f_r_1 := f_a_1
+// x := f_r_1
+// }
+// {
+// let f_a_2 := x
+// let f_r_2
+// sstore(f_a_2, 0)
+// f_r_2 := f_a_2
+// let t := f_r_2
+// }
+// }
+// function f(a) -> r
+// {
+// sstore(a, 0)
+// r := a
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul
index 3883c67c..cd9e2746 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/pop_result.yul
@@ -1,4 +1,6 @@
-// This tests that `pop(r)` is removed.
+// An earlier version of the inliner produced
+// pop(...) statements and explicitly removed them.
+// This used to test that they are removed.
{
function f(a) -> x {
let r := mul(a, a)
@@ -13,12 +15,9 @@
// let _1 := 2
// let f_a := 7
// let f_x
-// {
-// let f_r := mul(f_a, f_a)
-// f_x := add(f_r, f_r)
-// }
-// {
-// }
+// let f_r := mul(f_a, f_a)
+// f_x := add(f_r, f_r)
+// pop(add(f_x, _1))
// }
// function f(a) -> x
// {
diff --git a/test/libyul/yulOptimizerTests/fullInliner/recursion.yul b/test/libyul/yulOptimizerTests/fullInliner/recursion.yul
new file mode 100644
index 00000000..3e9a8021
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullInliner/recursion.yul
@@ -0,0 +1,18 @@
+{
+ function f(a) {
+ f(1)
+ }
+ f(mload(0))
+}
+// ----
+// fullInliner
+// {
+// {
+// let f_a := mload(0)
+// f(1)
+// }
+// function f(a)
+// {
+// f(1)
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullInliner/simple.yul b/test/libyul/yulOptimizerTests/fullInliner/simple.yul
index dd1a4e0a..fcdf453b 100644
--- a/test/libyul/yulOptimizerTests/fullInliner/simple.yul
+++ b/test/libyul/yulOptimizerTests/fullInliner/simple.yul
@@ -9,14 +9,12 @@
// fullInliner
// {
// {
-// let _1 := mload(7)
+// let _2 := mload(7)
// let f_a := sload(mload(2))
// let f_x
-// {
-// let f_r := mul(f_a, f_a)
-// f_x := add(f_r, f_r)
-// }
-// let y := add(f_x, _1)
+// let f_r := mul(f_a, f_a)
+// f_x := add(f_r, f_r)
+// let y := add(f_x, _2)
// }
// function f(a) -> x
// {
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul b/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul
new file mode 100644
index 00000000..90a3e16d
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/constant_propagation.yul
@@ -0,0 +1,10 @@
+{
+ let a := add(7, sub(mload(0), 7))
+ mstore(a, 0)
+}
+// ----
+// fullSimplify
+// {
+// let _2 := 0
+// mstore(mload(_2), _2)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/constants.yul b/test/libyul/yulOptimizerTests/fullSimplify/constants.yul
new file mode 100644
index 00000000..b9c7c1fc
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/constants.yul
@@ -0,0 +1,9 @@
+{
+ let a := add(1, mul(3, 4))
+ mstore(0, a)
+}
+// ----
+// fullSimplify
+// {
+// mstore(0, 13)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul
new file mode 100644
index 00000000..4b17d7ea
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_complex.yul
@@ -0,0 +1,9 @@
+{
+ let a := sub(calldataload(0), calldataload(0))
+ mstore(a, 0)
+}
+// ----
+// fullSimplify
+// {
+// mstore(0, 0)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul
new file mode 100644
index 00000000..a1737efa
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_negative.yul
@@ -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)))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul
new file mode 100644
index 00000000..22a358fd
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/identity_rules_simple.yul
@@ -0,0 +1,11 @@
+{
+ let a := mload(0)
+ mstore(0, sub(a, a))
+}
+// ----
+// fullSimplify
+// {
+// let _1 := 0
+// pop(mload(_1))
+// mstore(_1, 0)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul b/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul
new file mode 100644
index 00000000..fa3ff07c
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/including_function_calls.yul
@@ -0,0 +1,13 @@
+{
+ function f() -> a {}
+ let b := add(7, sub(f(), 7))
+ mstore(b, 0)
+}
+// ----
+// fullSimplify
+// {
+// function f() -> a
+// {
+// }
+// mstore(f(), 0)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul b/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul
new file mode 100644
index 00000000..f1b40301
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/inside_for.yul
@@ -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)
+// }
+// {
+// }
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul b/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul
new file mode 100644
index 00000000..a8eedef1
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/invariant.yul
@@ -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))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul
new file mode 100644
index 00000000..bba16a94
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_1.yul
@@ -0,0 +1,9 @@
+{
+ mstore(0, mod(calldataload(0), exp(2, 8)))
+}
+// ----
+// fullSimplify
+// {
+// let _4 := 0
+// mstore(_4, and(calldataload(_4), 255))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul
new file mode 100644
index 00000000..4a6eaa52
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/mod_and_2.yul
@@ -0,0 +1,9 @@
+{
+ mstore(0, mod(calldataload(0), exp(2, 255)))
+}
+// ----
+// fullSimplify
+// {
+// let _4 := 0
+// mstore(_4, and(calldataload(_4), 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul
new file mode 100644
index 00000000..0c5e3ed9
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_arguments.yul
@@ -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))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul
new file mode 100644
index 00000000..90e89fe1
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_different_names.yul
@@ -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()))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul
new file mode 100644
index 00000000..92e50ebe
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_function_call_equality_not_movable.yul
@@ -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()))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul
new file mode 100644
index 00000000..7dcdc280
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/not_applied_removes_non_constant_and_not_movable.yul
@@ -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)
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul b/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul
new file mode 100644
index 00000000..fb916e6a
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/reversed.yul
@@ -0,0 +1,10 @@
+{
+ let a := add(0, mload(0))
+ mstore(0, a)
+}
+// ----
+// fullSimplify
+// {
+// let _1 := 0
+// mstore(_1, mload(_1))
+// }
diff --git a/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul b/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul
new file mode 100644
index 00000000..a4fbb899
--- /dev/null
+++ b/test/libyul/yulOptimizerTests/fullSimplify/smoke.yul
@@ -0,0 +1,5 @@
+{ }
+// ----
+// fullSimplify
+// {
+// }