ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
22.66k stars 5.62k forks source link

Redundant DUP1 and POP in CallValueCheck #15165

Open molly-ting opened 1 month ago

molly-ting commented 1 month ago

Description

https://github.com/ethereum/solidity/blob/b849b327781cb71478709b28c4d0d372492cbdc1/libsolidity/codegen/ContractCompiler.cpp#L141-L146 The call value check will generate the following opcodes:

CALLVALUE DUP1 ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST POP

The original value of the first DUP1 is not used; it is not accessed in the revert branch and popped in the other branch. Therefore, the DUP1 operation is redundant. I think we can directly use the original value. The optimized opcodes could be:

CALLVALUE ISZERO PUSH2 0x10 JUMPI PUSH1 0x0 DUP1 REVERT JUMPDEST

Optimization

https://github.com/ethereum/solidity/blob/b849b327781cb71478709b28c4d0d372492cbdc1/libsolidity/codegen/CompilerContext.cpp#L357-L370 In this case, the function revertReasonIfDebug returns "revert(0,0)". For this special case, could we simply return the optimized opcodes to eliminate the redundant dup1 and pop? https://github.com/ethereum/solidity/blob/b849b327781cb71478709b28c4d0d372492cbdc1/libsolidity/codegen/CompilerContext.cpp#L427-L428 Or is it possible to optimize this dup1 and remove the pop in function appendConditionalRevert?