diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2025-01-11 18:13:45 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-11 18:13:45 +0100 |
| commit | b8e230a82413ea1c8274a7aa50317c4e5b084abf (patch) | |
| tree | dad42971b689687805c326e00c4c401a55e51756 /tests | |
| parent | fb65a3ee576feab95a632eb062f466d7a0342310 (diff) | |
| parent | 47573bf61ec0807cee3cf2c5c1ca88bb7d5b89cd (diff) | |
| download | rust-b8e230a82413ea1c8274a7aa50317c4e5b084abf.tar.gz rust-b8e230a82413ea1c8274a7aa50317c4e5b084abf.zip | |
Rollup merge of #134030 - folkertdev:min-fn-align, r=workingjubilee
add `-Zmin-function-alignment` tracking issue: https://github.com/rust-lang/rust/issues/82232 This PR adds the `-Zmin-function-alignment=<align>` flag, that specifies a minimum alignment for all* functions. ### Motivation This feature is requested by RfL [here](https://github.com/rust-lang/rust/issues/128830): > i.e. the equivalents of `-fmin-function-alignment` ([GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-fmin-function-alignment_003dn), Clang does not support it) / `-falign-functions` ([GCC](https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-falign-functions), [Clang](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang1-falign-functions)). > > For the Linux kernel, the behavior wanted is that of GCC's `-fmin-function-alignment` and Clang's `-falign-functions`, i.e. align all functions, including cold functions. > > There is [`feature(fn_align)`](https://github.com/rust-lang/rust/issues/82232), but we need to do it globally. ### Behavior The `fn_align` feature does not have an RFC. It was decided at the time that it would not be necessary, but maybe we feel differently about that now? In any case, here are the semantics of this flag: - `-Zmin-function-alignment=<align>` specifies the minimum alignment of all* functions - the `#[repr(align(<align>))]` attribute can be used to override the function alignment on a per-function basis: when `-Zmin-function-alignment` is specified, the attribute's value is only used when it is higher than the value passed to `-Zmin-function-alignment`. - the target may decide to use a higher value (e.g. on x86_64 the minimum that LLVM generates is 16) - The highest supported alignment in rust is `2^29`: I checked a bunch of targets, and they all emit the `.p2align 29` directive for targets that align functions at all (some GPU stuff does not have function alignment). *: Only with `build-std` would the minimum alignment also be applied to `std` functions. --- cc `@ojeda` r? `@workingjubilee` you were active on the tracking issue
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/codegen/min-function-alignment.rs | 43 | ||||
| -rw-r--r-- | tests/codegen/naked-fn/min-function-alignment.rs | 44 |
2 files changed, 87 insertions, 0 deletions
diff --git a/tests/codegen/min-function-alignment.rs b/tests/codegen/min-function-alignment.rs new file mode 100644 index 00000000000..7c0ad12402a --- /dev/null +++ b/tests/codegen/min-function-alignment.rs @@ -0,0 +1,43 @@ +//@ revisions: align16 align1024 +//@ compile-flags: -C no-prepopulate-passes -Z mir-opt-level=0 +//@ [align16] compile-flags: -Zmin-function-alignment=16 +//@ [align1024] compile-flags: -Zmin-function-alignment=1024 + +#![crate_type = "lib"] +#![feature(fn_align)] + +// functions without explicit alignment use the global minimum +// +// CHECK-LABEL: @no_explicit_align +// align16: align 16 +// align1024: align 1024 +#[no_mangle] +pub fn no_explicit_align() {} + +// CHECK-LABEL: @lower_align +// align16: align 16 +// align1024: align 1024 +#[no_mangle] +#[repr(align(8))] +pub fn lower_align() {} + +// the higher value of min-function-alignment and repr(align) wins out +// +// CHECK-LABEL: @higher_align +// align16: align 32 +// align1024: align 1024 +#[no_mangle] +#[repr(align(32))] +pub fn higher_align() {} + +// cold functions follow the same rules as other functions +// +// in GCC, the `-falign-functions` does not apply to cold functions, but +// `-Zmin-function-alignment` applies to all functions. +// +// CHECK-LABEL: @no_explicit_align_cold +// align16: align 16 +// align1024: align 1024 +#[no_mangle] +#[cold] +pub fn no_explicit_align_cold() {} diff --git a/tests/codegen/naked-fn/min-function-alignment.rs b/tests/codegen/naked-fn/min-function-alignment.rs new file mode 100644 index 00000000000..1330d796d39 --- /dev/null +++ b/tests/codegen/naked-fn/min-function-alignment.rs @@ -0,0 +1,44 @@ +//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 -Zmin-function-alignment=16 +//@ needs-asm-support +//@ ignore-arm no "ret" mnemonic + +#![feature(naked_functions, fn_align)] +#![crate_type = "lib"] + +// functions without explicit alignment use the global minimum +// +// CHECK: .balign 16 +#[no_mangle] +#[naked] +pub unsafe extern "C" fn naked_no_explicit_align() { + core::arch::naked_asm!("ret") +} + +// CHECK: .balign 16 +#[no_mangle] +#[repr(align(8))] +#[naked] +pub unsafe extern "C" fn naked_lower_align() { + core::arch::naked_asm!("ret") +} + +// CHECK: .balign 32 +#[no_mangle] +#[repr(align(32))] +#[naked] +pub unsafe extern "C" fn naked_higher_align() { + core::arch::naked_asm!("ret") +} + +// cold functions follow the same rules as other functions +// +// in GCC, the `-falign-functions` does not apply to cold functions, but +// `-Zmin-function-alignment` applies to all functions. +// +// CHECK: .balign 16 +#[no_mangle] +#[cold] +#[naked] +pub unsafe extern "C" fn no_explicit_align_cold() { + core::arch::naked_asm!("ret") +} |
