Skip to content

Commit ed9e6f2

Browse files
committed
Enable inline stack probes on X86 with LLVM 16
1 parent 1bb8d27 commit ed9e6f2

36 files changed

+87
-65
lines changed

compiler/rustc_target/src/spec/i386_apple_ios.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ pub fn target() -> Target {
1414
arch: "x86".into(),
1515
options: TargetOptions {
1616
max_atomic_width: Some(64),
17-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
18-
stack_probes: StackProbeType::Call,
17+
stack_probes: StackProbeType::X86,
1918
..base
2019
},
2120
}

compiler/rustc_target/src/spec/i686_apple_darwin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ pub fn target() -> Target {
77
base.max_atomic_width = Some(64);
88
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
99
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
10-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
11-
base.stack_probes = StackProbeType::Call;
10+
base.stack_probes = StackProbeType::X86;
1211
base.frame_pointer = FramePointer::Always;
1312

1413
// Clang automatically chooses a more specific target based on

compiler/rustc_target/src/spec/i686_linux_android.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ pub fn target() -> Target {
1111
// https://developer.android.com/ndk/guides/abis.html#x86
1212
base.cpu = "pentiumpro".into();
1313
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3".into();
14-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
15-
base.stack_probes = StackProbeType::Call;
14+
base.stack_probes = StackProbeType::X86;
1615

1716
Target {
1817
llvm_target: "i686-linux-android".into(),

compiler/rustc_target/src/spec/i686_unknown_freebsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "i686-unknown-freebsd".into(),

compiler/rustc_target/src/spec/i686_unknown_haiku.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "i686-unknown-haiku".into(),

compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ pub fn target() -> Target {
66
base.max_atomic_width = Some(64);
77
base.supported_sanitizers = SanitizerSet::ADDRESS;
88
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
9-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
10-
base.stack_probes = StackProbeType::Call;
9+
base.stack_probes = StackProbeType::X86;
1110

1211
Target {
1312
llvm_target: "i686-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
// The unwinder used by i686-unknown-linux-musl, the LLVM libunwind
1211
// implementation, apparently relies on frame pointers existing... somehow.

compiler/rustc_target/src/spec/i686_unknown_netbsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "i686-unknown-netbsdelf".into(),

compiler/rustc_target/src/spec/i686_unknown_openbsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "i686-unknown-openbsd".into(),

compiler/rustc_target/src/spec/i686_wrs_vxworks.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "pentium4".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "i686-unknown-linux-gnu".into(),

compiler/rustc_target/src/spec/linux_kernel_base.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ pub fn opts() -> TargetOptions {
66
env: "gnu".into(),
77
disable_redzone: true,
88
panic_strategy: PanicStrategy::Abort,
9-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
10-
stack_probes: StackProbeType::Call,
9+
stack_probes: StackProbeType::X86,
1110
frame_pointer: FramePointer::Always,
1211
position_independent_executables: true,
1312
needs_plt: true,

compiler/rustc_target/src/spec/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,10 @@ pub enum StackProbeType {
635635
}
636636

637637
impl StackProbeType {
638+
// LLVM X86 targets (ix86 and x86_64) can use inline-asm stack probes starting with LLVM 16.
639+
// Notable past issues were rust#83139 (fixed in 14) and rust#84667 (fixed in 16).
640+
const X86: Self = Self::InlineOrCall { min_llvm_version_for_inline: (16, 0, 0) };
641+
638642
fn from_json(json: &Json) -> Result<Self, String> {
639643
let object = json.as_object().ok_or_else(|| "expected a JSON object")?;
640644
let kind = object

compiler/rustc_target/src/spec/x86_64_apple_darwin.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ pub fn target() -> Target {
99
base.frame_pointer = FramePointer::Always;
1010
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
1111
base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
12-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
13-
base.stack_probes = StackProbeType::Call;
12+
base.stack_probes = StackProbeType::X86;
1413
base.supported_sanitizers =
1514
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
1615

compiler/rustc_target/src/spec/x86_64_apple_ios.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ pub fn target() -> Target {
1313
arch: "x86_64".into(),
1414
options: TargetOptions {
1515
max_atomic_width: Some(64),
16-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
17-
stack_probes: StackProbeType::Call,
16+
stack_probes: StackProbeType::X86,
1817
..base
1918
},
2019
}

compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ pub fn target() -> Target {
1515
arch: "x86_64".into(),
1616
options: TargetOptions {
1717
max_atomic_width: Some(64),
18-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
19-
stack_probes: StackProbeType::Call,
18+
stack_probes: StackProbeType::X86,
2019
..base
2120
},
2221
}

compiler/rustc_target/src/spec/x86_64_apple_tvos.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ pub fn target() -> Target {
1010
arch: "x86_64".into(),
1111
options: TargetOptions {
1212
max_atomic_width: Some(64),
13-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
14-
stack_probes: StackProbeType::Call,
13+
stack_probes: StackProbeType::X86,
1514
..base
1615
},
1716
}

compiler/rustc_target/src/spec/x86_64_apple_watchos_sim.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ pub fn target() -> Target {
1515
arch: "x86_64".into(),
1616
options: TargetOptions {
1717
max_atomic_width: Some(64),
18-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
19-
stack_probes: StackProbeType::Call,
18+
stack_probes: StackProbeType::X86,
2019
forces_embed_bitcode: true,
2120
// Taken from a clang build on Xcode 11.4.1.
2221
// These arguments are not actually invoked - they just have

compiler/rustc_target/src/spec/x86_64_fuchsia.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ pub fn target() -> Target {
44
let mut base = super::fuchsia_base::opts();
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
7-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
8-
base.stack_probes = StackProbeType::Call;
7+
base.stack_probes = StackProbeType::X86;
98
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
109

1110
Target {

compiler/rustc_target/src/spec/x86_64_linux_android.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ pub fn target() -> Target {
77
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
88
base.max_atomic_width = Some(64);
99
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
10-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
11-
base.stack_probes = StackProbeType::Call;
10+
base.stack_probes = StackProbeType::X86;
1211

1312
Target {
1413
llvm_target: "x86_64-linux-android".into(),

compiler/rustc_target/src/spec/x86_64_pc_solaris.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ pub fn target() -> Target {
66
base.cpu = "x86-64".into();
77
base.vendor = "pc".into();
88
base.max_atomic_width = Some(64);
9-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
10-
base.stack_probes = StackProbeType::Call;
9+
base.stack_probes = StackProbeType::X86;
1110
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
1211

1312
Target {

compiler/rustc_target/src/spec/x86_64_sun_solaris.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ pub fn target() -> Target {
66
base.cpu = "x86-64".into();
77
base.vendor = "sun".into();
88
base.max_atomic_width = Some(64);
9-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
10-
base.stack_probes = StackProbeType::Call;
9+
base.stack_probes = StackProbeType::X86;
1110

1211
Target {
1312
llvm_target: "x86_64-pc-solaris".into(),

compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "x86_64-unknown-dragonfly".into(),

compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
base.supported_sanitizers =
1110
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD;
1211

compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
// This option is required to build executables on Haiku x86_64
1110
base.position_independent_executables = true;
1211

compiler/rustc_target/src/spec/x86_64_unknown_hermit.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.features = "+rdrnd,+rdseed".into();
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "x86_64-unknown-hermit".into(),

compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
base.static_position_independent_executables = true;
1110
base.supported_sanitizers = SanitizerSet::ADDRESS
1211
| SanitizerSet::CFI

compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ pub fn target() -> Target {
66
base.abi = "x32".into();
77
base.max_atomic_width = Some(64);
88
base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]);
9-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
10-
base.stack_probes = StackProbeType::Call;
9+
base.stack_probes = StackProbeType::X86;
1110
base.has_thread_local = false;
1211
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI
1312
// breaks code gen. See LLVM bug 36743

compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
base.static_position_independent_executables = true;
1110
base.supported_sanitizers = SanitizerSet::ADDRESS
1211
| SanitizerSet::CFI

compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
base.supported_sanitizers = SanitizerSet::ADDRESS
1110
| SanitizerSet::CFI
1211
| SanitizerSet::LEAK

compiler/rustc_target/src/spec/x86_64_unknown_none.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ pub fn target() -> Target {
1111
let opts = TargetOptions {
1212
cpu: "x86-64".into(),
1313
max_atomic_width: Some(64),
14-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
15-
stack_probes: StackProbeType::Call,
14+
stack_probes: StackProbeType::X86,
1615
position_independent_executables: true,
1716
static_position_independent_executables: true,
1817
relro_level: RelroLevel::Full,

compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "x86_64-unknown-openbsd".into(),

compiler/rustc_target/src/spec/x86_64_unknown_redox.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109

1110
Target {
1211
llvm_target: "x86_64-unknown-redox".into(),

compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ pub fn target() -> Target {
55
base.cpu = "x86-64".into();
66
base.max_atomic_width = Some(64);
77
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
8-
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
9-
base.stack_probes = StackProbeType::Call;
8+
base.stack_probes = StackProbeType::X86;
109
base.disable_redzone = true;
1110

1211
Target {

src/test/assembly/x86-stack-probes.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// min-llvm-version: 16
2+
// revisions: x86_64 i686
3+
// assembly-output: emit-asm
4+
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
5+
//[x86_64] needs-llvm-components: x86
6+
//[i686] compile-flags: --target i686-unknown-linux-gnu
7+
//[i686] needs-llvm-components: x86
8+
// compile-flags: -C llvm-args=-x86-asm-syntax=intel
9+
10+
#![feature(no_core, lang_items)]
11+
#![crate_type = "lib"]
12+
#![no_core]
13+
14+
#[lang = "sized"]
15+
trait Sized {}
16+
#[lang = "copy"]
17+
trait Copy {}
18+
19+
impl Copy for u8 {}
20+
21+
// Check that inline-asm stack probes are generated correctly.
22+
// To avoid making this test fragile to slight asm changes,
23+
// we only check that the stack pointer is decremented by a page at a time,
24+
// instead of matching the whole probe sequence.
25+
26+
// CHECK-LABEL: small_stack_probe:
27+
#[no_mangle]
28+
pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) {
29+
// CHECK-NOT: __rust_probestack
30+
// x86_64: sub rsp, 4096
31+
// i686: sub esp, 4096
32+
f(&mut [x; 8192]);
33+
}
34+
35+
// CHECK-LABEL: big_stack_probe:
36+
#[no_mangle]
37+
pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) {
38+
// CHECK-NOT: __rust_probestack
39+
// x86_64: sub rsp, 4096
40+
// i686: sub esp, 4096
41+
f(&mut [x; 65536]);
42+
}

src/test/codegen/stack-probes-call.rs

+2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
// revisions: i686 x86_64
66
//[i686] compile-flags: --target i686-unknown-linux-gnu
77
//[i686] needs-llvm-components: x86
8+
//[i686] ignore-llvm-version: 16 - 99
89
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
910
//[x86_64] needs-llvm-components: x86
11+
//[x86_64] ignore-llvm-version: 16 - 99
1012

1113
#![crate_type = "rlib"]
1214
#![feature(no_core, lang_items)]

0 commit comments

Comments
 (0)