Skip to content

add rustc option -Zpacked-stack#152432

Merged
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
fneddy:s390x_packed_stack_attribute
Mar 31, 2026
Merged

add rustc option -Zpacked-stack#152432
rust-bors[bot] merged 1 commit intorust-lang:mainfrom
fneddy:s390x_packed_stack_attribute

Conversation

@fneddy
Copy link
Copy Markdown
Contributor

@fneddy fneddy commented Feb 10, 2026

View all comments

this enables -Zpacked-stack just as -mpacked-stack in clang and gcc. packed-stack is needed on s390x for kernel development.

For reference: #151154 and #150766

look at @uweigand s post for full explanation of what this does. Here a wrap-up:

#150766 (comment)

[...]
packed-stack [...] modifies how the compiler-generated function prolog/epilog code makes use of the 160 byte register save area provided by a caller to the callee [...] this variant is not actually incompatible with the ABI - packed-stack and regular functions can freely call each other without ABI issues.
[...]
combination of -mpacked-stack and -mbackchain [...] the location in the stack frame where the backchain link ought to be stored is not available. [...] is not supported at all with the default ABI
[...]
However, in the special case of also using soft-float, our (implied) soft-float ABI provides a different location for the backchain that is compatible with -mpacked-stack, so that combination should be supported
[...]

@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 Feb 10, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Feb 10, 2026

r? @chenyukang

rustbot has assigned @chenyukang.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 66 candidates
  • Random selection from 14 candidates

@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Feb 10, 2026

@fneddy fneddy marked this pull request as draft February 10, 2026 10:24
@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 Feb 10, 2026
@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Feb 10, 2026

I'll add tests for assembly output and for target incompatibility.

@rust-log-analyzer

This comment has been minimized.

@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from 5ddcabb to 4ebec9d Compare February 10, 2026 11:29
@fneddy fneddy marked this pull request as ready for review February 13, 2026 11:19
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Feb 13, 2026
@rust-bors

This comment has been minimized.

@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from 0d6d167 to 0c182af Compare February 13, 2026 12:58
@rustbot

This comment has been minimized.

@rust-bors

This comment has been minimized.

@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from 0c182af to 7fef6ea Compare February 16, 2026 09:35
@rustbot

This comment has been minimized.

@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Feb 16, 2026

ok, i think most should be ok now.

@rust-log-analyzer

This comment has been minimized.

@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from 7fef6ea to 31a40dc Compare February 16, 2026 09:50
if sess.target.arch == Arch::S390x
&& sess.opts.unstable_opts.packed_stack
&& sess.unstable_target_features.contains(&Symbol::intern(&"backchain"))
&& sess.target.abi != Abi::SoftFloat
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

target.abi is just in charge of cfg(target_abi), it doesn't control the actual ABI. Please check rustc_abi which controls the actual ABI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

changed it to check on the soft-float unstable_target_feature which llvm will evaluate to switch abi for s390x.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think checking rustc_abi makes most sense.

// this is the first place in the `run_compiler` flow where all this is available
if sess.target.arch == Arch::S390x
&& sess.opts.unstable_opts.packed_stack
&& sess.unstable_target_features.contains(&Symbol::intern(&"backchain"))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What happens if someone tries to enable backchain just for a particular function via #[target_feature] instead of -Ctarget-feature?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ufff yes we have to check this for every call to llfn_attrs_from_instance at compiler runtime. is it ok to do ....contains(&Symbol::intern(... every time?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

from_target_feature_attr is probably a better, higher-level place to check this?

You can add backchain as a pre-interned symbol in compiler/rustc_span/src/symbol.rs so you don't have to re-intern it every time.

Copy link
Copy Markdown
Contributor Author

@fneddy fneddy Feb 24, 2026

Choose a reason for hiding this comment

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

I am back on working on this. yes in from_target_feature_attr we can check for the #[target_feature(...)] attributes. BUT unfortunately not for the -Ctarget-feature... attributes ..

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Yeah the handling for -Ctarget-feature and #[target_feature] is entirely separate. Maybe it's possible to introduce a new helper that gets called form those 2 places and that performs these kinds of consistency checks?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah I see you're now doing the check in packed_stack_attr. That also seems reasonable.

