1
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

contract Test {
    uint num = 2 * 2 + 10;
}

For example, when compiling the above code in Remix,

PUSH1 80 PUSH1 40 MSTORE PUSH1 0e PUSH1 00 SSTORE CALLVALUE DUP1 
ISZERO PUSH1 14 JUMPI PUSH1 00 DUP1 REVERT JUMPDEST POP PUSH1 3f 
DUP1 PUSH1 22 PUSH1 00 CODECOPY PUSH1 00 RETURN INVALID PUSH1 80 
PUSH1 40 MSTORE PUSH1 00 DUP1 REVERT INVALID LOG2 PUSH5 6970667358 
INVALID SLT SHA3 CREATE SELFDESTRUCT INVALID INVALID DUP16 INVALID 
PUSH22 d90e58eb53e493f888d414bd8d524536395032c9202b XOR 
PUSH25 b864736f6c634300080d0033

I got the same opcode as above. There is no opcode for 2*2+10 here.

PUSH1 0e PUSH1 00 SSTORE

just saved(SSTORE) 14(0x0e).

.

enter image description here

I found the image info in the assembly of the compilation details. Here 2*2+10 is calculated.

Questions

  • Doesn't EVM run operations(add/sub/div/mul) with opcodes?
  • When did the EVM work 2 * 2 + 10?
3
  • 1
    why do you want the EVM to do more work than necessary? you pay for that work every time you run the contract! Commented Apr 14, 2023 at 14:44
  • Um... I don't think it's necessary. But there is 2 +2 * 10 in the code, I wonder why the calculation process is not in the opcode.
    – imelon2
    Commented Apr 14, 2023 at 15:25
  • The compiler is not stupid and can see that 2*2+10 is 14. Almost every compiler does this simple optimization which is called constant folding Commented Apr 15, 2023 at 6:23

2 Answers 2

1

I was able to find the answer in the solidity optimizer.

The opcode-based optimizer applies a set of simplification rules to opcodes. It also combines equal code sets and removes unused code.

EVM simplification rules

enter image description here Some logic seems to be removed from the opcode operation according to a set of rules set by the EVM.

1

The right hand side 2 * 2 + 10 is constant at compile time so the compiler will precompute it.

If you use another variable it will be computed at runtime. The bytecode will be larger because it will contain the overflow checks.

contract Test {
    uint x = 2;
    uint num = 2 * x + 10;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.