-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Always inline functions signatures containing f16
or f128
#133050
base: master
Are you sure you want to change the base?
Conversation
rustbot has assigned @compiler-errors. Use |
Some changes occurred to MIR optimizations cc @rust-lang/wg-mir-opt |
I'm not sure what I am missing here - testing by setting r? @saethlin, I could use a bit of help here |
Oh right, |
You're getting code emitted because the functions are You might also run into rust/compiler/rustc_middle/src/mir/mono.rs Lines 107 to 113 in c82e0df
|
let sig = tcx.fn_sig(def_id).instantiate_identity(); | ||
for ty in sig.inputs().skip_binder().iter().chain(std::iter::once(&sig.output().skip_binder())) | ||
{ | ||
// FIXME(f16_f128): in order to avoid crashes building `core`, always inline to skip | ||
// codegen if the function is not used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you move this down after let mir
, you can just iterate over mir.args_iter()
instead of having to call fn_sig
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would require moving let mir
above the checks against opts.incremental
, OptLevel::No
, and threashold
to avoid hitting a return false
before we check for the types. Would this wind up with a perf impact since we don't generate mir here in these cases?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I thought having this check so far down would be fine. But maybe not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a (temporary, right?) hack, I'd rather the diff be small and localized than pretty. What you've written here is good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(temporary, right?)
Yes please, I don't think we will be able to stabilize these types until LLVM at least doesn't crash on everything T2+.
|
||
pub fn f16_arg(_a: f16) { | ||
// CHECK-NOT: f16_arg | ||
todo!() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure the automatic inlining heuristics wouldn't anyway already mark these functions as inlineable? Might be worth setting cross_crate_inline_threshold to 0 to be sure that doesn't mask the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a revision with -Zcross-crate-inline-threshold=never -Zmir-opt-level=0 -Cno-prepopulate-passes
, is that reasonable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should also add -Copt-level=0
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah of course. Done, tests still pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-Cno-prepopulate-passes
just disables LLVM optimizations, rustc changes its behavior in a few places based on the value of opt-level
.
This comment has been minimized.
This comment has been minimized.
Is there a good way to walk the signature and check for the types recursively at this point? I'm realizing that
Should this function be updated to emit a |
Please change the |
I need to unjunkify my commit history (edit: done) but as-is, this resolves the problem at #133035. |
These types are currently passed by reference, which does not avoid the backend crashes. Change these back to being passed by value, which makes the types easier to detect for automatic inlining.
53a873b
to
781ea18
Compare
f16
or f128
There are a handful of tier 2 and tier 3 targets that cause a LLVM crash or linker error when generating code that contains `f16` or `f128`. The cranelift backend also does not support these types. To work around this, every function in `std` or `core` that contains these types must be marked `#[inline]` in order to avoid sending any code to the backend unless specifically requested. However, this is inconvenient and easy to forget. Introduce a check for these types in the frontend that automatically inlines any function signatures that take or return `f16` or `f128`. Note that this is not a perfect fix because it does not account for the types being passed by reference or as members of aggregate types, but this is sufficient for what is currently needed in the standard library. Fixes: rust-lang#133035 Closes: rust-lang#133037
781ea18
to
5d81891
Compare
After thinking about this I think I've convinced myself that no such change is required, because that code is only run after MirUsedCollector has determined that the Instance must be codegenned. The choice of |
I've manually verified that
Work on this PR, and not on nightly. @bors r+ |
Always inline functions signatures containing `f16` or `f128` There are a handful of tier 2 and tier 3 targets that cause a LLVM crash or linker error when generating code that contains `f16` or `f128`. The cranelift backend also does not support these types. To work around this, every function in `std` or `core` that contains these types must be marked `#[inline]` in order to avoid sending any code to the backend unless specifically requested. However, this is inconvenient and easy to forget. Introduce a check for these types in the frontend that automatically inlines any function signatures that take or return `f16` or `f128`. Note that this is not a perfect fix because it does not account for the types being passed by reference or as members of aggregate types, but this is sufficient for what is currently needed in the standard library. Fixes: rust-lang#133035 Closes: rust-lang#133037
There are a handful of tier 2 and tier 3 targets that cause a LLVM crash or linker error when generating code that contains
f16
orf128
. The cranelift backend also does not support these types. To work around this, every function instd
orcore
that contains these types must be marked#[inline]
in order to avoid sending any code to the backend unless specifically requested.However, this is inconvenient and easy to forget. Introduce a check for these types in the frontend that automatically inlines any function signatures that take or return
f16
orf128
.Note that this is not a perfect fix because it does not account for the types being passed by reference or as members of aggregate types, but this is sufficient for what is currently needed in the standard library.
Fixes: #133035
Closes: #133037