You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Tracking Issue for -Ctarget-feature=+backchain #158014
This is a tracking issue for the -Ctarget-feature=+backchain feature on s390x.
About tracking issues
Tracking issues are used to record the overall progress of implementation.
They are also used as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.
Discussion comments will get marked as off-topic or deleted.
Repeated discussions on the tracking issue may lead to the tracking issue getting locked.
Should this use the new -Zllvm-target-feature? (Context, PR) I see backchain in the table of the Rust ones, so perhaps not.
In addition / relatedly, if I understand correctly, the flag can be an ABI concern if mixed with -Zpacked-stack (which the compiler already rejects). Thus, should this be mentioned at #131837?
Finally, there is #150259 -- linking it from here, though I am not sure if it is expected to have individual tracking issues in addition to that one.
I will check if we can still do the necessary checks with -Zllvm-target-feature.
Currently this checks are not very well tied into one place, but a little scattered. I dislike the current state, maybe I can clean it up a little with this infrastructure.
The question is, can one cause ABI trouble by mixing different values for backchain in different compilation units? AFAIK we concluded that no one cannot, but I am not an expert. In particular I wonder what happens if some compilation units use -Ctarget-feature=+backchain, some use -Zpacked-stack, but none of them use both so the check does not get triggered.
Or is -Zpacked-stack a target modifier (i.e. forced to be consistent across the entire crate graph)?
@uweigand had a good write-up about this here1. In essence: you should NOT combine backchain and packed-stack (unless combined with softfloat for the kernel) in the same compilation unit. We check that in rust2 and it also in llvm3. As far as I understand, it its possible to call from backchain to packed-stack and reverse back and forth. I *think* it will break backchain-unwind but call-wise it's all fine.
you should NOT combine backchain and packed-stack (unless combined with softfloat for the kernel) in the same compilation unit.
(emphasis mine)
As long as that's a per-compilation-unit requirement, not a global one, the current checks should be fine. No reason to use -Zllvm-target-feature.
Though of course if the target maintainers think that backchain should only be changed globally, and it should be impossible to use e.g. a std without "backchain" together with an application with "backchain", then we should use -Zllvm-target-feature (or a separate target modifier flag). That would however also mean that "backchain" cannot be used with the prebuilt standard library.
Let me try to summarize again. This whole issue is a bit tricky as we need to consider the interaction of three distinct options: backchain, packed-stack, and soft-float. The following main principles apply:
soft-float is a global ABI-changing option that affects interoperability. Either everything or nothing must be built with soft-float. (De facto usage: the Linux kernel uses soft-float globally, all user-space code including libraries does not use soft-float.)
backchain does (generally) not affect interoperability You can switch between backchain and no-backchain at any function boundary, either between or within a compilation unit. However, in order to actually use the backchain for stack unwinding for debug purposes, all relevant code must be built with backchain. We consider this a "soft" requirement that's up to the user to ensure if they care about this, the compiler should not enforce anything here. (De facto usage: code by default does not use backchain, it is only enabled manually in some places that have specific debugging needs, e.g. the Linux kernel or some user-space environments like JITs where some code does not come with proper DWARF CFI.)
packed-stack does not affect interoperability at all, and there is no observable side effect of intermixing packed and non-packed functions whatsoever. However, it is impossible to generate code using bothbackchainandpacked-stack, unlesssoft-float is also in effect. This is a fully local requirement that applies on a per-function basis and must be enforced by the compiler (or else the back-end will abort with an internal error). (De facto usage: not normally used in user-space. Always used by the Linux kernel where kernel stack space is precious. Note that the kernel also uses both backchain and soft-float, so the requirement is satisfied.)
In particular I wonder what happens if some compilation units use -Ctarget-feature=+backchain, some use -Zpacked-stack, but none of them use both so the check does not get triggered.
This works fine. (With the exception that of course you will not get a reliable backtrace, as always when usage of backchain is inconsistent across the whole program.)
backchain is used in the userspace (Ubuntu compiles everything with backchain enabled).
I dont know, and cannot find, if there is any use of packed-stackin userspace enabled by any package or distribution.
@uweigand and I had a talk and we prefer to go forward and stabilize backchain and packed-stack. For backchain we know that there are people who want to use that. And for packed-stack we also want to make it available in stable.
The -Zllvm-target-feature option might be a good intermediate option for the Kernel folks. But our main goal is to get this two options stable.
I will start a stabilization PR first for backchain and later for packed-stack.
backchain is represented as a target feature, packed-stack is a dedicated compiler flag. Is there a specific reason for that difference?
Right now, the LLVM back-end does not actually have a packed-stack target feature. Thinking about this more, this seems to be more of an historical accident. Initially, neither packed-stack nor backchain were supported as target features. Rather, both features could only be triggered via LLVM IR function attributes. The -mbackchain and -mpacked-stack command line arguments to Clang set the corresponding function attribute on all functions of the current compilation unit.
The target feature for backchain was introduced much later here: llvm/llvm-project#71668, with the argument that this is needed to enable the __attribute__((target("backchain"))) syntax for GCC compatibility. The same was never done for packed-stack - even though the same argument could have been made; GCC does suport __attribute__((target("packed-stack"))) as well. I guess the difference is that there is some code out there using the former but not the latter.
Nevertheless, if it would make Rust integration easier, I guess we could just add a packed-stack target feature to LLVM with the same reasoning. This would implicitly add a dependency on a (future) LLVM version to Rust, though.
I'd like us to first and foremost think about the UI we want to expose from the Rust side. We can have something be a target feature in Rust without it being a target feature in LLVM. (Though that is a bit of a pain. We should probably make it easier to implement that rather than adding ad-hoc hacks each time we need this.)
I am not sure about what the trade-offs are between making something a target feature vs. a -C flag. Some differences that come to mind:
A -C flag makes it seem much more "built-in" to the compiler. Every such flag is a dedicated field in the rust compiler session, target specs (if applicable), and so on.
Target features can typically be enabled (but not disabled!) on a per-function basis (#[target_feature]), and can be queried via cfg (cfg!(target_feature)).
I don't know how to use those differences to decide what makes most sense for any particular flag, but I noticed you talking about backchain and packed-stack as very similar kinds of things so it would seem odd that we make a different decision for the two of them.
@rust-lang/compiler if someone has thoughts on target features vs compiler flags, or if we maybe even have some useful precedent or guidelines for that, please chime in. :)
IMHO making packed-stack a target-feature would feel cleaner.
I don't know the overall impact of making it a target-feature in llvm. As far as I know only clang is the other frontend that has a packed-stack option.
It just occurred to me that if we make packed-stack a target-feature we automatically support it via the #[target_feature] function attribute. This means one can endup with a call-stack where backchain and packed-stack is mixed. I doubt that we want to analyze each and every possible call-stack during compilation to check for this.
So for me this results in the question:
Should we forbid backchain and (if we make packed-stack a target-feature) also target-feature from being set by function attributes within the code?
It's supported to mix packed-stack and backchain arbitrarily on a per-function basis. (Of course always under the caveat that if you want to use packed-stackandbackchain on any single function, the compilation unit has to use soft-float.)
Activity
ojeda commentedon Jun 17, 2026
@rustbot label +A-rust-for-linux
ojeda commentedon Jun 17, 2026
Should this use the new
-Zllvm-target-feature? (Context, PR) I seebackchainin the table of the Rust ones, so perhaps not.In addition / relatedly, if I understand correctly, the flag can be an ABI concern if mixed with
-Zpacked-stack(which the compiler already rejects). Thus, should this be mentioned at #131837?Finally, there is #150259 -- linking it from here, though I am not sure if it is expected to have individual tracking issues in addition to that one.
Thanks for tracking this!
Cc @RalfJung
fneddy commentedon Jun 17, 2026
I will check if we can still do the necessary checks with
-Zllvm-target-feature.Currently this checks are not very well tied into one place, but a little scattered. I dislike the current state, maybe I can clean it up a little with this infrastructure.
RalfJung commentedon Jun 23, 2026
Did you mean
-Zpacked-stack?RalfJung commentedon Jun 23, 2026
The question is, can one cause ABI trouble by mixing different values for
backchainin different compilation units? AFAIK we concluded that no one cannot, but I am not an expert. In particular I wonder what happens if some compilation units use-Ctarget-feature=+backchain, some use-Zpacked-stack, but none of them use both so the check does not get triggered.Or is
-Zpacked-stacka target modifier (i.e. forced to be consistent across the entire crate graph)?ojeda commentedon Jun 23, 2026
Yeah -- fixed there.
fneddy commentedon Jun 24, 2026
@uweigand had a good write-up about this here1. In essence: you should NOT combine
backchainandpacked-stack(unless combined withsoftfloatfor the kernel) in the same compilation unit. We check that in rust2 and it also in llvm3. As far as I understand, it its possible to call frombackchaintopacked-stackand reverse back and forth. I *think* it will breakbackchain-unwind but call-wise it's all fine.Footnotes
https://github.com/rust-lang/rust/pull/150766#issuecomment-3729074303 ↩
https://github.com/rust-lang/rust/blob/main/compiler/rustc_codegen_llvm/src/attributes.rs#L362 ↩
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/SystemZ/SystemZFrameLowering.cpp#L917 ↩
RalfJung commentedon Jun 24, 2026
(emphasis mine)
As long as that's a per-compilation-unit requirement, not a global one, the current checks should be fine. No reason to use
-Zllvm-target-feature.Though of course if the target maintainers think that
backchainshould only be changed globally, and it should be impossible to use e.g. astdwithout "backchain" together with an application with "backchain", then we should use-Zllvm-target-feature(or a separate target modifier flag). That would however also mean that "backchain" cannot be used with the prebuilt standard library.uweigand commentedon Jun 24, 2026
Let me try to summarize again. This whole issue is a bit tricky as we need to consider the interaction of three distinct options:
backchain,packed-stack, andsoft-float. The following main principles apply:soft-floatis a global ABI-changing option that affects interoperability. Either everything or nothing must be built withsoft-float. (De facto usage: the Linux kernel usessoft-floatglobally, all user-space code including libraries does not usesoft-float.)backchaindoes (generally) not affect interoperability You can switch betweenbackchainandno-backchainat any function boundary, either between or within a compilation unit. However, in order to actually use the backchain for stack unwinding for debug purposes, all relevant code must be built withbackchain. We consider this a "soft" requirement that's up to the user to ensure if they care about this, the compiler should not enforce anything here. (De facto usage: code by default does not use backchain, it is only enabled manually in some places that have specific debugging needs, e.g. the Linux kernel or some user-space environments like JITs where some code does not come with proper DWARF CFI.)packed-stackdoes not affect interoperability at all, and there is no observable side effect of intermixing packed and non-packed functions whatsoever. However, it is impossible to generate code using bothbackchainandpacked-stack, unlesssoft-floatis also in effect. This is a fully local requirement that applies on a per-function basis and must be enforced by the compiler (or else the back-end will abort with an internal error). (De facto usage: not normally used in user-space. Always used by the Linux kernel where kernel stack space is precious. Note that the kernel also uses bothbackchainandsoft-float, so the requirement is satisfied.)This works fine. (With the exception that of course you will not get a reliable backtrace, as always when usage of
backchainis inconsistent across the whole program.)fneddy commentedon Jun 24, 2026
Another thing:
backchainis used in the userspace (Ubuntu compiles everything withbackchainenabled).I dont know, and cannot find, if there is any use of
packed-stackin userspace enabled by any package or distribution.fneddy commentedon Jun 29, 2026
@uweigand and I had a talk and we prefer to go forward and stabilize
backchainandpacked-stack. Forbackchainwe know that there are people who want to use that. And forpacked-stackwe also want to make it available in stable.The
-Zllvm-target-featureoption might be a good intermediate option for the Kernel folks. But our main goal is to get this two options stable.I will start a stabilization PR first for
backchainand later forpacked-stack.RalfJung commentedon Jun 29, 2026
backchainis represented as a target feature,packed-stackis a dedicated compiler flag. Is there a specific reason for that difference?uweigand commentedon Jun 29, 2026
Right now, the LLVM back-end does not actually have a
packed-stacktarget feature. Thinking about this more, this seems to be more of an historical accident. Initially, neitherpacked-stacknorbackchainwere supported as target features. Rather, both features could only be triggered via LLVM IR function attributes. The-mbackchainand-mpacked-stackcommand line arguments to Clang set the corresponding function attribute on all functions of the current compilation unit.The target feature for
backchainwas introduced much later here: llvm/llvm-project#71668, with the argument that this is needed to enable the__attribute__((target("backchain")))syntax for GCC compatibility. The same was never done forpacked-stack- even though the same argument could have been made; GCC does suport__attribute__((target("packed-stack")))as well. I guess the difference is that there is some code out there using the former but not the latter.Nevertheless, if it would make Rust integration easier, I guess we could just add a
packed-stacktarget feature to LLVM with the same reasoning. This would implicitly add a dependency on a (future) LLVM version to Rust, though.RalfJung commentedon Jun 29, 2026
I'd like us to first and foremost think about the UI we want to expose from the Rust side. We can have something be a target feature in Rust without it being a target feature in LLVM. (Though that is a bit of a pain. We should probably make it easier to implement that rather than adding ad-hoc hacks each time we need this.)
I am not sure about what the trade-offs are between making something a target feature vs. a
-Cflag. Some differences that come to mind:-Cflag makes it seem much more "built-in" to the compiler. Every such flag is a dedicated field in the rust compiler session, target specs (if applicable), and so on.#[target_feature]), and can be queried via cfg (cfg!(target_feature)).I don't know how to use those differences to decide what makes most sense for any particular flag, but I noticed you talking about
backchainandpacked-stackas very similar kinds of things so it would seem odd that we make a different decision for the two of them.@rust-lang/compiler if someone has thoughts on target features vs compiler flags, or if we maybe even have some useful precedent or guidelines for that, please chime in. :)
fneddy commentedon Jun 30, 2026
IMHO making
packed-stacka target-feature would feel cleaner.I don't know the overall impact of making it a target-feature in llvm. As far as I know only clang is the other frontend that has a
packed-stackoption.fneddy commentedon Jul 1, 2026
It just occurred to me that if we make
packed-stacka target-feature we automatically support it via the#[target_feature]function attribute. This means one can endup with a call-stack wherebackchainandpacked-stackis mixed. I doubt that we want to analyze each and every possible call-stack during compilation to check for this.So for me this results in the question:
Should we forbid
backchainand (if we makepacked-stacka target-feature) alsotarget-featurefrom being set by function attributes within the code?uweigand commentedon Jul 1, 2026
It's supported to mix
packed-stackandbackchainarbitrarily on a per-function basis. (Of course always under the caveat that if you want to usepacked-stackandbackchainon any single function, the compilation unit has to usesoft-float.)uweigand commentedon Jul 2, 2026
OK, I now agree the overall best solution would be to:
packed-stacka target feature, initially only in the Rust front-endpacked-stacka target feature in LLVM