Skip to content

stabilize s390x specific target-feature backchain#158612

Open
fneddy wants to merge 1 commit into
rust-lang:mainfrom
fneddy:stabilize-backchain
Open

stabilize s390x specific target-feature backchain#158612
fneddy wants to merge 1 commit into
rust-lang:mainfrom
fneddy:stabilize-backchain

Conversation

@fneddy

@fneddy fneddy commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

PRELIMINARY - STILL IN WORK

Stabilization report: s390x backchain target feature

Summary

This stabilizes the s390x (SystemZ) target feature backchain.

When backchain is enabled, the function prologue stores the caller's stack
pointer into the first slot (the backchain slot) of the function's stack
frame. This links all stack frames into a chain that can be walked without
DWARF/CFI unwind information, which is how the Linux kernel unwinds the stack
on s390x. The primary motivation for stabilization is Rust-for-Linux: the s390x
kernel is compiled with backchain enabled (-mbackchain in GCC/Clang), and
Rust kernel code must match.

backchain is not a hardware (ISA) capability — it is a pure codegen option,
available on every s390x CPU. The feature name matches LLVM's SystemZ feature
backchain; GCC and Clang expose the same functionality as -mbackchain.

Tracking:

Reference PRs:

  • TODO (link Reference PR adding backchain to the s390x target-feature table)

What is stabilized

On s390x targets, backchain becomes a stable target feature, i.e. all of the
following are accepted on stable without warnings:

// per function
#[target_feature(enable = "backchain")]
pub fn in_kernel_context() { ... }

// detection of a compiler-enabled backchain
#[cfg(target_feature = "backchain")]
fn walk_backchain() { ... }

and on the command line:

rustc -Ctarget-feature=+backchain ...

What isn't stabilized

  • All other s390x target features (vector-* extensions were stabilized
    separately in 1.93 via s390x_target_feature_vector; the remaining ISA
    features stay gated behind s390x_target_feature).
  • -Zpacked-stack (the GCC -mpacked-stack equivalent) remains unstable; only
    its interaction with backchain is relevant here (see below).
  • soft-float remains unstable.

Design

Reference

The Reference documents stable target features per architecture in
attributes/codegen.md. A PR adding backchain to the s390x table accompanies
this stabilization: TODO link.

RFC history

None. Target features are added and stabilized through the tracking-issue /
stabilization-report process rather than the RFC process.

Answers to unresolved questions

