Skip to content

Commit a33da17

Browse files
ekpyroncameel
andcommitted
Bugfix and tests.
Co-authored-by: Kamil Śliwak <[email protected]>
1 parent d5e2925 commit a33da17

7 files changed

+164
-2
lines changed

libyul/optimiser/UnusedStoreEliminator.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,13 @@ void UnusedStoreEliminator::operator()(FunctionCall const& _functionCall)
105105
else
106106
sideEffects = m_controlFlowSideEffects.at(_functionCall.functionName.name);
107107

108+
if (sideEffects.canTerminate)
109+
changeUndecidedTo(State::Used, Location::Storage);
108110
if (!sideEffects.canContinue)
109111
{
110112
changeUndecidedTo(State::Unused, Location::Memory);
111-
changeUndecidedTo(sideEffects.canTerminate ? State::Used : State::Unused, Location::Storage);
113+
if (!sideEffects.canTerminate)
114+
changeUndecidedTo(State::Unused, Location::Storage);
112115
}
113116
}
114117

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
contract C {
2+
uint public x;
3+
function f() public {
4+
x = 1; // This write used to be removed by the Yul optimizer due to the StorageWriteRemovalBeforeConditionalTermination bug.
5+
g();
6+
x = 2;
7+
}
8+
function g() internal {
9+
if (msg.data.length > 4) return;
10+
assembly { return(0, 0) }
11+
}
12+
}
13+
// ----
14+
// f() ->
15+
// x() -> 1

test/libyul/yulOptimizerTests/unusedStoreEliminator/function_side_effects_3.yul renamed to test/libyul/yulOptimizerTests/unusedStoreEliminator/store_before_conditionally_terminating_function_call.yul

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
}
66
let x := 0
77
let y := 1
8-
sstore(x, y)
8+
sstore(x, y) // used to be removed due to the StorageWriteRemovalBeforeConditionalTermination
99
conditionallyStop()
1010
sstore(x, y)
1111
}
@@ -16,6 +16,7 @@
1616
// {
1717
// let x := 0
1818
// let y := 1
19+
// sstore(x, y)
1920
// conditionallyStop()
2021
// sstore(x, y)
2122
// }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
{
2+
function conditionallyStop() {
3+
if calldataload(0) { leave }
4+
return(0, 0)
5+
}
6+
function g() {
7+
let a := 0
8+
let b := 1
9+
sstore(a, b)
10+
}
11+
let x := 0
12+
let y := 1
13+
let z := 2
14+
switch calldataload(64)
15+
case 0 {
16+
sstore(z, x)
17+
g()
18+
}
19+
default {
20+
sstore(x, z) // used to be removed due to the StorageWriteRemovalBeforeConditionalTermination
21+
}
22+
conditionallyStop()
23+
switch calldataload(32)
24+
case 0 {
25+
revert(0, 0)
26+
}
27+
default {
28+
sstore(x, z)
29+
}
30+
}
31+
// ----
32+
// step: unusedStoreEliminator
33+
//
34+
// {
35+
// {
36+
// let x := 0
37+
// let y := 1
38+
// let z := 2
39+
// switch calldataload(64)
40+
// case 0 {
41+
// sstore(z, x)
42+
// g()
43+
// }
44+
// default { sstore(x, z) }
45+
// conditionallyStop()
46+
// switch calldataload(32)
47+
// case 0 { revert(0, 0) }
48+
// default { sstore(x, z) }
49+
// }
50+
// function conditionallyStop()
51+
// {
52+
// if calldataload(0) { leave }
53+
// return(0, 0)
54+
// }
55+
// function g()
56+
// {
57+
// let a := 0
58+
// sstore(a, 1)
59+
// }
60+
// }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
function conditionallyStop() {
3+
if calldataload(0) { leave }
4+
return(0, 0)
5+
}
6+
let x := 0
7+
let y := 1
8+
sstore(x, y) // used to be removed due to the to the StorageWriteRemovalBeforeConditionalTermination bug
9+
conditionallyStop()
10+
revert(0,0)
11+
}
12+
// ----
13+
// step: unusedStoreEliminator
14+
//
15+
// {
16+
// {
17+
// let x := 0
18+
// sstore(x, 1)
19+
// conditionallyStop()
20+
// revert(0, 0)
21+
// }
22+
// function conditionallyStop()
23+
// {
24+
// if calldataload(0) { leave }
25+
// return(0, 0)
26+
// }
27+
// }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
function conditionallyStop() {
3+
if calldataload(0) { leave }
4+
returnEmpty()
5+
}
6+
function returnEmpty() {
7+
return(0, 0)
8+
}
9+
let x := 0
10+
let y := 1
11+
sstore(x, y) // used to be removed due to a bug
12+
conditionallyStop()
13+
sstore(x, y)
14+
}
15+
// ----
16+
// step: unusedStoreEliminator
17+
//
18+
// {
19+
// {
20+
// let x := 0
21+
// let y := 1
22+
// sstore(x, y)
23+
// conditionallyStop()
24+
// sstore(x, y)
25+
// }
26+
// function conditionallyStop()
27+
// {
28+
// if calldataload(0) { leave }
29+
// returnEmpty()
30+
// }
31+
// function returnEmpty()
32+
// { return(0, 0) }
33+
// }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
function neverStop() {
3+
if calldataload(0) { leave } // prevent inlining
4+
}
5+
let x := 0
6+
let y := 1
7+
sstore(x, y) // should be removed
8+
neverStop()
9+
sstore(x, y)
10+
}
11+
// ----
12+
// step: unusedStoreEliminator
13+
//
14+
// {
15+
// {
16+
// let x := 0
17+
// let y := 1
18+
// neverStop()
19+
// sstore(x, y)
20+
// }
21+
// function neverStop()
22+
// { if calldataload(0) { leave } }
23+
// }

0 commit comments

Comments
 (0)