Skip to content

compiler-rt math functions reorg #11532

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 18 commits into from
Apr 28, 2022
Merged

compiler-rt math functions reorg #11532

merged 18 commits into from
Apr 28, 2022

Conversation

andrewrk
Copy link
Member

@andrewrk andrewrk commented Apr 26, 2022

  • unify the logic for exporting math functions from compiler-rt,
    with the appropriate suffixes and prefixes.
    • add all missing f128 and f80 exports. Functions with missing
      implementations call other functions and have TODO comments.
    • also add f16 implementations
  • move math functions from freestanding libc to compiler-rt (consolidate libc and libssp into compiler-rt #7265)
  • enable all the f128 and f80 code in the stage2 compiler and behavior
    tests
  • update std lib to use builtins rather than std.math.
  • tan is moved to compiler-rt to match @sin and @cos, because all three implementations share a common dependency.

Merge checklist:

@andrewrk andrewrk changed the title *WIP* compiler-rt math functions reorg compiler-rt math functions reorg Apr 26, 2022
@andrewrk andrewrk marked this pull request as ready for review April 26, 2022 22:29
return math.ln(2 * x - 1 / (x + math.sqrt(x * x - 1)));
return @log(2 * x - 1 / (x + @sqrt(x * x - 1)));
Copy link
Contributor

Choose a reason for hiding this comment

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

math.ln and @log are not equivalent. ln is base e and log is base 10. You would need to divide by @log(e).

Copy link
Member

Choose a reason for hiding this comment

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

@log does refer to the natural logarithm. See https://ziglang.org/documentation/0.9.1/#log.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks, I should have checked before commenting. Sorry for that!

Copy link
Member Author

Choose a reason for hiding this comment

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

It's still a fair point; we may want to play with the naming to make it less ambiguous. Although we are a bit limited by libc here since we do need to match the symbol names, and libc has log as natural log.

andrewrk and others added 5 commits April 27, 2022 12:20
 * unify the logic for exporting math functions from compiler-rt,
   with the appropriate suffixes and prefixes.
   - add all missing f128 and f80 exports. Functions with missing
     implementations call other functions and have TODO comments.
   - also add f16 functions
 * move math functions from freestanding libc to compiler-rt (#7265)
 * enable all the f128 and f80 code in the stage2 compiler and behavior
   tests (#11161).
 * update std lib to use builtins rather than `std.math`.
Updates stage1 to manually lower softfloat operations for all unary
floating point operations, extension/truncation, and arithmetic.
Updates stage2 to manually lower softfloat operations for all unary
floating point operations and arithmetic.

Softfloat support still needs to be added for conversion operators
(float<->float and int<->float)
 * std.math.snan: fix compilation error. Also make it and nan inline.
 * LLVM: use a proper enum type for float op instead of enum literal.
   Also various cleanups.
 * LLVM: use LLVMBuildVectorSplat for vector splat AIR instruction.
   - also the bindings had parameter order wrong
 * LLVM: additionally handle f16 lowering. For now all targets report OK
   but I think we will need to add some exceptions to this list.
andrewrk added 13 commits April 27, 2022 16:45
The reason for having `@tan` is that we already have `@sin` and `@cos`
because some targets have machine code instructions for them, but in the
case that the implementation needs to go into compiler-rt, sin, cos, and
tan all share a common dependency which includes a table of data. To
avoid duplicating this table of data, we promote tan to become a builtin
alongside sin and cos.

ZIR: The tag enum is at capacity so this commit moves
`field_call_bind_named` to be `extended`. I measured this as one of
the least used tags in the zig codebase.

Fix libc math suffix for `f32` being wrong in both stage1 and stage2.
stage1: add missing libc prefix for float functions.
This is to account for the small differences in math functions of
different libcs. For example, if the compiler links against glibc,
but the target is musl libc, then these values might be
slightly different.

Arguably, this is a bug in the compiler because comptime should
emulate the target, including rounding errors in libc math
functions. However that behavior is not what this particular test
is intended to cover.
Weak aliases don't work on Windows, so we avoid exporting the `l` alias
on this platform for functions we know will collide.
This was leftover from testing std.math.sin
This is a new test added in this branch but it is not yet passing for
i386-windows with the stage1 compiler.
These are only as accurate as f64 even for f128 comptime functions. This
is OK for now; improvements will come with the launch of self-hosted
(#89) and enhancements to compiler-rt implementations.
This avoids the optimizer turning sincos into a recursive call to
itself.
Before this change, struct {f80, f80} targeting i386-windows-msvc lowers
to

```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [6 x i8], x86_fp80, [6 x i8] }
```

which has an incorrect ABI size of 40. After this change, the struct
lowers to

```llvm
%"std.testing.struct:78:61.6" = type { x86_fp80, [4 x i8], x86_fp80, [4 x i8] }
```

which has the correct ABI size of 32, and properly aligns the second
field to 16 bytes.

The other place that calculates field padding (lowering of constant
values in codegen.cpp) already correctly calls LLVMABISizeOfType
rather than LLVMStoreSizeOfType.

This fixes the compiler-rt tests for i386-windows in this branch.
@andrewrk andrewrk added the breaking Implementing this issue could cause existing code to no longer compile or have different behavior. label Apr 28, 2022
@andrewrk
Copy link
Member Author

Labeling as "breaking" because this removes std.math functions which have corresponding builtins, such as @sqrt.

Copy link
Contributor

@matu3ba matu3ba left a comment

Choose a reason for hiding this comment

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

idea (could also be part of later refactoring): expose those things as part of the target info to be usable in build.zig

@@ -8055,6 +8188,26 @@ fn backendSupportsF80(target: std.Target) bool {
};
}

/// This function returns true if we expect LLVM to lower f16 correctly
/// and false if we expect LLVM to crash if it counters an f16 type or
/// if it produces miscompilations.
Copy link
Contributor

Choose a reason for hiding this comment

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

This sounds like stuff that would be very useful, if the user could query this.
Or what do you think? (Same argument holds for other codegen backends)

Copy link
Member Author

Choose a reason for hiding this comment

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

No, it is best if the user does not check these conditions. Technically, they already can, because they can put this logic into their application code and check for @import("builtin").zig_backend being one of the LLVM backends. However, see the doc comment on the CompilerBackend enum for best practices related to this.

}

/// LLVM does not support all relevant intrinsics for all targets, so we
/// may need to manually generate a libc call
Copy link
Contributor

Choose a reason for hiding this comment

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

same idea: offering the opportunity to query from build.zig if intrinsics are used sounds useful.

@andrewrk andrewrk merged commit 360ecc1 into master Apr 28, 2022
@andrewrk andrewrk deleted the compiler-rt-math branch April 28, 2022 17:34
@frmdstryr
Copy link
Contributor

Would you be opposed to having backward compatible inline fn's included in math?

Code doing complex math is already difficult enough to follow as is... remembering which is builtin vs in math just adds unnecessary friction (and makes the code ugly imo).

@andrewrk
Copy link
Member Author

Not opposed

perillo added a commit to perillo/zig that referenced this pull request Feb 2, 2023
In the math builtin functions documentation, remove the link to issue
ziglang#4026, since it was closed by
ziglang#11532.
Vexu pushed a commit that referenced this pull request Feb 3, 2023
In the math builtin functions documentation, remove the link to issue
#4026, since it was closed by
#11532.
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.

6 participants