@rust-log-analyzer

This comment has been minimized.

@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from d886fbf to f39c52b Compare February 16, 2026 14:18
@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from e9e5f4c to fd39c98 Compare March 20, 2026 13:17
@rustbot

This comment has been minimized.

@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Mar 20, 2026

Kind reminder this PR exists and breaks every now and then due to main -changes.

@RalfJung
Copy link
Copy Markdown
Member

r? @nikic

@rustbot rustbot assigned nikic and unassigned davidtwco Mar 20, 2026
@rust-bors

This comment has been minimized.

this enables packed-stack just as -mpacked-stack in clang and gcc.
packed-stack is needed on s390x for kernel development.

Co-authored-by: Ralf Jung <post@ralfj.de>
@fneddy fneddy force-pushed the s390x_packed_stack_attribute branch from fd39c98 to f39fa9e Compare March 31, 2026 07:09
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 31, 2026

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Mar 31, 2026

@rustbot ready

@nikic
Copy link
Copy Markdown
Contributor

nikic commented Mar 31, 2026

The interaction with LLVM looks fine.

A question I have is whether it is normal to emit errors during codegen attribute lowering?

Do I understand correctly that if -Z packed-stack is used, then any use of #[target_feature(enable = "backchain")] becomes a hard error? That seems quite unusual. (Does anyone have a reference for why s390x has a per-function backchain feature that is not integrated with the usual frame pointer options?)

@RalfJung
Copy link
Copy Markdown
Member

Do I understand correctly that if -Z packed-stack is used, then any use of #[target_feature(enable = "backchain")] becomes a hard error? That seems quite unusual.

Yeah it's a hack to deal with a somewhat ill-behaved target.

Can you think of a better way of dealing with this?

@nikic
Copy link
Copy Markdown
Contributor

nikic commented Mar 31, 2026

Do I understand correctly that if -Z packed-stack is used, then any use of #[target_feature(enable = "backchain")] becomes a hard error? That seems quite unusual.

Yeah it's a hack to deal with a somewhat ill-behaved target.

Can you think of a better way of dealing with this?

Not having backchain as a per-function target feature would be one way... Another would be to have packed-stack as part of the target definition.

@fneddy
Copy link
Copy Markdown
Contributor Author

fneddy commented Mar 31, 2026

Options:

disallow backchain- per-function

this would be via an explicit check during parsing or apply of codegen_fn_attrs and error if it is set? I don't see a way to mark a target_feature as allowed via target_spec_file AND cli AND NOT inline

packed_stack-part of target definition

I think we don't want to add packed-stack to any specific target. A dev could decide to use it with the regular target or with the softfloat target. Also packed-stack is currently NOT part of the target_features in llvm. Its just a frontend-flag that will set the function attribute. So we cannot add packed-stack to IBMZ_FEATURES.

Sidenote

If one tries to feed the backend with a function where backchain and packed-stack and not soft-float is set the backend will panic.

@uweigand
Copy link
Copy Markdown
Contributor

Does anyone have a reference for why s390x has a per-function backchain feature that is not integrated with the usual frame pointer options?

s390x has a frame pointer, which is used for accessing local variables and stack slots in functions using variable-sized stack allocation - the main purpose of frame pointers everywhere. On some other platforms (in particular x86 and arm), the frame pointer can also be used for stack unwinding, but that does not work on s390x, because our frame pointer indicates the bottom of the stack frame (like the stack pointer), not the top of the stack frame. The main reason for this is that some instructions do not support negative displacements, so a pointer to the top of the stack frame would be awkward to use.

Because the frame pointer is not usable for stack unwinding, there's no point in trying to use something like -fno-omit-frame-pointer on s390x. Instead, we have a separate stack backchain feature (which is unrelated to the frame pointer) that can be activated via -mbackchain; this is only used for frame unwinding in certain scenarios where DWARF CFI is not available, and it is not active by default.

