diff --git a/compiler/rustc_codegen_llvm/src/base.rs b/compiler/rustc_codegen_llvm/src/base.rs index 893c909b204..b296db64ee9 100644 --- a/compiler/rustc_codegen_llvm/src/base.rs +++ b/compiler/rustc_codegen_llvm/src/base.rs @@ -218,3 +218,27 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility { Visibility::Protected => llvm::Visibility::Protected, } } + +pub fn linkage_from_llvm(linkage: llvm::Linkage) -> Linkage { + match linkage { + llvm::Linkage::ExternalLinkage => Linkage::External, + llvm::Linkage::AvailableExternallyLinkage => Linkage::AvailableExternally, + llvm::Linkage::LinkOnceAnyLinkage => Linkage::LinkOnceAny, + llvm::Linkage::LinkOnceODRLinkage => Linkage::LinkOnceODR, + llvm::Linkage::WeakAnyLinkage => Linkage::WeakAny, + llvm::Linkage::WeakODRLinkage => Linkage::WeakODR, + llvm::Linkage::AppendingLinkage => Linkage::Appending, + llvm::Linkage::InternalLinkage => Linkage::Internal, + llvm::Linkage::PrivateLinkage => Linkage::Private, + llvm::Linkage::ExternalWeakLinkage => Linkage::ExternalWeak, + llvm::Linkage::CommonLinkage => Linkage::Common, + } +} + +pub fn visibility_from_llvm(linkage: llvm::Visibility) -> Visibility { + match linkage { + llvm::Visibility::Default => Visibility::Default, + llvm::Visibility::Hidden => Visibility::Hidden, + llvm::Visibility::Protected => Visibility::Protected, + } +} diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 99046839973..245842df1b0 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -17,6 +17,7 @@ use rustc_middle::ty::{self, Instance, Ty}; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{AddressSpace, Align, HasDataLayout, LayoutOf, Primitive, Scalar, Size}; +use rustc_target::spec::RelocModel; use tracing::debug; pub fn const_alloc_to_llvm(cx: &CodegenCx<'ll, '_>, alloc: &Allocation) -> &'ll Value { @@ -282,6 +283,12 @@ impl CodegenCx<'ll, 'tcx> { } } + if self.tcx.sess.relocation_model() == RelocModel::Static { + unsafe { + llvm::LLVMRustSetDSOLocal(g, true); + } + } + self.instances.borrow_mut().insert(instance, g); g } @@ -363,6 +370,12 @@ fn codegen_static(&self, def_id: DefId, is_mutable: bool) { set_global_alignment(&self, g, self.align_of(ty)); llvm::LLVMSetInitializer(g, v); + let linkage = base::linkage_from_llvm(llvm::LLVMRustGetLinkage(g)); + let visibility = base::visibility_from_llvm(llvm::LLVMRustGetVisibility(g)); + if self.should_assume_dso_local(linkage, visibility) { + llvm::LLVMRustSetDSOLocal(g, true); + } + // As an optimization, all shared statics which do not have interior // mutability are placed into read-only memory. if !is_mutable && self.type_is_freeze(ty) { diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index bf66040a7eb..966be4a53fd 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -54,7 +54,7 @@ pub enum CallConv { } /// LLVMRustLinkage -#[derive(PartialEq)] +#[derive(Copy, Clone, PartialEq)] #[repr(C)] pub enum Linkage { ExternalLinkage = 0, @@ -72,6 +72,7 @@ pub enum Linkage { // LLVMRustVisibility #[repr(C)] +#[derive(Copy, Clone)] pub enum Visibility { Default = 0, Hidden = 1, diff --git a/src/test/assembly/static-relocation-model.rs b/src/test/assembly/static-relocation-model.rs index 0463045c156..ce2b3b1cfa4 100644 --- a/src/test/assembly/static-relocation-model.rs +++ b/src/test/assembly/static-relocation-model.rs @@ -1,8 +1,8 @@ // min-llvm-version: 12.0.0 // needs-llvm-components: aarch64 x86 -// revisions:X64 A64 +// revisions:x64 A64 // assembly-output: emit-asm -// [X64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static +// [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static // [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static #![feature(no_core, lang_items)] @@ -15,14 +15,26 @@ trait Sized {} #[lang="copy"] trait Copy {} +#[lang="sync"] +trait Sync {} + +#[lang = "drop_in_place"] +fn drop_in_place(_: *mut T) {} + impl Copy for u8 {} +impl Sync for u8 {} + +#[no_mangle] +pub static PIERIS: u8 = 42; extern "C" { + static EXOCHORDA: *mut u8; + fn chaenomeles(); } // CHECK-LABEL: banana: -// x64: movb chaenomeles, %{{[a,z]+}} +// x64: movb chaenomeles{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}} // A64: adrp [[REG:[a-z0-9]+]], chaenomeles // A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles] #[no_mangle] @@ -33,7 +45,7 @@ pub fn banana() -> u8 { } // CHECK-LABEL: peach: -// x64: movb banana, %{{[a,z]+}} +// x64: movb banana{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}} // A64: adrp [[REG2:[a-z0-9]+]], banana // A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana] #[no_mangle] @@ -42,3 +54,24 @@ pub fn peach() -> u8 { *(banana as *mut u8) } } + +// CHECK-LABEL: mango: +// x64: movq EXOCHORDA{{(\(%[a-z0-9]+\))?}}, %[[REG:[a-z0-9]+]] +// x64-NEXT: movb (%[[REG]]), %{{[a-z0-9]+}} +// A64: adrp [[REG2:[a-z0-9]+]], EXOCHORDA +// A64-NEXT: ldr {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:EXOCHORDA] +#[no_mangle] +pub fn mango() -> u8 { + unsafe { + *EXOCHORDA + } +} + +// CHECK-LABEL: orange: +// x64: mov{{l|absq}} $PIERIS, %{{[a-z0-9]+}} +// A64: adrp [[REG2:[a-z0-9]+]], PIERIS +// A64-NEXT: add {{[a-z0-9]+}}, [[REG2]], :lo12:PIERIS +#[no_mangle] +pub fn orange() -> &'static u8 { + &PIERIS +}