From 633a040b2c64366c1ab8fd87d9cb4d064ca4b767 Mon Sep 17 00:00:00 2001 From: hrkrshnn Date: Wed, 27 Jan 2021 19:42:43 +0100 Subject: [PATCH] Add optimizer tests --- .../various/code_access_padding.sol | 5 +- .../memoryLoadResolver/anothertest.yul | 39 +++++++ .../memoryLoadResolver/calldataload.yul | 6 +- .../memoryLoadResolver/if.yul | 39 +++++++ .../memoryLoadResolver/non_ssa.yul | 26 +++++ .../memoryLoadResolver/proxy.yul | 104 ++++++++++++++++++ 6 files changed, 215 insertions(+), 4 deletions(-) create mode 100644 test/libyul/yulOptimizerTests/memoryLoadResolver/anothertest.yul create mode 100644 test/libyul/yulOptimizerTests/memoryLoadResolver/if.yul create mode 100644 test/libyul/yulOptimizerTests/memoryLoadResolver/non_ssa.yul create mode 100644 test/libyul/yulOptimizerTests/memoryLoadResolver/proxy.yul diff --git a/test/libsolidity/semanticTests/various/code_access_padding.sol b/test/libsolidity/semanticTests/various/code_access_padding.sol index ecad28a16..f35fe8089 100644 --- a/test/libsolidity/semanticTests/various/code_access_padding.sol +++ b/test/libsolidity/semanticTests/various/code_access_padding.sol @@ -14,6 +14,7 @@ contract C { } } } - +// ==== +// compileViaYul: true // ---- -// diff() -> 0 # This checks that the allocation function pads to multiples of 32 bytes # +// diff() -> 11 # This checks that the allocation function pads to multiples of 32 bytes # diff --git a/test/libyul/yulOptimizerTests/memoryLoadResolver/anothertest.yul b/test/libyul/yulOptimizerTests/memoryLoadResolver/anothertest.yul new file mode 100644 index 000000000..ffd72f312 --- /dev/null +++ b/test/libyul/yulOptimizerTests/memoryLoadResolver/anothertest.yul @@ -0,0 +1,39 @@ +{ + + let x := 1 + let y := 2 + let z := 3 + + mstore(x, y) + + let a := calldataload(0) + + if a + { + // resolves to y + let tmp_1 := mload(x) + mstore(x, z) + // resolves to z + let tmp_2 := mload(x) + } + + // should not be able to resolve x + let value := mload(x) +} +// ---- +// step: memoryLoadResolver +// +// { +// let x := 1 +// let y := 2 +// let z := 3 +// mstore(x, y) +// let a := calldataload(0) +// if a +// { +// let tmp_1 := y +// mstore(x, z) +// let tmp_2 := z +// } +// let value := mload(x) +// } diff --git a/test/libyul/yulOptimizerTests/memoryLoadResolver/calldataload.yul b/test/libyul/yulOptimizerTests/memoryLoadResolver/calldataload.yul index bb401965a..9efd2dc62 100644 --- a/test/libyul/yulOptimizerTests/memoryLoadResolver/calldataload.yul +++ b/test/libyul/yulOptimizerTests/memoryLoadResolver/calldataload.yul @@ -24,6 +24,8 @@ // mstore(key, value) // if callvalue() { revert(0, 0) } // let _1 := 0 -// calldatacopy(value, _1, calldatasize()) -// sstore(0, value) +// let c := calldatasize() +// calldatacopy(value, _1, c) +// let out := value +// sstore(0, out) // } diff --git a/test/libyul/yulOptimizerTests/memoryLoadResolver/if.yul b/test/libyul/yulOptimizerTests/memoryLoadResolver/if.yul new file mode 100644 index 000000000..ffd72f312 --- /dev/null +++ b/test/libyul/yulOptimizerTests/memoryLoadResolver/if.yul @@ -0,0 +1,39 @@ +{ + + let x := 1 + let y := 2 + let z := 3 + + mstore(x, y) + + let a := calldataload(0) + + if a + { + // resolves to y + let tmp_1 := mload(x) + mstore(x, z) + // resolves to z + let tmp_2 := mload(x) + } + + // should not be able to resolve x + let value := mload(x) +} +// ---- +// step: memoryLoadResolver +// +// { +// let x := 1 +// let y := 2 +// let z := 3 +// mstore(x, y) +// let a := calldataload(0) +// if a +// { +// let tmp_1 := y +// mstore(x, z) +// let tmp_2 := z +// } +// let value := mload(x) +// } diff --git a/test/libyul/yulOptimizerTests/memoryLoadResolver/non_ssa.yul b/test/libyul/yulOptimizerTests/memoryLoadResolver/non_ssa.yul new file mode 100644 index 000000000..13f9dade2 --- /dev/null +++ b/test/libyul/yulOptimizerTests/memoryLoadResolver/non_ssa.yul @@ -0,0 +1,26 @@ +// Test to see if non-ssa variables are encoded +{ + let x := 2 + x := calldataload(0) + + let y := calldataload(32) + + mstore(x, y) + + // Should not be resolved + let a := mload(x) + + // Makes no sense + let b := mload(y) +} +// ---- +// step: memoryLoadResolver +// +// { +// let x := 2 +// x := calldataload(0) +// let y := calldataload(32) +// mstore(x, y) +// let a := mload(x) +// let b := mload(y) +// } diff --git a/test/libyul/yulOptimizerTests/memoryLoadResolver/proxy.yul b/test/libyul/yulOptimizerTests/memoryLoadResolver/proxy.yul new file mode 100644 index 000000000..e693a2bda --- /dev/null +++ b/test/libyul/yulOptimizerTests/memoryLoadResolver/proxy.yul @@ -0,0 +1,104 @@ +{ + let key := 64 + let value := 128 + + mstore(key, value) + + if callvalue() { revert(0, 0) } + + let _1 := 0 + let c := calldatasize() + + calldatacopy(128, _1, c) + + // Should prove that location key is not invalidated + let key_1 := add(key, c) + mstore(key_1, _1) + let value_at_key := mload(key) + + // Should prove that both key and key_1 are not invalidated + pop(delegatecall(gas(), 25, 128, calldatasize(), _1, _1)) + let value_at_key_ := mload(key) + let value_at_key_1 := mload(key_1) + + let data := _1 + switch returndatasize() + case 0 { data := 96 } + default { + let result := and(add(returndatasize(), 63), not(31)) + + // Should be able to replace by value + let memPtr := mload(key_1) + + let newFreePtr := add(memPtr, result) + + if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) + { + let _tmp := shl(224, 0x4e487b71) + mstore(_1, _tmp) + + let __tmp := 4 + let tmp_val := 0x41 + mstore(__tmp, tmp_val) + + let tmp_val_1 := 0x24 + revert(_1, tmp_val) + } + + mstore(key, newFreePtr) + data := memPtr + + + mstore(memPtr, returndatasize()) + + let tmp_val_2 := 0x20 + let tmp_val_3 := add(memPtr, tmp_val_2) + + returndatacopy(add(memPtr, 0x20), _1, returndatasize()) + } + return(add(data, 0x20), mload(data)) +} + +// ---- +// step: memoryLoadResolver +// +// { +// let key := 64 +// let value := 128 +// mstore(key, value) +// if callvalue() { revert(0, 0) } +// let _1 := 0 +// let c := calldatasize() +// calldatacopy(128, _1, c) +// let key_1 := add(key, c) +// mstore(key_1, _1) +// let value_at_key := mload(key) +// pop(delegatecall(gas(), 25, 128, calldatasize(), _1, _1)) +// let value_at_key_ := mload(key) +// let value_at_key_1 := mload(key_1) +// let data := _1 +// switch returndatasize() +// case 0 { data := 96 } +// default { +// let result := and(add(returndatasize(), 63), not(31)) +// let memPtr := mload(key_1) +// let newFreePtr := add(memPtr, result) +// if or(gt(newFreePtr, 0xffffffffffffffff), lt(newFreePtr, memPtr)) +// { +// let _tmp := shl(224, 0x4e487b71) +// mstore(_1, _tmp) +// let __tmp := 4 +// let tmp_val := 0x41 +// mstore(__tmp, tmp_val) +// let tmp_val_1 := 0x24 +// revert(_1, tmp_val) +// } +// mstore(key, newFreePtr) +// data := memPtr +// mstore(memPtr, returndatasize()) +// let tmp_val_2 := 0x20 +// let tmp_val_3 := add(memPtr, tmp_val_2) +// returndatacopy(add(memPtr, 0x20), _1, returndatasize()) +// } +// return(add(data, 0x20), mload(data)) +// }