The tracking issue (#150259) listed one unresolved question about
the packed-stack interaction (#152432). It has no impact on
backchain itself, which stays a regular target feature matching how LLVM
models it; the packed-stack combination is handled as described in Key points.
No unresolved questions remain.

Post-RFC changes

None (no RFC; see above).

Key points

The only design decision of note is how to handle the interaction with the
(unstable) -Zpacked-stack option. A packed stack frame has no backchain
slot unless soft-float is also enabled, so the packed-stack + backchain +
hard-float combination cannot be lowered and makes LLVM ICE. rustc rejects
it up front with a dedicated hard error (#152432). backchain on
its own is uncontentious: it is a pure, additive codegen option available on
every s390x CPU.

Nightly extensions

The remaining s390x ISA target features stay gated behind
s390x_target_feature, and -Zpacked-stack and soft-float remain unstable.
Stabilizing backchain commits us to nothing about those: it is a single,
self-contained codegen flag whose only cross-feature interaction
(packed-stack) is guarded by a hard error (see Key points).

Doors closed

None. backchain maps directly onto the LLVM backchain feature and the
established -mbackchain semantics shared with GCC/Clang, so stabilizing it
does not constrain future language or target-feature work.

Feedback

Call for testing

No formal "call for testing" was issued. The feature has been exercised on
nightly by the Rust-for-Linux s390x work (see Nightly use).

Nightly use

The known nightly consumer is Rust-for-Linux: the s390x kernel is built with
-mbackchain, so Rust kernel code targeting s390x must enable backchain to
match. This is the motivation for stabilization.

Implementation

Major parts

Coverage

  • tests/codegen-llvm/backchain.rs-Ctarget-feature=+backchain results in
    the +backchain LLVM function attribute.
  • tests/assembly-llvm/s390x-backchain-toggle.rs — the prologue actually
    stores the backchain when enabled (+backchain), and does not when disabled
    (-backchain) or by default.
  • tests/ui/target-feature/packedstack-combinations.rs — the
    packed-stack/backchain interaction: rejected on hard-float targets
    whether backchain comes from #[target_feature] or -Ctarget-feature,
    accepted on s390x-unknown-none-softfloat.
  • tests/codegen-llvm/packedstack.rspacked-stack attribute emission on
    the soft-float target.
  • tests/ui/check-cfg/target_feature.rsbackchain is a known value for
    cfg(target_feature).

There are no known or intentional gaps in coverage.

Outstanding bugs

None. The former blocker #142412 is fixed.

Outstanding FIXMEs

None.

Tool changes

None required — target features need no support from these tools beyond what
exists generically.

  • rustfmt
    • Not applicable.
  • rust-analyzer
    • Not applicable.
  • rustdoc (both JSON and HTML)
    • Not applicable.
  • cargo
    • Not applicable.
  • clippy
    • Not applicable.
  • rustup
    • Not applicable.
  • docs.rs
    • Not applicable.

Breaking changes

None. This stabilization only makes an already-existing nightly target feature
available on stable; it does not change the meaning of any existing code, so no
crater run is applicable.

Crater report:

  • Not applicable.

Crater analysis:

  • Not applicable.

PRs to affected crates:

  • Not applicable.

Type system, opsem

Compile-time checks

The only compile-time check is the rejection of the invalid packed-stack +
backchain + hard-float combination, which LLVM cannot lower and would ICE
on. rustc emits a dedicated hard error up front (#152432); see
Coverage for the test.

Type system rules

No new type system rules. backchain is governed by the existing
target_feature 1.1 rules for enabling and detecting target features; it adds
no feature-specific typing rules.

Sound by default?

Yes. It does not change the calling convention or any type's ABI: the
backchain slot is part of the standard s390x ELF ABI stack frame layout, and
the feature only controls whether the prologue stores into it. Since it is not
a hardware
capability (see Summary), the #[target_feature] caller obligation is trivially
satisfied on every s390x CPU, so no unsafe opt-in is needed.

Breaks the AM?

No. It cannot introduce undefined behavior or expose the underlying
assembly-level implementation. The one invalid combination is rejected at
compile time (see Compile-time checks).

Common interactions

Temporaries

Not applicable. The feature introduces no new expressions and therefore no new
temporaries.

Drop order

Not applicable. The feature does not affect the order in which values are
dropped.

Pre-expansion / post-expansion

Not applicable. backchain raises no new pre- vs. post-expansion questions; it
is handled like any other target feature in #[target_feature] and
cfg(target_feature).

Edition hygiene

Not applicable. The feature is not gated on an edition.

SemVer implications

No new hazards beyond those that already apply to #[target_feature]
generally. As with any target feature, adding or removing
#[target_feature(enable = "backchain")] on a public function can affect
whether it can be used as a plain function pointer, so it follows the existing
target_feature conventions; backchain introduces nothing beyond that.

Exposing other features

None. Its only interaction with an unstable feature is the guarded
-Zpacked-stack combination (see Key points); no packed-stack behavior leaks
onto stable.

History

See Major parts for the annotated implementation PRs. Additional context not
listed there:

Acknowledgments

  • @liushuyu — initial implementation of the backchain target feature
  • @RalfJung — target-feature unification, cfg-detection fix, ABI review
  • @uweigand — s390x maintainer, architecture expert
  • @fneddypacked-stack support, soft-float target, this stabilization

No one who worked on this has objected to stabilizing it now.

Open items

  • Land the Reference PR adding backchain to the s390x target-feature
    table and replace the TODO link above.

@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 30, 2026
@rustbot

rustbot commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

r? @petrochenkov

rustbot has assigned @petrochenkov.
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 73 candidates
  • Random selection from 17 candidates

@rust-log-analyzer

Copy link
Copy Markdown
Collaborator

The job tidy failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
fmt: checked 6968 files
tidy check
tidy [rustdoc_json (src)]: `rustdoc-json-types` modified, checking format version
tidy: Skipping binary file check, read-only filesystem
tidy [style (tests)]: /checkout/tests/ui/target-feature/packedstack-combinations.rs:2: line longer than 100 chars
tidy [style (tests)]: FAIL
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'venv'
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'virtualenv'
Requirement already satisfied: pip in ./build/venv/lib/python3.10/site-packages (26.1.1)
Collecting pip
---
info: ✓ ES-Check passed! All files are ES10 compatible.
typechecking javascript files
tidy: The following check failed: style (tests)
Bootstrap failed while executing `test src/tools/tidy tidyselftest --extra-checks=py,cpp,js,spellcheck`
Command `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools-bin/rust-tidy --root-path=/checkout --cargo-path=/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo --output-dir=/checkout/obj/build --concurrency=4 --npm-path=/node/bin/yarn --ci=true --extra-checks=py,cpp,js,spellcheck` failed with exit code 1
Created at: src/bootstrap/src/core/build_steps/tool.rs:1625:23
Executed at: src/bootstrap/src/core/build_steps/test.rs:1646:29

--- BACKTRACE vvv
   0: <bootstrap::utils::exec::DeferredCommand>::finish_process
             at /checkout/src/bootstrap/src/utils/exec.rs:939:17
   1: <bootstrap::utils::exec::DeferredCommand>::wait_for_output::<&bootstrap::utils::exec::ExecutionContext>
             at /checkout/src/bootstrap/src/utils/exec.rs:831:21
   2: <bootstrap::utils::exec::ExecutionContext>::run
             at /checkout/src/bootstrap/src/utils/exec.rs:741:45
   3: <bootstrap::utils::exec::BootstrapCommand>::run::<&bootstrap::core::builder::Builder>
             at /checkout/src/bootstrap/src/utils/exec.rs:339:27
   4: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1646:29
   5: <bootstrap::core::builder::Builder>::ensure::<bootstrap::core::build_steps::test::Tidy>
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1597:36
   6: <bootstrap::core::build_steps::test::Tidy as bootstrap::core::builder::Step>::make_run
             at /checkout/src/bootstrap/src/core/build_steps/test.rs:1568:21
   7: <bootstrap::core::builder::StepDescription>::maybe_run
             at /checkout/src/bootstrap/src/core/builder/mod.rs:476:13
   8: bootstrap::core::builder::cli_paths::match_paths_to_steps_and_run
             at /checkout/src/bootstrap/src/core/builder/cli_paths.rs:232:18
   9: <bootstrap::core::builder::Builder>::run_step_descriptions
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1140:9
  10: <bootstrap::core::builder::Builder>::execute_cli
             at /checkout/src/bootstrap/src/core/builder/mod.rs:1119:14
  11: <bootstrap::Build>::build
             at /checkout/src/bootstrap/src/lib.rs:803:25
  12: bootstrap::main
             at /checkout/src/bootstrap/src/bin/main.rs:130:11
  13: <fn() as core::ops::function::FnOnce<()>>::call_once
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/core/src/ops/function.rs:250:5
  14: std::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/sys/backtrace.rs:166:18
  15: std::rt::lang_start::<()>::{closure#0}
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/rt.rs:206:18
  16: <&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe as core::ops::function::FnOnce<()>>::call_once
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/core/src/ops/function.rs:287:21
  17: std::panicking::catch_unwind::do_call::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:581:40
  18: std::panicking::catch_unwind::<i32, &dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:544:19
  19: std::panic::catch_unwind::<&dyn core::ops::function::Fn<(), Output = i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe, i32>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panic.rs:359:14
  20: std::rt::lang_start_internal::{closure#0}
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/rt.rs:175:24
  21: std::panicking::catch_unwind::do_call::<std::rt::lang_start_internal::{closure#0}, isize>
             at /rustc/0417c25868d6dfbd1c291dfeae950504faa6f790/library/std/src/panicking.rs:581:40
---
  28: __libc_start_main
  29: _start


Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:02:37
  local time: Tue Jun 30 12:05:56 UTC 2026
  network time: Tue, 30 Jun 2026 12:05:56 GMT
##[error]Process completed with exit code 1.
##[group]Run echo "disk usage:"

@ehuss

ehuss commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

As this is an architecture specific option I did NOT update the the docs and
did NOT write a stabilization report

Target features always need to be documented (example from a past s390x stabilization).

Also, since these always need a lang FCP, they generally need a written proposal as to what is being stabilized in order for them to make a decision.

@petrochenkov petrochenkov 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 30, 2026
@RalfJung

RalfJung commented Jul 1, 2026

Copy link
Copy Markdown
Member

According to target expert @uweigand, there are no ABI concerns with this feature (having some parts of the code compiled with and some without can lead to poor backtraces but doesn't break anything worse than that). So 👍 from the ABI side.

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-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.

6 participants