Skip to content

rustc_const_eval: respect target.min_global_align #142198

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Jun 8, 2025

Currently different backends handle the target.min_global_align option inconsistently: llvm and gcc respect it, but miri/rustc_const_eval does not. I believe that rustc_codegen_cranelift can't yet support per-item alignment.

The only rust target that sets min_global_align today is s390x. In LLVM the only other target that also specifies a min_global_align is larai, which rust does not support. The nvptx targets inherit the min_global_align from their host.

Proposal

The min_global_align target option becomes a language guarantee: If the target specifies min_global_align (i.e. it is not None), all globals will have an alignment of at least the min_global_align specified by the target.

This allows unsafe code authors to write inline assembly and other code that relies on the alignment of globals.

Background

Issue #44411 describes a correctness problem on s390x, where a static is not sufficiently aligned: the larl instruction that LLVM generates assumes an even address, but e.g. a static containing a bool may have an odd address. Clang and gcc make sure that globals are always aligned properly, even if their type does not require it. A language guarantee is required to justify inline assembly using the same instruction.

See also #miri > alignment of globals on s390x

r? @RalfJung
@rustbot label +I-lang-nominated

@rustbot rustbot added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 8, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 8, 2025

The Miri subtree was changed

cc @rust-lang/miri

These commits modify compiler targets.
(See the Target Tier Policy.)

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

@rust-log-analyzer

This comment has been minimized.

@folkertdev folkertdev force-pushed the miri-s390x-align-statics branch from c87f1ba to 21aae4d Compare June 8, 2025 17:17
@@ -0,0 +1,50 @@
// Test that miri respects the `target.min_global_align` value for the target.
// E.g. on s390x, statics have, in practice, a minimum alignment of 2.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"in practice" seems like unnecessarily wobbly language here. Can we say something more concrete, or if the answer is complicated point to where the full answer is?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the actual answer is "LLVM and some other compilers generate incorrect code if globals have an alignment less than 2, as they generate accesses to globals using LALR, which requires alignment to even addresses in order to work".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, the situation here is a confusing

  • technically, miri does not need to enforce this alignment of 2, because it does not actually emit the larl instruction that would behave incorrectly
  • but in practice, both gcc, clang and rustc do respect this alignment
  • intuitively miri should respect target.min_global_align
  • the only way to observe its effect right now is to test the alignment of statics on s390x

Anyway I've updated the comment with why this test was written.

@folkertdev folkertdev force-pushed the miri-s390x-align-statics branch 2 times, most recently from 7b8bcdd to 553ae22 Compare June 8, 2025 17:44
@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

The way I'd frame it is that LLVM made the choice to access globals with an instruction that requires the address to be even (?!?), and we have to set some target option to ensure this is indeed the case. It is somewhat odd that LLVM doesn't ensure this by itself -- nobody asked it to use that instruction after all, that was its own choice, why do frontends even have to know about this? But that's a separate discussion from the one in this PR.

For this PR, the question is whether we promise to unsafe code authors that all globals on this target are going to be 2-aligned. If the answer is "no", then I don't think Miri should do anything here; the use of larl and the 2-aligning of globals is an implementation choice that we could take back any time. If we land this PR, we pretty much make a stable promise that all globals will be 2-aligned, and that should be documented somewhere.

Cc @rust-lang/opsem

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance this could be done with a macro rather than having to repeat the same code many times?

@folkertdev folkertdev force-pushed the miri-s390x-align-statics branch from 553ae22 to 69a7b9c Compare June 9, 2025 10:11
@folkertdev folkertdev force-pushed the miri-s390x-align-statics branch from 69a7b9c to adfdea0 Compare June 9, 2025 10:16
@folkertdev
Copy link
Contributor Author

The target maintainer may have some background too, cc @uweigand.

@Darksonn
Copy link
Contributor

Darksonn commented Jun 9, 2025

For this PR, the question is whether we promise to unsafe code authors that all globals on this target are going to be 2-aligned.

There might be unsafe code authors that wish to use the larl instruction in their own inline assembly. That doesn't seem like an unreasonable expectation.

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

Yes, that would be the kind of argument requiring us to make this a language guarantee. Miri can't run inline asm, but arguably unsafe code authors could also cast a pointer to such memory to &u16 and justify it with the platform alignment.

But that requires making this alignment an actual language guarantee, so we should involve the lang team before landing this.

@folkertdev can you rephrase the PR description to make it clear that this is about elevating this target option to a language guarantee? Then we can nominate for t-lang discussion.

@rustbot rustbot added the I-lang-nominated Nominated for discussion during a lang team meeting. label Jun 9, 2025
@folkertdev
Copy link
Contributor Author

I updated the comment, hopefully that is sufficiently clear.

If this does become a language guarantee, I should write a test with a custom target that sets a much higher min_global_align, hence:

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 9, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 9, 2025

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

Custom targets are unstable, and adding such a test at least in Miri will be somewhat tricky.

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

The nvptx targets inherit the min_global_align from their host.

That's a statement about LLVM or rustc? It seems like very undesirable behavior, so I hope it's not ours.^^ The generated code shouldn't depend on the host used for compilation...

@folkertdev
Copy link
Contributor Author

The nvptx targets inherit the min_global_align from their host.

That's a statement about LLVM or rustc? It seems like entirely wild behavior, so I hope it's not ours.^^

That's about llvm, specifically the value is inherited here. spir is similar to nvptx, but it has no rust targets.

But now that I look a bit more carefully, also e.g. aarch64 windows has some custom alignment rules for globals here. That logic is based on

https://learn.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=msvc-170#alignment

That alignment logic is in the clang part of the code base, so presumably rustc would have to replicate it if it wants to be compatible.

The final case (similar to aarch64) is csky here.

@RalfJung
Copy link
Member

RalfJung commented Jun 9, 2025

That's about llvm, specifically the value is inherited here. spir is similar to nvptx, but it has no rust targets.

If Opts.HostTriple there is actually the host this runs on, then that is truly cursed. Cc @RDambrosio016 @kjetilkjeka

@uweigand
Copy link
Contributor

The target maintainer may have some background too, cc @uweigand.

On our platform the ABI specifies that symbol values are guaranteed to be 2-byte aligned. All compilers for the platform will (by default) enforce that property for symbols they generate, and assume that property for external symbols they reference.

(As an extension, at least in GCC you can in fact override this and force generation of a symbol that is not 2-byte aligned; this requires an explicit attribute ((aligned (1))) and strictly speaking causes the program to no longer comply with the ABI - any user of that symbol will also have to use the aligned attribute to ensure correct code generation.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. I-lang-nominated Nominated for discussion during a lang team meeting. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants