-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for f32 and f64 methods in libcore #50145
Comments
If we provide the fallback implementations in compiler-builtins I'd be fine moving these to libcore, but otherwise I'd personally prefer that they remain in std. I think the implementations in compiler-builtins may not be too bad though? |
We could consider supporting all the math functions in There no reason any of these functions ( |
@Amanieu We certainly can consider that, but what I had in mind for this issue is starting for example with with |
Regarding
|
(Most) trigonometric and transcendental functions are far from trivial, especially if you want at all reasonable accuracy and performance (if not, people would -- rightly! -- avoid the libcore implementations or use them and find them unsatisfactory, defeating the purpose of providing them). They can be supported in a core-only environment in principle, but unless and until someone puts in the work to actually implement them, that's pie in the sky. |
The three functions mentioned here ( |
This comment was marked as off-topic.
This comment was marked as off-topic.
@vks Only having Rust implementations of those functions is certainly a possibility. But since LLVM intrinsics exist, should we try to use them? Maybe some architecture have dedicated instructions that can be faster? On the other hand, can we rely on those intrinsics to be available for all targets, even when @hellow554 The reasons is that (as far as I know) we don’t yet have a clear answer to the questions above. Counting months is irrelevant, answers/solutions do now grow by themselves. |
The LLVM intrinsics exist on every target, but many (all?) targets lower them to libm function calls. They are intrinsics mostly to facilitate optimizations, I believe. Which leads to another potential problem: if we implement these in Rust, might LLVM optimizations canonicalize them to calls to the intrinsics? This is certainly a problem for other functions/intrinsics like |
I believe this is also a problem for using the LLVM intrinsics for Edit: though am I understanding correctly that it's non-breaking to move a floating-point method from libcore to libstd? |
Use LLVM intrinsics for floating-point min/max Resurrection of #46926, now that the optimisation issues are fixed. I've confirmed locally that #61384 solves the issues. I'm not sure if we're allowed to move the `min`/`max` methods from libcore to libstd: I can't quite tell what the status is from #50145. However, this is necessary to use the intrinsics. Fixes #18384. r? @SimonSapin cc @rkruppe @nikic
As per #61408, we should be able to use LLVM intrinsics provided we make sure they're properly supported.
|
@varkor So I've been working on But once the compiler-builtins issue gets resolved can we put sqrt in core? |
Update (see the above issue that references here): How shall we proceed? Is this an RFC level change, or do we just PR to libcore and have T-libs approve it? |
You should be able to simply open a PR, now that precedent has been set. I'd cc @alexcrichton in the PR. |
I suspect this will be much trickier than the small PRs I've done in the past, but I will attempt to get us started today or tomorrow. |
To help this issue I've conduct a little experiment with compiler-explorer (godbolt) which consist of compiling the llvm intrinsics for every target that rust supports:
I think it's pretty safe to say that given the current situation Given this I would be willing to make a PR to move those functions back to |
I don't think such a PR would be accepted. A better solution would be to properly support all math functions in core by providing them in cc @Lokathor who may have some thoughts on this. |
my understanding is that compiler-builtins is a deliberately minimal and "as needed" type of crate right now, rather than exhaustively providing all things. Well it's trivial to copy the sign bit or clear the sign bit. LLVM can seemingly do that much on its own without ever asking for help. This assumes IEEE floats, but Rust already assumes that. powf, not so much, I suspect that llvm will always need to call a libm here. So I'm not against putting all functions into compiler-builtins all the time as float support in core is expanded, just so long as we're willing to recognize and document that llvm is exceedingly unlikely to ever call particular functions (and we provide them anyway just in case). |
I just reviewed the past issues in compiler-builtins regarding support for weak functions, and here is what I propose we do:
Once this is done, we should have the necessary symbols available on all targets which would allow moving the |
Technically LLVM supports using weak symbols on Windows, at least in mingw-w64 mode it works good. The problem is it requires whole comdat. |
Do we need an RFC for this or a PR is sufficient? |
Cc @eduardosm |
I think they should be considered separately from other functions that actually require a non-trivial implementation, like |
I think it is also okay to move |
IEEE 754 has a separate section "5.5.1 Sign bit operations" for
Similarly, B.3 notes that So very much agreed for everything in that section, Ralf. It's like those ones are written intentionally to not need to think about most of the float complications, and to allow us to just do the integer implementation. I think the "well we wrote it already" cases should be considered separately, Trevor. I think the sign-bit operations are fundamentally different from the others, in more than them already-working. |
Yes, exactly. They are also called out in the docs as "non-arithmetic operations", and they are the only non-arithmetic operations that are not in |
Well not literally the exact same PR :) just as far as how |
I made a PR to move abs, copysign, signum to libcore: #131304. |
float types: move copysign, abs, signum to libcore These operations are explicitly specified to act "bitwise", i.e. they just act on the sign bit and do not even quiet signaling NaNs. We also list them as ["non-arithmetic operations"](https://doc.rust-lang.org/nightly/std/primitive.f32.html#nan-bit-patterns), and all the other non-arithmetic operations are in libcore. There's no reason to expect them to require any sort of runtime support, and from [these experiments](rust-lang#50145 (comment)) it seems like LLVM indeed compiles them in a way that does not require any sort of runtime support. Nominating for `@rust-lang/libs-api` since this change takes immediate effect on stable. Part of rust-lang#50145.
Rollup merge of rust-lang#131304 - RalfJung:float-core, r=tgross35 float types: move copysign, abs, signum to libcore These operations are explicitly specified to act "bitwise", i.e. they just act on the sign bit and do not even quiet signaling NaNs. We also list them as ["non-arithmetic operations"](https://doc.rust-lang.org/nightly/std/primitive.f32.html#nan-bit-patterns), and all the other non-arithmetic operations are in libcore. There's no reason to expect them to require any sort of runtime support, and from [these experiments](rust-lang#50145 (comment)) it seems like LLVM indeed compiles them in a way that does not require any sort of runtime support. Nominating for `@rust-lang/libs-api` since this change takes immediate effect on stable. Part of rust-lang#50145.
#49896 removes from libcore (and moves to libstd) three methods of
f32
andf64
(that were only usable through the unstable traitcore::num::Float
) because they’re implemented by calling LLVM intrinsics, and it’s not clear whether those intrinsics are lowered on any platform to calls to C’slibm
or something else that requires runtime support that we don’t want in libcore:abs
: callsllvm.fabs.f32
orllvm.fabs.f64
signum
: callsllvm.copysign.f32
orllvm.copysign.f64
powi
: callsllvm.powi.f32
orllvm.powi.f32
The first two seem like they’d be easy to implement in a small number of lower-level instructions (such as a couple lines with
if
, or even bit twiddling based on IEEE 754).abs
in particular seems like a rather common operation, and it’s unfortunate not to have it in libcore.The
compiler-builtins
crate has Rust implementations of__powisf2
and__powidf2
, but in LLVM code those are only mentioned inlib/Target/WebAssembly/WebAssemblyRuntimeLibcallSignatures.cpp
so I haven’t found evidence thatllvm.powi.f32
andllvm.powi.f32
call those functions.PR #27823 “Remove dependencies on libm functions from libcore” similarly moved a number of other
f32
andf64
methods to libstd, but left these three behind specifically. (And unfortunately doesn’t discuss why.)Maybe it’s fine to move them back in libcore? (As inherent methods, assuming #49896 lands.)
CC @alexcrichton
The text was updated successfully, but these errors were encountered: