Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[stdlib] Support nextafter at compile time - #6787

#6787
Open
VihaanAgarwal wants to merge 1 commit into
modular:mainmodular/modular:mainfrom
VihaanAgarwal:fix/nextafter-comptimeVihaanAgarwal/modular:fix/nextafter-comptimeCopy head branch name to clipboard
Open

[stdlib] Support nextafter at compile time#6787
VihaanAgarwal wants to merge 1 commit into
modular:mainmodular/modular:mainfrom
VihaanAgarwal:fix/nextafter-comptimeVihaanAgarwal/modular:fix/nextafter-comptimeCopy head branch name to clipboard

Conversation

@VihaanAgarwal

Copy link
Copy Markdown

Linked issue

Fixes #6721

Type of change

  • Bug fix (non-breaking change that fixes an issue)

Motivation

Calling nextafter at compile time fails to compile. It only ever dispatches to
libc's nextafter/nextafterf through an external_call, and the comptime
interpreter has no way to execute an external C function, so it bails out with
"failed to run the pass manager". Anyone who reaches nextafter in a comptime
context hits this, and it also blocks math.ulp, which is built on nextafter
(that is the path in the linked issue).

What changed

Added a comptime-interpreter branch to nextafter that computes the neighbour
directly from the IEEE-754 bit pattern, leaving the libc dispatch untouched for
runtime. For a fixed sign, consecutive representable floats have consecutive
integer bit patterns, so stepping toward arg1 is one increment or decrement of
the raw bits. The arg0 == 0, equal-inputs, and NaN cases are handled
explicitly. This follows the same __is_run_in_comptime_interpreter pattern
already used elsewhere in math.mojo, and the branch folds away at runtime so
there is no runtime cost or behaviour change.

Testing

./bazelw test //mojo/stdlib/test/utils:test_numerics.mojo.test //mojo/stdlib/test/math:test_math.mojo.test — both pass.

  • Added test_nextafter_at_comptime covering the up/down, equal,
    zero-to-subnormal, negative, vector, and NaN branches.
  • Added test_ulp_at_comptime so the reporter's original ulp scenario is
    exercised at compile time.
  • Separately cross-checked the fallback against libc nextafter across a large
    sweep of random float32 bit patterns (infinities, subnormals, and
    MAX_FINITE included); every result matched bit for bit.

Checklist

  • The linked issue above has been reviewed by a maintainer and is agreed-upon
  • PR is small and focused
  • I ran the formatter over my changes
  • I added or updated tests to cover my changes
  • AI tools assisted with this contribution; an Assisted-by: trailer is in the commit message

`nextafter` dispatched only to libc `nextafter`/`nextafterf` through an
`external_call`, which the comptime interpreter cannot run, so any call in a
comptime context failed to compile. That also blocked `math.ulp`, which relies
on `nextafter`.

This adds a comptime-interpreter branch that walks to the neighbouring value
straight from the IEEE-754 bit pattern and keeps the libc dispatch for runtime.
Adjacent representable floats of the same sign have adjacent integer bit
patterns, so the step toward `arg1` is a single increment or decrement, with
signed zero and NaN handled explicitly.

Fixes modular#6721

Assisted-by: Claude
@VihaanAgarwal
VihaanAgarwal requested a review from a team as a code owner July 17, 2026 19:46
@github-actions github-actions Bot added mojo-stdlib Tag for issues related to standard library waiting-on-review labels Jul 17, 2026
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@VihaanAgarwal

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

modular-cla-bot Bot added a commit to modular/cla that referenced this pull request Jul 17, 2026
# comptime interpreter cannot execute; these evaluate the branches at
# compile time to guard the pure-Mojo fallback.
comptime up = nextafter(Float64(1), Float64(2))
assert_almost_equal(up, 1.0000000000000002)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions are weaker than they look. assert_almost_equal defaults to atol=1e-8, rtol=1e-5, but nextafter(1, 2) = 1.0000000000000002 differs from 1.0 by only ~2.2e-16 — well inside the tolerance. So this would still pass if the function returned exactly 1.0 (a no-op bug), and likewise the subnormal cases (5e-324 is "almost equal" to 0). Since the whole point of nextafter is the 1-ULP step, please use assert_equal here for exact-bit checking. The test still serves its primary purpose (proving comptime evaluation compiles), so this is a strengthening suggestion rather than a correctness problem — note test_ulp_at_comptime already uses assert_equal, which is the pattern to follow. (The pre-existing runtime test_nextafter has the same shortcoming).

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

Labels

mojo-stdlib Tag for issues related to standard library waiting-on-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] math.ulp does not work at compile time

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.