@uweigand
Copy link
Copy Markdown
Contributor

Not sure whether the per-function notion is a particular problem, but this aspect isn't really important - users typically enable backchain for the whole compilation unit. The fact that this is modeled in LLVM as a "target feature" is really more of an implementation detail. If this simplifies the Rust logic, I'd also be fine with only supporting a command line option like -Z backchain and prohibit use of the target feature.

The one important use case is the Linux kernel, which is fully built with backchain, packed-stack, and soft-float. This combination must work (and be active for the kernel target).

@RalfJung
Copy link
Copy Markdown
Member

RalfJung commented Mar 31, 2026

I don't see a way to mark a target_feature as allowed via target_spec_file AND cli AND NOT inline

Yeah this is currently not a thing. Conceptually it's not that hard to add, but doing it in a way that the target feature table does not become a lot more verbose could be tricky.

This is all still unstable obviously so we could also just leave a note on the backchain tracking issue that this should probably not be stabilized for per-function use, only for -C target-feature. (EDIT: I added a note in #150259.)

@nikic
Copy link
Copy Markdown
Contributor

nikic commented Mar 31, 2026

Because the frame pointer is not usable for stack unwinding, there's no point in trying to use something like -fno-omit-frame-pointer on s390x. Instead, we have a separate stack backchain feature (which is unrelated to the frame pointer) that can be activated via -mbackchain; this is only used for frame unwinding in certain scenarios where DWARF CFI is not available, and it is not active by default.

I think in practice, "I want a frame pointer" really means "I want non-DWARF unwind", which is why I consider frame pointers and backchain to be the same thing, even if they technically aren't... But I guess the ship here has sailed in terms of option naming.

@nikic
Copy link
Copy Markdown
Contributor

nikic commented Mar 31, 2026

@bors r+

As everything involved here is unstable anyway, I think this is fine to land as-is...

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors bot commented Mar 31, 2026

📌 Commit f39fa9e has been approved by nikic

It is now in the queue for this repository.

@rust-bors rust-bors bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 31, 2026
rust-bors bot pushed a commit that referenced this pull request Mar 31, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - #150752 (Update libc to v0.2.183)
 - #152432 (add rustc option -Zpacked-stack)
 - #154634 (Use `Hcx`/`hcx` consistently for `StableHashingContext`.)
 - #154635 (./x run miri: default to edition 2021)
@rust-bors rust-bors bot merged commit f883d62 into rust-lang:main Mar 31, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 31, 2026
rust-timer added a commit that referenced this pull request Mar 31, 2026
Rollup merge of #152432 - fneddy:s390x_packed_stack_attribute, r=nikic

add rustc option -Zpacked-stack

this enables `-Zpacked-stack` just as `-mpacked-stack` in clang and gcc. packed-stack is needed on s390x for kernel development.

For reference: #151154 and #150766

look at @uweigand s post for full explanation of what this does. Here a wrap-up:

#150766 (comment)
> [...]
> packed-stack [...] modifies how the compiler-generated function prolog/epilog code makes use of the 160 byte register save area provided by a caller to the callee [...]  this variant is not actually incompatible with the ABI - packed-stack and regular functions can freely call each other without ABI issues.
> [...]
> combination of -mpacked-stack and -mbackchain [...]  the location in the stack frame where the backchain link ought to be stored is not available. [...] is not supported at all with the default ABI
> [...]
> However, in the special case of also using soft-float, our (implied) soft-float ABI provides a different location for the backchain that is compatible with -mpacked-stack, so that combination should be supported
> [...]
github-actions bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Apr 6, 2026
…uwer

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#150752 (Update libc to v0.2.183)
 - rust-lang/rust#152432 (add rustc option -Zpacked-stack)
 - rust-lang/rust#154634 (Use `Hcx`/`hcx` consistently for `StableHashingContext`.)
 - rust-lang/rust#154635 (./x run miri: default to edition 2021)
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. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.