Auto merge of #105812 - ojeda:no-jump-tables, r=nikic

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
This commit is contained in:
bors 2022-12-21 17:38:38 +00:00
commit a8207df49e
6 changed files with 69 additions and 0 deletions

View File

@ -137,6 +137,14 @@ fn instrument_function_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribu
}
}
fn nojumptables_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
if !cx.sess().opts.unstable_opts.no_jump_tables {
return None;
}
Some(llvm::CreateAttrStringValue(cx.llcx, "no-jump-tables", "true"))
}
fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
// Currently stack probes seem somewhat incompatible with the address
// sanitizer and thread sanitizer. With asan we're already protected from
@ -293,6 +301,7 @@ pub fn from_fn_attrs<'ll, 'tcx>(
// FIXME: none of these three functions interact with source level attributes.
to_add.extend(frame_pointer_type_attr(cx));
to_add.extend(instrument_function_attr(cx));
to_add.extend(nojumptables_attr(cx));
to_add.extend(probestack_attr(cx));
to_add.extend(stackprotector_attr(cx));

View File

@ -754,6 +754,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(move_size_limit, Some(4096));
tracked!(mutable_noalias, Some(true));
tracked!(no_generate_arange_section, true);
tracked!(no_jump_tables, true);
tracked!(no_link, true);
tracked!(no_profiler_runtime, true);
tracked!(no_unique_section_names, true);

View File

@ -1421,6 +1421,8 @@ options! {
"run all passes except codegen; no output"),
no_generate_arange_section: bool = (false, parse_no_flag, [TRACKED],
"omit DWARF address ranges that give faster lookups"),
no_jump_tables: bool = (false, parse_no_flag, [TRACKED],
"disable the jump tables and lookup tables that can be generated from a switch case lowering"),
no_leak_check: bool = (false, parse_no_flag, [UNTRACKED],
"disable the 'leak check' for subtyping; unsound, but useful for tests"),
no_link: bool = (false, parse_no_flag, [TRACKED],

View File

@ -0,0 +1,34 @@
// Test that jump tables are (not) emitted when the `-Zno-jump-tables`
// flag is (not) set.
// revisions: unset set
// assembly-output: emit-asm
// compile-flags: -O
// [set] compile-flags: -Zno-jump-tables
// only-x86_64
#![crate_type = "lib"]
extern "C" {
fn bar1();
fn bar2();
fn bar3();
fn bar4();
fn bar5();
fn bar6();
}
// CHECK-LABEL: foo:
#[no_mangle]
pub unsafe fn foo(x: i32) {
// unset: LJTI0_0
// set-NOT: LJTI0_0
match x {
1 => bar1(),
2 => bar2(),
3 => bar3(),
4 => bar4(),
5 => bar5(),
_ => bar6(),
}
}

View File

@ -0,0 +1,22 @@
// Test that the `no-jump-tables` function attribute are (not) emitted when
// the `-Zno-jump-tables` flag is (not) set.
// revisions: unset set
// needs-llvm-components: x86
// compile-flags: --target x86_64-unknown-linux-gnu
// [set] compile-flags: -Zno-jump-tables
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[no_mangle]
pub fn foo() {
// CHECK: @foo() unnamed_addr #0
// unset-NOT: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
// set: attributes #0 = { {{.*}}"no-jump-tables"="true"{{.*}} }
}

View File

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