Skip to content

Commit

Permalink
Auto merge of rust-lang#77885 - erikdesjardins:probeasm, r=cuviper
Browse files Browse the repository at this point in the history
Use probe-stack=inline-asm in LLVM 11+

Fixes (?) rust-lang#74405, related to rust-lang#43241

r? `@cuviper`
  • Loading branch information
bors committed Jan 16, 2021
2 parents 6c869d3 + cd25807 commit 635ccfe
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 10 deletions.
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,18 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
return;
}

// Flag our internal `__rust_probestack` function as the stack probe symbol.
// This is defined in the `compiler-builtins` crate for each architecture.
llvm::AddFunctionAttrStringValue(
llfn,
llvm::AttributePlace::Function,
const_cstr!("probe-stack"),
const_cstr!("__rust_probestack"),
if llvm_util::get_version() < (11, 0, 1) {
// Flag our internal `__rust_probestack` function as the stack probe symbol.
// This is defined in the `compiler-builtins` crate for each architecture.
const_cstr!("__rust_probestack")
} else {
// On LLVM 11+, emit inline asm for stack probes instead of a function call.
const_cstr!("inline-asm")
},
);
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub unsafe fn create_module(
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);

let mut target_data_layout = sess.target.data_layout.clone();
if llvm_util::get_major_version() < 10
if llvm_util::get_version() < (10, 0, 0)
&& (sess.target.arch == "x86" || sess.target.arch == "x86_64")
{
target_data_layout = strip_x86_address_spaces(target_data_layout);
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_codegen_llvm/src/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1811,6 +1811,7 @@ extern "C" {
pub fn LLVMRustDebugMetadataVersion() -> u32;
pub fn LLVMRustVersionMajor() -> u32;
pub fn LLVMRustVersionMinor() -> u32;
pub fn LLVMRustVersionPatch() -> u32;

pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);

Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,17 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
}

pub fn print_version() {
let (major, minor, patch) = get_version();
println!("LLVM version: {}.{}.{}", major, minor, patch);
}

pub fn get_version() -> (u32, u32, u32) {
// Can be called without initializing LLVM
unsafe {
println!("LLVM version: {}.{}", llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
(llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch())
}
}

pub fn get_major_version() -> u32 {
unsafe { llvm::LLVMRustVersionMajor() }
}

pub fn print_passes() {
// Can be called without initializing LLVM
unsafe {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,8 @@ extern "C" uint32_t LLVMRustDebugMetadataVersion() {
return DEBUG_METADATA_VERSION;
}

extern "C" uint32_t LLVMRustVersionPatch() { return LLVM_VERSION_PATCH; }

extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }

extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
Expand Down
42 changes: 42 additions & 0 deletions src/test/assembly/stack-probes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// min-llvm-version: 11.0.1
// revisions: x86_64 i686
// assembly-output: emit-asm
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[i686] compile-flags: --target i686-unknown-linux-gnu
// compile-flags: -C llvm-args=--x86-asm-syntax=intel

#![feature(no_core, lang_items)]
#![crate_type = "lib"]
#![no_core]

#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}

impl Copy for u8 {}

// Check that inline-asm stack probes are generated correctly.
// To avoid making this test fragile to slight asm changes,
// we only check that the stack pointer is decremented by a page at a time,
// instead of matching the whole probe sequence.

// CHECK-LABEL: small_stack_probe:
#[no_mangle]
pub fn small_stack_probe(x: u8, f: fn([u8; 8192])) {
// CHECK-NOT: __rust_probestack
// x86_64: sub rsp, 4096
// i686: sub esp, 4096
let a = [x; 8192];
f(a);
}

// CHECK-LABEL: big_stack_probe:
#[no_mangle]
pub fn big_stack_probe(x: u8, f: fn([u8; 65536])) {
// CHECK-NOT: __rust_probestack
// x86_64: sub rsp, 4096
// i686: sub esp, 4096
let a = [x; 65536];
f(a);
}
3 changes: 2 additions & 1 deletion src/test/codegen/stack-probes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
// ignore-emscripten
// ignore-windows
// compile-flags: -C no-prepopulate-passes
// min-llvm-version: 11.0.1

#![crate_type = "lib"]

#[no_mangle]
pub fn foo() {
// CHECK: @foo() unnamed_addr #0
// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} }
// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} }
}

0 comments on commit 635ccfe

Please sign in to comment.