Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,18 @@ fn stackprotector_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll A
Some(sspattr.create_attr(cx.llcx))
}

fn packed_stack_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> Option<&'ll Attribute> {
if sess.target.arch != Arch::S390x {
return None;
Copy link
Member

Choose a reason for hiding this comment

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

Maybe panic here given that the frontend should already have emitted an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

hmm packed_stack_attr(...) is called every time llfn_attrs_from_instance is called indifferent of target arch.

And I think it would not be a good thing to add an arch check to llfn_attrs_from_instance as there are no other checks in that function. It blindly calls all possibilities and assumes that checks are already handled elsewhere.

}

if sess.opts.unstable_opts.packed_stack {
Some(llvm::CreateAttrString(cx.llcx, "packed-stack"))
} else {
None
}
}

pub(crate) fn target_cpu_attr<'ll>(cx: &SimpleCx<'ll>, sess: &Session) -> &'ll Attribute {
let target_cpu = llvm_util::target_cpu(sess);
llvm::CreateAttrStringValue(cx.llcx, "target-cpu", target_cpu)
Expand Down Expand Up @@ -519,6 +531,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
if let Some(align) = codegen_fn_attrs.alignment {
llvm::set_alignment(llfn, align);
}
if let Some(packed_stack) = packed_stack_attr(cx, sess) {
to_add.push(packed_stack);
}
to_add.extend(patchable_function_entry_attrs(
cx,
sess,
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_interface/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,13 @@ pub struct IgnoringOutDir;
#[diag("can't use option `-o` or `--emit` to write multiple output types to stdout")]
pub struct MultipleOutputTypesToStdout;

#[derive(Diagnostic)]
#[diag("packedstack with backchain needs softfloat")]
#[note(
"enabling both `packedstack` and `backchain` attributes is incompatible with the default s390x target. Switch to s390x-unknown-none-softfloat if you need both attributes!"
)]
pub struct PackedStackBackchainNeedsSoftfloat;

#[derive(Diagnostic)]
#[diag(
"target feature `{$feature}` must be {$enabled} to ensure that the ABI of the current target can be implemented correctly"
Expand Down
12 changes: 11 additions & 1 deletion compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use rustc_session::{EarlyDiagCtxt, Session, filesearch};
use rustc_span::edition::Edition;
use rustc_span::source_map::SourceMapInputs;
use rustc_span::{SessionGlobals, Symbol, sym};
use rustc_target::spec::Target;
use rustc_target::spec::{Abi, Arch, Target};
use tracing::info;

use crate::errors;
Expand Down Expand Up @@ -96,6 +96,16 @@ pub(crate) fn check_abi_required_features(sess: &Session) {
sess.dcx().emit_warn(errors::AbiRequiredTargetFeature { feature, enabled: "disabled" });
}
}

// we need to have access to the complete constructed `target` and the session options.
// 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"))
&& sess.target.abi != Abi::SoftFloat
{
sess.dcx().emit_err(errors::PackedStackBackchainNeedsSoftfloat);
}
}

pub static STACK_SIZE: OnceLock<usize> = OnceLock::new();
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_session/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -537,3 +537,7 @@ pub(crate) struct UnexpectedBuiltinCfg {
pub(crate) cfg_name: Symbol,
pub(crate) controlled_by: &'static str,
}

#[derive(Diagnostic)]
#[diag("`-Zpacked-stack` is only supported on s390x")]
pub(crate) struct UnsupportedPackedStack;
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2536,6 +2536,8 @@ options! {
"pass `-install_name @rpath/...` to the macOS linker (default: no)"),
packed_bundled_libs: bool = (false, parse_bool, [TRACKED],
"change rlib format to store native libraries as archives"),
packed_stack: bool = (false, parse_bool, [TRACKED],
"use packed stack frames (s390x only) (default: no)"),
panic_abort_tests: bool = (false, parse_bool, [TRACKED],
"support compiling tests with panic=abort (default: no)"),
panic_in_drop: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy, [TRACKED],
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
sess.dcx().emit_warn(errors::SoftFloatIgnored);
}
}

if sess.opts.unstable_opts.packed_stack {
if sess.target.arch != Arch::S390x {
sess.dcx().emit_err(errors::UnsupportedPackedStack);
}
Copy link
Member

Choose a reason for hiding this comment

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

This seems like the most reasonable place to check the backchain condition?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes i will move the other check here

Copy link
Contributor Author

@fneddy fneddy Feb 12, 2026

Choose a reason for hiding this comment

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

unfortunately feature flags are only parsed during codegen_backend.init(sess) which is one step after rustc_session::build_session(...). So no feature flags available to check at this point.

-> i need to check them in codegen_llvm or codegen_ssa.

Copy link
Member

Choose a reason for hiding this comment

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

Please avoid duplicating the check across the codegen backends.

The check seems to be somewhat similar in nature to

util::check_abi_required_features(&sess);
. So maybe rename check_abi_required_features to something slightly more general and do the check there?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes this seems, also to me, the only option left.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

there is another way.

I could try to talk to the llvm guys if its possible to make packed-stack a proper target-feature so we dont have to go over a cli argument.

Copy link
Member

Choose a reason for hiding this comment

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

Not sure if that would help. Target feature conflicts currently also need ad-hoc checks, we don't have a framework for dealing with them at the moment.

}
}

/// Holds data on the current incremental compilation session, if there is one.
Expand Down
37 changes: 37 additions & 0 deletions tests/assembly-llvm/s390x-packedstack-toggle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//@ add-minicore
//@ revisions: enable-packedstack default-packedstack
//@ assembly-output: emit-asm
//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-linux-gnu -Cforce-unwind-tables=no
//@ needs-llvm-components: systemz
//@[enable-packedstack] compile-flags: -Zpacked-stack
#![feature(no_core, lang_items)]
#![no_std]
#![no_core]

extern crate minicore;
use minicore::*;

extern "C" {
fn extern_func() -> i32;
}

// CHECK-LABEL: test_packedstack
#[no_mangle]
extern "C" fn test_packedstack() -> i32 {
// test the creation of call stack with and without packed-stack

// without packed-stack we always reserve a least the maximal space of 160 bytes
// default-packedstack: stmg %r14, %r15, 112(%r15)
// default-packedstack-NEXT: aghi %r15, -160
// default-packedstack-NEXT: brasl %r14, extern_func

// with packed-stack only the actually needed registers are reserved on the stack
// enable-packedstack: stmg %r14, %r15, 144(%r15)
// enable-packedstack-NEXT: aghi %r15, -16
// enable-packedstack-NEXT: brasl %r14, extern_func
unsafe {
extern_func();
}
1
// CHECK: br %r{{.*}}
}
16 changes: 16 additions & 0 deletions tests/codegen-llvm/packedstack.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//@ add-minicore
//@ compile-flags: -Copt-level=3 --crate-type=lib --target=s390x-unknown-linux-gnu -Zpacked-stack
//@ needs-llvm-components: systemz
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]

extern crate minicore;
use minicore::*;

#[no_mangle]

pub fn test_packedstack() {
// CHECK: @test_packedstack() unnamed_addr #0
}
// CHECK: attributes #0 = { {{.*}}"packed-stack"{{.*}} }
4 changes: 4 additions & 0 deletions tests/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1070,6 +1070,10 @@ Exercises operator overloading via [`std::ops`](https://doc.rust-lang.org/std/op

See [`repr(packed)` | Nomicon](https://doc.rust-lang.org/nomicon/other-reprs.html#reprpacked-reprpackedn).

## `tests/ui/packedstack/`

Tests different combinations that `-Zpacked-stack` will affect.

## `tests/ui/panic-handler/`

See [panic handler | Nomicon](https://doc.rust-lang.org/nomicon/panic-handler.html).
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/packedstack/combination.need_softfloat.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
warning: unstable feature specified for `-Ctarget-feature`: `backchain`
|
= note: this feature is not stably supported; its behavior can change in the future

error: packedstack with backchain needs softfloat
|
= note: enabling both `packedstack` and `backchain` attributes is incompatible with the default s390x target. Switch to s390x-unknown-none-softfloat if you need both attributes!

error: aborting due to 1 previous error; 1 warning emitted

29 changes: 29 additions & 0 deletions tests/ui/packedstack/combination.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//@ revisions: wrong_arch only_packedstack need_softfloat with_softfloat
//@ compile-flags: -Zpacked-stack --crate-type=lib

//@ [wrong_arch] compile-flags: --target=x86_64-unknown-linux-gnu
//@ [wrong_arch] needs-llvm-components: x86

//@ [only_packedstack] compile-flags: --target=s390x-unknown-linux-gnu
//@ [only_packedstack] build-pass
//@ [only_packedstack] needs-llvm-components: systemz

//@ [need_softfloat] compile-flags: -Ctarget-feature=+backchain --target=s390x-unknown-linux-gnu
//@ [need_softfloat] check-fail
//@ [need_softfloat] needs-llvm-components: systemz

//@ [with_softfloat] compile-flags: -Ctarget-feature=+backchain
//@ [with_softfloat] compile-flags: --target=s390x-unknown-none-softfloat
//@ [with_softfloat] build-pass
//@ [with_softfloat] needs-llvm-components: systemz

//@ ignore-backends: gcc

#![feature(no_core)]
#![crate_type = "rlib"]
#![no_core]

//[wrong_arch]~? ERROR `-Zpacked-stack` is only supported on s390x
//[need_softfloat]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain`
//[need_softfloat]~? ERROR packedstack with backchain needs softfloat
//[with_softfloat]~? WARN unstable feature specified for `-Ctarget-feature`: `backchain`
6 changes: 6 additions & 0 deletions tests/ui/packedstack/combination.with_softfloat.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
warning: unstable feature specified for `-Ctarget-feature`: `backchain`
|
= note: this feature is not stably supported; its behavior can change in the future

warning: 1 warning emitted

4 changes: 4 additions & 0 deletions tests/ui/packedstack/combination.wrong_arch.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: `-Zpacked-stack` is only supported on s390x

error: aborting due to 1 previous error

Loading