You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The opcode sequence 'DUPx ... JUMPI POP' indicates that the duplicated value is redundant and not utilized. Eliminating such redundant operations could lead to gas savings.
Description
function and(uint256 a, uint256 b) public returns(uint256) {
if (a > b || a > 100) {
return a - b;
}
return a+b;
}
The above function will generate the following assembly code.
...
tag_7:
/* "condition.sol":270:277 uint256 */
0x00
/* "condition.sol":297:298 b */
dup2
/* "condition.sol":293:294 a */
dup4
/* "condition.sol":293:298 a > b */
gt
/* "condition.sol":293:309 a > b || a > 100 */
dup1
tag_11
jumpi
pop
/* "condition.sol":306:309 100 */
0x64
/* "condition.sol":302:303 a */
dup4
/* "condition.sol":302:309 a > 100 */
gt
/* "condition.sol":293:309 a > b || a > 100 */
tag_11:
/* "condition.sol":289:348 if (a > b || a > 100) {... */
iszero
tag_12
jumpi
/* "condition.sol":336:337 b */
dup2
/* "condition.sol":332:333 a */
dup4
/* "condition.sol":332:337 a - b */
tag_13
swap2
swap1
tag_14
jump // in
tag_13:
/* "condition.sol":325:337 return a - b */
swap1
pop
jump(tag_10)
/* "condition.sol":289:348 if (a > b || a > 100) {... */
tag_12:
/* "condition.sol":366:367 b */
dup2
/* "condition.sol":364:365 a */
dup4
/* "condition.sol":364:367 a+b */
tag_15
swap2
swap1
tag_16
jump // in
…
In tag_7, there is a 'POP' just after 'JUMPI', which means the DUP value is not used. Although this value is used in the other branch(tag_11), this can be optimized by changing the order of the opcodes in these two branches.
Optimization
Specifically, moving tag_12 before tag_11 would achieve this optimization. The resulting assembly code is as follows:
...
tag_7:
/* "condition.sol":270:277 uint256 */
0x00
/* "condition.sol":297:298 b */
dup2
/* "condition.sol":293:294 a */
dup4
/* "condition.sol":293:298 a > b */
gt
/* "condition.sol":293:309 a > b || a > 100 */
tag_11
jumpi
/* "condition.sol":306:309 100 */
0x64
/* "condition.sol":302:303 a */
dup4
/* "condition.sol":302:309 a > 100 */
gt
/* "condition.sol":293:309 a > b || a > 100 */
tag_11
jumpi
tag_12:
/* "condition.sol":366:367 b */
dup2
/* "condition.sol":364:365 a */
dup4
/* "condition.sol":364:367 a+b */
tag_15
swap2
swap1
tag_16
jump // in
tag_11:
/* "condition.sol":336:337 b */
dup2
/* "condition.sol":332:333 a */
dup4
/* "condition.sol":332:337 a - b */
tag_13
swap2
swap1
tag_14
jump // in
tag_13:
/* "condition.sol":325:337 return a - b */
swap1
pop
jump(tag_10)
/* "condition.sol":289:348 if (a > b || a > 100) {... */
…
This could save one DUP1, ISZERO, PUSH, JUMPI for the 'a > b' condition and one DUP1, POP, ISZERO for 'a <= b'. Other cases that generate POP after JUMPI, such as an external call with try/catch which generates "DUP1 ISZERO PUSH2 JUMPI POP", may also be optimized in this way.
The text was updated successfully, but these errors were encountered:
Abstract
The opcode sequence 'DUPx ... JUMPI POP' indicates that the duplicated value is redundant and not utilized. Eliminating such redundant operations could lead to gas savings.
Description
The above function will generate the following assembly code.
In tag_7, there is a 'POP' just after 'JUMPI', which means the DUP value is not used. Although this value is used in the other branch(tag_11), this can be optimized by changing the order of the opcodes in these two branches.
Optimization
Specifically, moving tag_12 before tag_11 would achieve this optimization. The resulting assembly code is as follows:
This could save one DUP1, ISZERO, PUSH, JUMPI for the 'a > b' condition and one DUP1, POP, ISZERO for 'a <= b'. Other cases that generate POP after JUMPI, such as an external call with try/catch which generates "DUP1 ISZERO PUSH2 JUMPI POP", may also be optimized in this way.
The text was updated successfully, but these errors were encountered: