-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Stabilize -Cmin-function-alignment
#142824
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
base: master
Are you sure you want to change the base?
Stabilize -Cmin-function-alignment
#142824
Conversation
Higher alignments are not supported in COFF
Some changes occurred to the CTFE machinery Some changes occurred to the CTFE / Miri interpreter cc @rust-lang/miri Some changes occurred in compiler/rustc_codegen_cranelift cc @bjorn3 Some changes occurred in compiler/rustc_codegen_ssa The Miri subtree was changed cc @rust-lang/miri |
// alignment that works on all target platforms. COFF does not support higher alignments. | ||
if bytes > 8192 { | ||
return false; | ||
} |
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.
Why should it be limited on all platforms? Can't we error when the alignment exceeds the maximum that the actual target we are compiling for supports? Maybe someone genuinely needs to align to 16k on ELF for whatever reason?
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.
Well, so as we've discovered, alignment is just a mess between clang and llvm. For instance -falign-function
only goes up to 1 << 16
, although you can manually align a function to a much higher alignment.
For 8192, we know it'll work everywhere, and the logic for when to accept/reject an alignment value is clear.
This flag aligns all functions to the minimum, so I have a hard time seeing a realistic scenario where aligning all functions to 16k is a reasonable thing to do (the limit on individual functions will be handled separately).
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.
So I think the options are:
- Limit to
8192
on all platforms, it's consistent and unlikely to cause issues. The limit can be safely raised in the future if a need arises - Follow
clang
and allow1 << 16
, except when the target object format is COFF, then the limit is8192
. - Accept what llvm accepts: allow
1 << 29
, except when the target object format is COFF, then the limit is8192
.
I've picked the most conservative one (again, with the option to relax the limits if the need ever arises), but if there is consensus now on one of the other options that's also fine.
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.
It is my understanding that on Linux kernels we still nominally support, overaligning beyond the page size, typically 4096, is not going to work properly, so it is arguable that even 8192 is too high.
let fn_align = self.tcx.codegen_fn_attrs(instance.def_id()).alignment; | ||
let global_align = self.tcx.sess.opts.unstable_opts.min_function_alignment; | ||
let global_align = self.tcx.sess.opts.cg.min_function_alignment; |
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.
(orthogonal to this PR)
it is not great that the logic for merging the per-fn alignment and the global alignment needs to be repeated in each backend.
Maybe codegen_fn_attrs
should just take min_function_alignment
into account?
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.
In fact, using sess.opts
in the interpreter is at best iffy since it means the interpreter can behave differently in different crates in the same crate graph which can cause unsoundness...
tracking issue: #82232
split out from: #140261
Request for Stabilization
Summary
The
-Cmin-function-alignment=<align>
flag specifies the minimum alignment of functions for which code is generated.The
align
value must be a power of 2, other values are rejected.Note that
-Zbuild-std
(or similar) is required to apply this minimum alignment to standard library functions.By default, these functions come precompiled and their alignments won't respect the
min-function-alignment
flag.This flag is equivalent to:
-fmin-function-alignment
for GCC-falign-functions
for ClangThe specified alignment is a minimum. A higher alignment can be specified for specific functions by annotating the function with a
#[align(<align>)]
attribute.The attribute's value is ignored when it is lower than the value passed to
min-function-alignment
.There are two additional edge cases for this flag:
A
min-function-alignment
value lower than the target's minimum has no effect.8192
. Trying to set a higher value results in an error.Testing
History
-Zmin-function-alignment
#134030The -Zmin-function-alignment flag was requested by rust-for-linux #128830. It will be used soon (see #t-compiler/help > ✔ Alignment for function addresses).
Miri supports function alignment since #140072. In const-eval there is no way to observe the address of a function pointer, so no special attention is needed there (see #t-compiler/const-eval > function address alignment).
Originally, the maximum allowed alignment was
1 << 29
, because this is the highest value the LLVM API accepts. However, on COFF the highest supported alignment is only 8192 (see #142638). Practically speaking, that seems more than sufficient for all known use cases. So for simplicity, for now, we limit the alignment to 8192. The value can be increased on platforms that support it if the need arises.r? @workingjubilee
the first commit can be split out if that is more convenient.