Skip to content

Conversation

pmur
Copy link
Contributor

@pmur pmur commented Aug 28, 2025

I propose stabilizing the -Zno-jump-tables option into -Cjump-tables=.

-Zno-jump-tables stabilization report

What is the RFC for this feature and what changes have occurred to the user-facing design since the RFC was finalized?

No RFC was created for this option. This was a narrowly scoped option introduced in #105812 to support code generation requirements of the x86-64 linux kernel, and eventually other targets as Rust For Linux grows.

The tracking is #116592.

What behavior are we committing to that has been controversial? Summarize the major arguments pro/con.

The behavior of this flag is well defined, and mimics the existing -fno-jump-tables option currently available with LLVM and GCC.

  • What should the flag name be?
    As introduced, this option was named -Zno-jump-tables. However, other major toolchains allow both positive and negative variants of this option to toggle this feature. Renaming the option to -Cjump-tables=<bool> makes this option consistent, and if for some reason, expandable to other arguments in the future. Notably, many LLVM targets have a configurable and different thresholds for when to lower into a jump table.

Are there extensions to this feature that remain unstable? How do we know that we are not accidentally committing to those.

No. This option is used exclusively to gate a very specific class of optimization.

Summarize the major parts of the implementation and provide links into the code (or to PRs)

Has a call-for-testing period been conducted? If so, what feedback was received?

No. The option has originally created is being used by Rust For Linux to build the x86-64 kernel without issue.

What outstanding bugs in the issue tracker involve this feature? Are they stabilization-blocking?

There are no outstanding issues.

Summarize contributors to the feature by name for recognition and assuredness that people involved in the feature agree with stabilization

What FIXMEs are still in the code for that feature and why is it ok to leave them there?

There are none.

What static checks are done that are needed to prevent undefined behavior?

This option cannot cause undefined behavior. It is a boolean option with well defined behavior in both cases.

In what way does this feature interact with the reference/specification, and are those edits prepared?

This adds a new cli option to rustc. The documentation is updated, and the unstable documentation cleaned up in this PR.

Does this feature introduce new expressions and can they produce temporaries? What are the lifetimes of those temporaries?

No.

What other unstable features may be exposed by this feature?

None.

What is tooling support like for this feature, w.r.t rustdoc, clippy, rust-analzyer, rustfmt, etc.?

No support is required from other rust tooling.

Open Items

  • Are there objections renaming -Zno-jump-tables to -Cjump-tables=<bool>?
  • Is it desirable to keep -Zno-jump-tables for a period of time?

Closes #116592

Both gcc and llvm accept -fjump-tables as well as -fno-jump-tables. For
consistency, allow rustc to accept -Zjump-tables=yes too.
@rustbot
Copy link
Collaborator

rustbot commented Aug 28, 2025

r? @lcnr

rustbot has assigned @lcnr.
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

@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 Aug 28, 2025
Copy link
Member

Choose a reason for hiding this comment

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

Question [GUARANTEE 1/3]: is this intended to be a hint, or a guarantee?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is guarantee for the crate being compiled. No attempts are made to verify the entire link unit is compiled with this flag.

I think that is OK. It may be desirable for some crates to control this option. A jump table isn't always a more performant optimization (such was my experience when experimenting with them on Go/PPC64).

Copy link
Contributor

@tgross35 tgross35 Aug 29, 2025

Choose a reason for hiding this comment

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

Maybe it's worth mentioning in the docs that:

  • This can be enabled for a single crate if you are interested in controlling this for performance reasons
  • If you are going after IBT concerns, it probably needs to be enabled for all crates in the graph
  • Pre-built std may not meet your requirements

(Great questions btw Jieyou)

Copy link
Member

@jieyouxu jieyouxu Aug 30, 2025

Choose a reason for hiding this comment

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

Yeah, this is why I asked, because depending on what you are aiming for, perf-only versus security concerns might want different levels of guarantees (or don't need guarantees).

Copy link
Member

Choose a reason for hiding this comment

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

Question:

This option enables the -fno-jump-tables flag for LLVM, which makes the codegen backend avoid generating jump tables when lowering switches.

This option adds the LLVM no-jump-tables=true attribute to every function.

The option can be used to help provide protection against jump-oriented-programming (JOP) attacks, such as with the linux kernel's IBT.

How does this interact with pre-compiled std? I.e. can you mix downstream user crates compiled with -Cjump-tables=no versus a pre-compiled std compiled and distributed with -Cjump-tables=yes?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should link without issue. Disabling this codegen optimization should have no effect on ABI.

Comment on lines 220 to 221
Disabling jump tables can be used to help provide protection against
jump-oriented-programming (JOP) attacks, such as with the linux kernel's [IBT].
Copy link
Member

Choose a reason for hiding this comment

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

Discussion [GUARANTEE 3/3]: If the flag is intended to be a hint, then this sentence can be a bit misleading, because we may not always guarantee it. We may want to slightly caveat this wording to not convey a "false promise" so to speak.

Or, if a user do want such protection, then do they need to enforce it over the whole crate graph?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The flag should be guarantee anything compiled with jump tables turned off does not contain jump tables. It would be up to the user to enforce this dependency beyond the individual crate.

I think it might be better to remove this statement entirely. Maybe it would be better rewriten as:

Disabling jump tables can be used to help provide protection against
jump-oriented-programming (JOP) attacks. However, this option makes
no guarantee any precompiled or external dependencies are compiled 
with or without jump tables.

Comment on lines 214 to 215
This option is used to allow or prevent the codegen backend from creating
jump tables when lowering switches.
Copy link
Member

Choose a reason for hiding this comment

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

Discussion: Hm, what happens if a different cg backend is selected?

cc @GuillaumeGomez @antoyo

Copy link
Contributor

Choose a reason for hiding this comment

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

It is not implemented yet in cg_gcc, but I guess it could be by sending -fno-jump-tables with context.add_driver_option("-fno-jump-tables") or context.add_command_line_option("-fno-jump-tables").

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should this be implemented for the other backends before stabilizing?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we need to block on it, though it may be worth a note. For GCC it should be a simple check here

, I think it should be fine to add a commit doing that to this PR if you're up for it.

(assuming Antoni is okay with doing it here rather than the submodule repo to avoid dancing also dancing around the name change).

Cc @bjorn3 for cranelift

Copy link
Member

Choose a reason for hiding this comment

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

Cranelift doesn't have support emission of jump tables for the br_table instruction. Avoiding emitting br_table itself may be feasible, but would require a cranelift-frontend change. FWIW cg_clif silently ignores many of these flags already.

Copy link
Contributor

Choose a reason for hiding this comment

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

(assuming Antoni is okay with doing it here rather than the submodule repo to avoid dancing also dancing around the name change).

I'm OK with this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Adding support to the gcc backend seems straightforward. What is the difference between using add_driver_option vs add_command_line_option? The former did inhibit jump tables when I tested it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Some options won't work if not using the correct function. If it works, all is good.

Comment on lines 214 to 215
This option is used to allow or prevent the codegen backend from creating
jump tables when lowering switches.
Copy link
Member

Choose a reason for hiding this comment

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

Question [GUARANTEE 2/3]: This wording reads like a guarantee -- but is it? Can we make that guarantee?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It should, though that is entirely dependent on the codegen backend to honor it.

More accurately, this should be reworded as the LLVM codegen backend. However, it seems relatively trivial to pass this through to the gcc backend too.

Copy link
Member

Choose a reason for hiding this comment

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

Question: I'm assuming that if you inspect the assembly of an actual hello world binary that uses std in some way, then you might see jump stables still? 🤔

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, if they exist and are included when linking. That is expected, though unintuitive to someone unfamiliar with the rust build system.

Copy link
Member

Choose a reason for hiding this comment

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

Are there objections renaming -Zno-jump-tables to -Zjump-tables=?

Not having double-negatives is very nice 👍

Is it desirable to keep -Zno-jump-tables for a period of time?

No, I rather not have to keep around an unstable flag as an alias to a stable flag, that's very weird.

Copy link
Contributor

Choose a reason for hiding this comment

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

Not having double-negatives is very nice 👍

The current flag (i.e. the GCC/Clang naming) has no double negatives, i.e. it does not take a parameter. If it did, then yeah, it wouldn't be great.

Copy link
Contributor

@tgross35 tgross35 Aug 29, 2025

Choose a reason for hiding this comment

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

It's not a single-option flag for the C compilers: -fjump-tables is a legal option (and the default), -fno-jump-tables is just its inverted value. As-is, if we wanted to pass the positive option to rustc it would mean something like -Cno-jump-tables=false which has the double negative.

Unfortunately we do have a few flags that didn't remove the C-style no- prefix, e.g. -Cno-redzone=false, but I don't think we should follow that precedent. (Honestly we should probably consider deprecating that one in favor of a new -Credzone=....)

Copy link
Contributor

Choose a reason for hiding this comment

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

@tgross35 Not sure if you are replying to @jieyouxu or me. If you are replying to me, then I am confused, because that is what I was saying.

Copy link
Contributor

Choose a reason for hiding this comment

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

It was in response to your comment about the CC flag: I'm saying that there is no double negative in that case specifically because -fno-jump-tables is already inverted (from -fjump-tables), not necessarily because it doesn't take any options.

I think we're in agreement, I'm just making a point that we aren't actually consistent with the C compilers currently because our base flag is "no-jump-tables" while theirs is "jump-tables" (and we don't treat no- as a prefix to flip boolean flags).

Copy link
Member

Choose a reason for hiding this comment

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

(Yeah for better or worse, the rustc flags sometimes accept too many different forms of "on"/"off" that make it confusing...)

Copy link
Contributor

@ojeda ojeda Aug 30, 2025

Choose a reason for hiding this comment

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

It was in response to your comment about the CC flag

My comment (and @jieyouxu's, given the quote) was referring to the current Rust flag, not the C one. In any case, I think you are talking from an implementation point of view, but I think the user interface is what matters: -fx existing or not does not change anything regarding double negatives on e.g. -fno-x and whether compilers auto-implement negatives or not (and what is the "base option" etc.) is orthogonal.

So what I was trying to say with my original comment is that there is no double negative with the current Rust interface, because the OP comment sounded ambiguous to me, i.e. there is no double negative being removed w.r.t. the current state. It is only because we want the flexibility of a parameter that the issue is introduced if we kept the name.

@jieyouxu jieyouxu added the needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. label Aug 29, 2025
@ojeda
Copy link
Contributor

ojeda commented Aug 29, 2025

Thanks for this!

and eventually other targets as Rust For Linux grows

Yeah, it may get used for other things. Apart from what I mentioned in the original PR, I see LoongArch also uses it since a year ago (so I assume it should be passed for Rust too there, Cc @chenhuacai in case there is a reason not to).

Are there objections renaming -Zno-jump-tables to -Zjump-tables=<bool>?

I assume you mean -C for the latter, i.e. we are going directly from -Zno-jump-tables to -Cjump-tables rather than one more step -- that is what the PR seems to do, right? Otherwise, we will need to support 3 names on the kernel side, which isn't great.

As for the name change, it seems fine -- the usual argument for using the current name is to keep it close to GCC's and Clang's flags, which always helps, but here it is obvious, i.e. we are not changing other parts of the name or grouping different flags into a new one or things like that.

Is it desirable to keep -Zno-jump-tables for a period of time?

I think it is fine either way for us.

If the old flag isn't there, we may get a kernel build error here in this PR, in which case I can give you a commit to fix it.

@pmur
Copy link
Contributor Author

pmur commented Aug 29, 2025

I assume you mean -C for the latter, i.e. we are going directly from -Zno-jump-tables to -Cjump-tables rather than one more step -- that is what the PR seems to do, right? Otherwise, we will need to support 3 names on the kernel side, which isn't great.

Yes. I've updated the report. The PR intentionally contains a commit to rename -Zno-jump-tables to -Zjump-tables=, but I think that detail is ultimately irrelevant. I don't think anyone wants to support 3 names.

@pmur pmur force-pushed the murp/stabilize-zno-jump-tables branch from 68bfda9 to 08d2690 Compare August 29, 2025 21:57
@rustbot
Copy link
Collaborator

rustbot commented Aug 29, 2025

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

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. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. 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.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking Issue for no-jump-tables
8 participants