Skip to content

Absorb std.math.big.rational logic into std.math.big.int; fix @intFromFloat safety check #24188

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 17, 2025

Conversation

mlugg
Copy link
Member

@mlugg mlugg commented Jun 15, 2025

First, @jacobly0 rewrote a bunch of bigint logic for me, and that's... actually most of the lines in this PR. Then is what it was meant to be; see below.

This is breaking because it removes std.math.big.rational.


This safety check was completely broken; it triggered unchecked illegal behavior in order to implement the safety check. You definitely can't do that! Instead, we must explicitly check the boundaries. This is a tiny bit fiddly, because we need to make sure we do floating-point rounding in the correct direction, and also handle the fact that the operation truncates so the boundary works differently for min vs max.

Instead of implementing this safety check in Sema, there are now dedicated AIR instructions for safety-checked intfromfloat (two instructions; which one is used depends on the float mode). Currently, no backend directly implements them; instead, a Legalize.Feature is added which expands the safety check, and this feature is enabled for all backends we currently test, including the LLVM backend.

The u0 case is still handled in Sema, because Sema needs to check for that anyway due to the comptime-known result. The old safety check here was also completely broken and has therefore been rewritten. In that case, we just check for 'abs(input) < 1.0'.

I've added a bunch of test coverage for the boundary cases of @intFromFloat, both for successes (in test/behavior/cast.zig) and failures (in test/cases/safety/).

Resolves: #24161

@mlugg mlugg added the breaking Implementing this issue could cause existing code to no longer compile or have different behavior. label Jun 15, 2025
@mlugg mlugg changed the title compiler: fix @intFromFloat safety check Absorb std.math.big.rational logic into std.math.big.int; fix @intFromFloat safety check Jun 15, 2025
@mlugg mlugg force-pushed the intfromfloat-safety branch from 49bf21d to b15215e Compare June 15, 2025 13:48
jacobly0 and others added 5 commits June 15, 2025 11:42
This allows legalizations to be added that aren't used by zig1 without
affecting the size of zig1.
Compiler needs a subset of the legalization features enabled.
These conversion routines accept a `round` argument to control how the
result is rounded and return whether the result is exact. Most callers
wanted this functionality and had hacks around it being missing.

Also delete `std.math.big.rational` because it was only being used for
float conversion, and using rationals for that is a lot more complex
than necessary. It also required an allocator, whereas the new integer
routines only need to be passed enough memory to store the result.
This safety check was completely broken; it triggered unchecked illegal
behavior *in order to implement the safety check*. You definitely can't
do that! Instead, we must explicitly check the boundaries. This is a
tiny bit fiddly, because we need to make sure we do floating-point
rounding in the correct direction, and also handle the fact that the
operation truncates so the boundary works differently for min vs max.

Instead of implementing this safety check in Sema, there are now
dedicated AIR instructions for safety-checked intfromfloat (two
instructions; which one is used depends on the float mode). Currently,
no backend directly implements them; instead, a `Legalize.Feature` is
added which expands the safety check, and this feature is enabled for
all backends we currently test, including the LLVM backend.

The `u0` case is still handled in Sema, because Sema needs to check for
that anyway due to the comptime-known result. The old safety check here
was also completely broken and has therefore been rewritten. In that
case, we just check for 'abs(input) < 1.0'.

I've added a bunch of test coverage for the boundary cases of
`@intFromFloat`, both for successes (in `test/behavior/cast.zig`) and
failures (in `test/cases/safety/`).

Resolves: ziglang#24161
There will be more call sites to `preparePanicId` as we transition away
from safety checks in Sema towards safety checked instructions; it's
silly for them to all have this clunky usage.
@mlugg mlugg merged commit 561fdd0 into ziglang:master Jun 17, 2025
10 checks passed
@mlugg mlugg deleted the intfromfloat-safety branch June 17, 2025 10:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Implementing this issue could cause existing code to no longer compile or have different behavior.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

@intFromFloat does not panic when expected for too-large floats
2 participants