intrinsics: Add a fallback for non-const libm float functions#150946
Conversation
| #[rustc_intrinsic_const_stable_indirect] | ||
| #[rustc_intrinsic] | ||
| #[rustc_nounwind] | ||
| pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128; |
There was a problem hiding this comment.
Is there a way to provide a non-const fallback for const intrinsics? In cases where CTFE definitely has to hook it rather than using the fallback, like here.
Not the worst thing if not.
There was a problem hiding this comment.
I don't think there is -- please file an issue.
This comment has been minimized.
This comment has been minimized.
d533ef5 to
90b9d6a
Compare
This comment has been minimized.
This comment has been minimized.
Huh - so |
|
At a glance, your reasoning is completely backwards. The fallback body for |
|
It shouldn't be; the |
|
The changes LGTM. However I can't actually check whether what you say about what is available where is correct -- you would be the person I ask about things like that. ;) |
|
https://github.com/rust-lang/compiler-builtins/blob/65624df7f55db9b7b494fbe3aa9dcea0a743eea4/compiler-builtins/src/math/mod.rs is what controls what we sometimes/always provide, so the module root symbols and |
Yes, that's the problem. The body for the function is not available in the crate compiler-builtins when compiling compiler-builtins. Remember the the rule is to ban linkage against other crates and the point of these extern declarations is to use linkage. |
This comment has been minimized.
This comment has been minimized.
Forgot to follow up here. In this case it there isn't anything technically incorrect right, and instead it's a limitation of the knowledge the compiler has to emit that error? Because c-b itself provides the It probably goes without saying but libm isn't calling the |
|
Oh I see, thanks for clarifying. I think this is actually a limitation of the check logic itself. The problem is that you have an item defined in an upstream crate, which is not So the missing check is whether the |
|
I threw this together to convince myself that this can work, and it seems to work. diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index c8aa7c04585..3fc0411d2be 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -867,6 +867,10 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
/// unlinkable calls.
///
/// Note that calls to LLVM intrinsics are uniquely okay because they won't make it to the linker.
+/// Note also that calls to foreign items that are actually exported by the local crate are also
+/// okay. This situation arises because compiler-builtins calls functions in core that are #[inline]
+/// wrappers for extern "C" declarations in core, which resolve to a symbol exported by
+/// compiler-builtins.
pub fn is_call_from_compiler_builtins_to_upstream_monomorphization<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
@@ -879,11 +883,19 @@ fn is_llvm_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
}
}
+ fn is_extern_call_to_local_crate<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> bool {
+ tcx.is_foreign_item(instance.def_id())
+ && tcx.exported_non_generic_symbols(LOCAL_CRATE).iter().any(|(sym, _info)| {
+ sym.symbol_name_for_local_instance(tcx) == tcx.symbol_name(instance)
+ })
+ }
+
let def_id = instance.def_id();
!def_id.is_local()
&& tcx.is_compiler_builtins(LOCAL_CRATE)
&& !is_llvm_intrinsic(tcx, def_id)
&& !tcx.should_codegen_locally(instance)
+ && !is_extern_call_to_local_crate(tcx, instance)
}
impl CrateInfo {The linear search of all exported non-generic symbols seems bad. It's only done a handful of times so it doesn't have a visible impact on compile time of compiler-builtins... yet. |
|
@rustbot author |
|
Reminder, once the PR becomes ready for a review, use |
90b9d6a to
176fd06
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
intrinsics: Add a fallback for non-const libm float functions try-job: i686-msvc-1 try-job: x86_64-msvc-1 try-job: aarch64-msvc-1 try-job: x86_64-mingw-1
|
@bors r=RalfJung,saethlin |
… r=RalfJung,saethlin intrinsics: Add a fallback for non-const libm float functions A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
… r=RalfJung,saethlin intrinsics: Add a fallback for non-const libm float functions A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
…uwer Rollup of 21 pull requests Successful merges: - #150946 (intrinsics: Add a fallback for non-const libm float functions) - #158510 (Enable `static_position_independent_executables` on all gnu and musl targets) - #158541 (Move `std::io::Write` to `core::io`) - #158899 (Fix `unaligned_volatile_store` by removing `MemFlags::UNALIGNED`) - #155429 (Support `u128`/`i128` c-variadic arguments) - #156370 (Reject linked dylib EII default overrides) - #156508 (Infer all anonymous lifetimes in assoc consts as `'static`) - #158617 (allow mGCA const arguments to fall back to anon consts) - #158645 (Fix splat ICEs and ban it in closures) - #158859 (Improve `-Zls` diagnostic message on `.rs` files) - #158988 (Redo `TokenStreamIter`) - #158347 (Improve generic parameters handling for #[diagnostic::on_const]) - #158722 (delegation: do not always inherit `ConstArgHasType` predicates) - #158739 (view-types: HIR lowering) - #158883 (tests: fix enum-match.rs to handle LLVM 23) - #158886 (Add documentation for the `no_std` attribute) - #158940 (Implement feature `char_to_u32`) - #158951 (Merge three `MaxUniverse`s into one) - #158961 (Reapply "LLVM 23: Run AssignGUIDPass in some places") - #158996 ([compiler] Implement `PartialOrd` via `Ord` for `Span` and newtype_indexes) - #159005 (Use `as_lang_item` instead of repeatedly matching)
… r=RalfJung,saethlin intrinsics: Add a fallback for non-const libm float functions A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
…uwer Rollup of 24 pull requests Successful merges: - #150946 (intrinsics: Add a fallback for non-const libm float functions) - #158510 (Enable `static_position_independent_executables` on all gnu and musl targets) - #158541 (Move `std::io::Write` to `core::io`) - #158899 (Fix `unaligned_volatile_store` by removing `MemFlags::UNALIGNED`) - #156027 (Consider captured regions for opaque type region liveness.) - #156370 (Reject linked dylib EII default overrides) - #156508 (Infer all anonymous lifetimes in assoc consts as `'static`) - #157561 (rustdoc: do not include extra stuff in span) - #158617 (allow mGCA const arguments to fall back to anon consts) - #158645 (Fix splat ICEs and ban it in closures) - #158859 (Improve `-Zls` diagnostic message on `.rs` files) - #158988 (Redo `TokenStreamIter`) - #158347 (Improve generic parameters handling for #[diagnostic::on_const]) - #158384 (Allow BackwardIncompatibleDropHint in polonius legacy) - #158722 (delegation: do not always inherit `ConstArgHasType` predicates) - #158739 (view-types: HIR lowering) - #158877 (borrowck: Keep returned `path` from `best_blame_constraint()` consistent) - #158883 (tests: fix enum-match.rs to handle LLVM 23) - #158886 (Add documentation for the `no_std` attribute) - #158940 (Implement feature `char_to_u32`) - #158951 (Merge three `MaxUniverse`s into one) - #158961 (Reapply "LLVM 23: Run AssignGUIDPass in some places") - #158995 (Use REST API in linkchecker script) - #158996 ([compiler] Implement `PartialOrd` via `Ord` for `Span` and newtype_indexes)
… r=RalfJung,saethlin intrinsics: Add a fallback for non-const libm float functions A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
Rollup of 24 pull requests Successful merges: - #150946 (intrinsics: Add a fallback for non-const libm float functions) - #158541 (Move `std::io::Write` to `core::io`) - #156027 (Consider captured regions for opaque type region liveness.) - #156370 (Reject linked dylib EII default overrides) - #156508 (Infer all anonymous lifetimes in assoc consts as `'static`) - #157561 (rustdoc: do not include extra stuff in span) - #158617 (allow mGCA const arguments to fall back to anon consts) - #158645 (Fix splat ICEs and ban it in closures) - #158859 (Improve `-Zls` diagnostic message on `.rs` files) - #158988 (Redo `TokenStreamIter`) - #158347 (Improve generic parameters handling for #[diagnostic::on_const]) - #158384 (Allow BackwardIncompatibleDropHint in polonius legacy) - #158722 (delegation: do not always inherit `ConstArgHasType` predicates) - #158739 (view-types: HIR lowering) - #158877 (borrowck: Keep returned `path` from `best_blame_constraint()` consistent) - #158883 (tests: fix enum-match.rs to handle LLVM 23) - #158886 (Add documentation for the `no_std` attribute) - #158940 (Implement feature `char_to_u32`) - #158951 (Merge three `MaxUniverse`s into one) - #158960 (Fix bootstrap submodule path prefix matching) - #158961 (Reapply "LLVM 23: Run AssignGUIDPass in some places") - #158995 (Use REST API in linkchecker script) - #158996 ([compiler] Implement `PartialOrd` via `Ord` for `Span` and newtype_indexes) - #159036 (bootstrap: expand '@argfile' arguments to rustc shim)
Rollup merge of #150946 - tgross35:float-intrinsic-fallback, r=RalfJung,saethlin intrinsics: Add a fallback for non-const libm float functions A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
|
@rust-timer build ba59afc |
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (ba59afc): comparison URL. Overall result: ❌✅ regressions and improvements - please read:Benchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. Next, please: If you can, justify the regressions found in this try perf run in writing along with @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
Max RSS (memory usage)Results (primary -2.4%, secondary -0.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (primary 1.8%, secondary -1.1%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 490.768s -> 490.048s (-0.15%) |
|
@rustbot label: +perf-regression-triaged |
View all comments
A number of float operations from libm have intrinsics for optimization, but it is also okay to just call the libm functions directly. Add a fallback for these cases, including converting to/from another float size where needed, so the backends don't need to override these.
r? @RalfJung