Auto merge of #77885 - erikdesjardins:probeasm, r=cuviper
Use probe-stack=inline-asm in LLVM 11+ Fixes (?) #74405, related to #43241 r? `@cuviper`
This commit is contained in:
commit
635ccfe01c
@ -127,13 +127,18 @@ fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
|||||||
return;
|
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(
|
llvm::AddFunctionAttrStringValue(
|
||||||
llfn,
|
llfn,
|
||||||
llvm::AttributePlace::Function,
|
llvm::AttributePlace::Function,
|
||||||
const_cstr!("probe-stack"),
|
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")
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ pub unsafe fn create_module(
|
|||||||
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
|
||||||
|
|
||||||
let mut target_data_layout = sess.target.data_layout.clone();
|
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")
|
&& (sess.target.arch == "x86" || sess.target.arch == "x86_64")
|
||||||
{
|
{
|
||||||
target_data_layout = strip_x86_address_spaces(target_data_layout);
|
target_data_layout = strip_x86_address_spaces(target_data_layout);
|
||||||
|
@ -1811,6 +1811,7 @@ extern "C" {
|
|||||||
pub fn LLVMRustDebugMetadataVersion() -> u32;
|
pub fn LLVMRustDebugMetadataVersion() -> u32;
|
||||||
pub fn LLVMRustVersionMajor() -> u32;
|
pub fn LLVMRustVersionMajor() -> u32;
|
||||||
pub fn LLVMRustVersionMinor() -> u32;
|
pub fn LLVMRustVersionMinor() -> u32;
|
||||||
|
pub fn LLVMRustVersionPatch() -> u32;
|
||||||
|
|
||||||
pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
|
pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);
|
||||||
|
|
||||||
|
@ -171,14 +171,15 @@ pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_version() {
|
pub fn print_version() {
|
||||||
// Can be called without initializing LLVM
|
let (major, minor, patch) = get_version();
|
||||||
unsafe {
|
println!("LLVM version: {}.{}.{}", major, minor, patch);
|
||||||
println!("LLVM version: {}.{}", llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_major_version() -> u32 {
|
pub fn get_version() -> (u32, u32, u32) {
|
||||||
unsafe { llvm::LLVMRustVersionMajor() }
|
// Can be called without initializing LLVM
|
||||||
|
unsafe {
|
||||||
|
(llvm::LLVMRustVersionMajor(), llvm::LLVMRustVersionMinor(), llvm::LLVMRustVersionPatch())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_passes() {
|
pub fn print_passes() {
|
||||||
|
@ -660,6 +660,8 @@ extern "C" uint32_t LLVMRustDebugMetadataVersion() {
|
|||||||
return DEBUG_METADATA_VERSION;
|
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 LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }
|
||||||
|
|
||||||
extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
|
extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }
|
||||||
|
42
src/test/assembly/stack-probes.rs
Normal file
42
src/test/assembly/stack-probes.rs
Normal file
@ -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);
|
||||||
|
}
|
@ -13,11 +13,12 @@
|
|||||||
// ignore-emscripten
|
// ignore-emscripten
|
||||||
// ignore-windows
|
// ignore-windows
|
||||||
// compile-flags: -C no-prepopulate-passes
|
// compile-flags: -C no-prepopulate-passes
|
||||||
|
// min-llvm-version: 11.0.1
|
||||||
|
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn foo() {
|
pub fn foo() {
|
||||||
// CHECK: @foo() unnamed_addr #0
|
// CHECK: @foo() unnamed_addr #0
|
||||||
// CHECK: attributes #0 = { {{.*}}"probe-stack"="__rust_probestack"{{.*}} }
|
// CHECK: attributes #0 = { {{.*}}"probe-stack"="inline-asm"{{.*}} }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user