Skip to content

Conversation

@philippecyberian
Copy link

@philippecyberian philippecyberian commented Dec 1, 2025

Summary

This PR introduces a new peephole optimization that simplifies and reduces the bytecode for Solidity’s function selector guard emitted in the dispatcher of every contract.

The standard guard:

PUSH1 0x04 CALLDATASIZE LT ISZERO PUSH <tag> JUMPI

is replaced with its shorter logically equivalent form:

PUSH1 0x03 CALLDATASIZE GT PUSH <tag> JUMPI

This optimization is safe, local, and formally verified.


Motivation

The function selector guard exists in essentially every Solidity contract.
This PR saves:

  • 1 byte of deployed runtime code (≈ 200 gas)

  • 2 gas per external call (based on execution measured via evmone)

  • Eliminates ISZERO and avoids one stack element.

The optimization applies only when the canonical dispatcher pattern is recognized and the pattern appears immediately after a Tag. This ensures no interference with ABI decoding, length checks, or string/memory operations.


Formal Equivalence

The replacement is proven equivalent by demonstrating:

!(cds < 4) ≡ (cds ≥ 4) ≡ (cds > 3)

An SMT formulation in Z3 confirms no counterexamples exist:

(assert (>= cds 0)) (assert (not (= (ite (< cds 4) 0 1) (ite (> cds 3) 1 0)))) (check-sat) ; unsat

A formal proof sketch (stack transformer equivalence and algebraic equivalence) is included in the Issue:
👉[GitHub Issue #16316]


Changes Included

  • New peephole optimization: FunctionSelectorGuard

  • Restriction: pattern applies only immediately after Tag

  • Unit test verifying:

    • rewrite occurs in valid canonical case

    • rewrite is suppressed when pattern is incomplete or misplaced

  • Measurements demonstrating bytecode and gas savings


Gas & Size Savings Summary

Category Before After Savings
Bytes in guard 5 4 -1 byte
Deployment gas ~200 gas
Execution gas 11 gas 8 gas 3 gas theoretical / 2 gas observed

Request for Review

I would appreciate review focus on:

  1. Pattern matching constraints (only following Tag)

  2. Interaction with future dispatcher variants or EOF changes

  3. Placement order within the peephole optimizer list

  4. Any additional edge cases to include in testing

This PR is intended to be minimal, safe, and consistent with existing peephole optimizations.

@github-actions
Copy link

github-actions bot commented Dec 1, 2025

Thank you for your contribution to the Solidity compiler! A team member will follow up shortly.

If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother.

If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix.

@philippecyberian philippecyberian changed the title Add Peephole Optimization for Function Selector Guard (cds >= 4 → cds > 3) Add Peephole Optimization for Function Selector Guard Dec 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants