Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a65ec44

Browse files
committedDec 20, 2022
Add -Zno-jump-tables
This flag mimics GCC/Clang's `-fno-jump-tables` [1][2], which makes the codegen backend avoid generating jump tables when lowering switches. In the case of LLVM, the `"no-jump-tables"="true"` function attribute is added to every function. The kernel currently needs it for x86 when enabling IBT [3], as well as for Alpha (plus VDSO objects in MIPS/LoongArch). [1] https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fno-jump-tables [2] https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fjump-tables [3] https://github.com/torvalds/linux/blob/v6.1/arch/x86/Makefile#L75-L83 Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 9c07efe commit a65ec44

File tree

6 files changed

+69
-0
lines changed

6 files changed

+69
-0
lines changed
 

‎compiler/rustc_codegen_llvm/src/attributes.rs

+9
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,14 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu
137137
}
138138
}
139139

140+
fn nojumptables_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
141+
if !cx.sess().opts.unstable_opts.no_jump_tables {
142+
return None;
143+
}
144+
145+
Some(llvm::CreateAttrStringValue(cx.llcx, "no-jump-tables", "true"))
146+
}
147+
140148
fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
141149
// Currently stack probes seem somewhat incompatible with the address
142150
// sanitizer and thread sanitizer. With asan we're already protected from
@@ -293,6 +301,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
293301
// FIXME: none of these three functions interact with source level attributes.
294302
to_add.extend(frame_pointer_type_attr(cx));
295303
to_add.extend(instrument_function_attr(cx));
304+
to_add.extend(nojumptables_attr(cx));
296305
to_add.extend(probestack_attr(cx));
297306
to_add.extend(stackprotector_attr(cx));
298307

‎compiler/rustc_interface/src/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ fn test_unstable_options_tracking_hash() {
754754
tracked!(move_size_limit, Some(4096));
755755
tracked!(mutable_noalias, Some(true));
756756
tracked!(no_generate_arange_section, true);
757+
tracked!(no_jump_tables, true);
757758
tracked!(no_link, true);
758759
tracked!(no_profiler_runtime, true);
759760
tracked!(no_unique_section_names, true);

‎compiler/rustc_session/src/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ options! {
14211421
"run all passes except codegen; no output"),
14221422
no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
14231423
"omit DWARF address ranges that give faster lookups"),
1424+
no_jump_tables: bool = (false, parse_no_flag, [TRACKED],
1425+
"disable the jump tables and lookup tables that can be generated from a switch case lowering"),
14241426
no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
14251427
"disable the 'leak check' for subtyping; unsound, but useful for tests"),
14261428
no_link: bool = (false, parse_no_flag, [TRACKED],
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Test that jump tables are (not) emitted when the `-Zno-jump-tables`
2+
// flag is (not) set.
3+
4+
// revisions: unset set
5+
// assembly-output: emit-asm
6+
// compile-flags: -O
7+
// [set] compile-flags: -Zno-jump-tables
8+
// only-x86_64
9+
10+
#![crate_type = "lib"]
11+
12+
extern "C" {
13+
fn bar1();
14+
fn bar2();
15+
fn bar3();
16+
fn bar4();
17+
fn bar5();
18+
fn bar6();
19+
}
20+
21+
// CHECK-LABEL: foo:
22+
#[no_mangle]
23+
pub unsafe fn foo(x: i32) {
24+
// unset: LJTI0_0
25+
// set-NOT: LJTI0_0
26+
match x {
27+
1 => bar1(),
28+
2 => bar2(),
29+
3 => bar3(),
30+
4 => bar4(),
31+
5 => bar5(),
32+
_ => bar6(),
33+
}
34+
}

‎src/test/codegen/no-jump-tables.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Test that the `no-jump-tables` function attribute are (not) emitted when
2+
// the `-Zno-jump-tables` flag is (not) set.
3+
4+
// revisions: unset set
5+
// needs-llvm-components: x86
6+
// compile-flags: --target x86_64-unknown-linux-gnu
7+
// [set] compile-flags: -Zno-jump-tables
8+
9+
#![crate_type = "lib"]
10+
#![feature(no_core, lang_items)]
11+
#![no_core]
12+
13+
#[lang = "sized"]
14+
trait Sized {}
15+
16+
#[no_mangle]
17+
pub fn foo() {
18+
// CHECK: @foo() unnamed_addr #0
19+
20+
// unset-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
21+
// set: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
22+
}

‎src/test/rustdoc-ui/z-help.stdout

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
-Z no-analysis=val -- parse and expand the source, but run no analysis
9393
-Z no-codegen=val -- run all passes except codegen; no output
9494
-Z no-generate-arange-section=val -- omit DWARF address ranges that give faster lookups
95+
-Z no-jump-tables=val -- disable the jump tables and lookup tables that can be generated from a switch case lowering
9596
-Z no-leak-check=val -- disable the 'leak check' for subtyping; unsound, but useful for tests
9697
-Z no-link=val -- compile without linking
9798
-Z no-parallel-llvm=val -- run LLVM in non-parallel mode (while keeping codegen-units and ThinLTO)

0 commit comments

Comments
 (0)
Failed to load comments.