Skip to content

Add Branchless library - #6792

Draft
Amxx wants to merge 1 commit into
masterfrom
feat/branchless
Draft

Amxx wants to merge 1 commit into
masterfrom
feat/branchless

Conversation

@Amxx

@Amxx Amxx commented Sep 30, 2026

Copy link
Copy Markdown
Collaborator

Adds a procedurally generated Branchless library. It provides a constant-gas ternary(bool condition, T a, T b) (i.e. condition ? a : b) for the five largest value types: address, bool, bytes32, uint256 and int256.

Each overload computes xor(b, mul(xor(a, b), iszero(iszero(condition)))) in a single assembly block, with no imports. Math.ternary and SignedMath.ternary already cover uint256 and int256; this library extends the same approach to the other value types.

Design notes

  • Large types only. Overloading ternary for every size (uint8…uint256, bytes1…bytes32, …) is ambiguous: a uint8 argument implicitly converts to every wider overload, and solc rejects the call ("not unique after argument-dependent lookup"). Smaller types can instead be passed directly and resolve to the widest type of their family (checked for uint8, int8 and bytes4). The caller downcasts the result, e.g. uint8(Branchless.ternary(c, a, b)).
  • Generated. The source of truth is scripts/generate/templates/Branchless.sol.eta. It loops over TYPES filtered to value types with no upcastTo, so the covered set follows data.js. The Foundry test is generated the same way.
  • As with Math.ternary, the NatSpec warns that the compiler can optimize a native ?: to evaluate a single branch, which may make the native form cheaper.

Open questions

  • Is this worth adding as a separate library, or should it stay in Math / SignedMath and grow there?
  • Should Math.ternary / SignedMath.ternary be made to delegate to it, or left as they are?

PR Checklist

  • Tests
  • Documentation
  • Changeset entry (run npx changeset add)

@changeset-bot

changeset-bot Bot commented Sep 30, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fed3732

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
openzeppelin-solidity Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant