Skip to content

Commit 95a5a0e

Browse files
committed
Add TargetOptions::min_global_align, with s390x at 16-bit
The SystemZ `LALR` instruction provides PC-relative addressing for globals, but only to *even* addresses, so other compilers make sure that such globals are always 2-byte aligned. In Clang, this is modeled with `TargetInfo::MinGlobalAlign`, and `TargetOptions::min_global_align` now serves the same purpose for rustc. In Clang, the only targets that set this are SystemZ, Lanai, and NVPTX, and the latter two don't have targets in rust master.
1 parent dead08c commit 95a5a0e

File tree

3 files changed

+29
-2
lines changed

3 files changed

+29
-2
lines changed

src/librustc_back/target/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ pub struct TargetOptions {
425425

426426
/// Whether or not stack probes (__rust_probestack) are enabled
427427
pub stack_probes: bool,
428+
429+
/// The minimum alignment for global symbols.
430+
pub min_global_align: Option<u64>,
428431
}
429432

430433
impl Default for TargetOptions {
@@ -486,6 +489,7 @@ impl Default for TargetOptions {
486489
crt_static_default: false,
487490
crt_static_respected: false,
488491
stack_probes: false,
492+
min_global_align: None,
489493
}
490494
}
491495
}
@@ -724,6 +728,7 @@ impl Target {
724728
key!(crt_static_default, bool);
725729
key!(crt_static_respected, bool);
726730
key!(stack_probes, bool);
731+
key!(min_global_align, Option<u64>);
727732

728733
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
729734
for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -914,6 +919,7 @@ impl ToJson for Target {
914919
target_option_val!(crt_static_default);
915920
target_option_val!(crt_static_respected);
916921
target_option_val!(stack_probes);
922+
target_option_val!(min_global_align);
917923

918924
if default.abi_blacklist != self.options.abi_blacklist {
919925
d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()

src/librustc_back/target/s390x_unknown_linux_gnu.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub fn target() -> TargetResult {
2222
base.max_atomic_width = Some(64);
2323
// see #36994
2424
base.exe_allocation_crate = None;
25+
base.min_global_align = Some(16);
2526

2627
Ok(Target {
2728
llvm_target: "s390x-unknown-linux-gnu".to_string(),

src/librustc_trans/consts.rs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use rustc::ty;
2626

2727
use rustc::hir;
2828

29+
use std::cmp;
2930
use std::ffi::{CStr, CString};
3031
use syntax::ast;
3132
use syntax::attr;
@@ -42,6 +43,25 @@ pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef {
4243
}
4344
}
4445

46+
fn set_global_alignment(ccx: &CrateContext,
47+
gv: ValueRef,
48+
mut align: machine::llalign) {
49+
// The target may require greater alignment for globals than the type does.
50+
// Note: GCC and Clang also allow `__attribute__((aligned))` on variables,
51+
// which can force it to be smaller. Rust doesn't support this yet.
52+
if let Some(min) = ccx.sess().target.target.options.min_global_align {
53+
match ty::layout::Align::from_bits(min, min) {
54+
Ok(min) => align = cmp::max(align, min.abi() as machine::llalign),
55+
Err(err) => {
56+
ccx.sess().err(&format!("invalid minimum global alignment: {}", err));
57+
}
58+
}
59+
}
60+
unsafe {
61+
llvm::LLVMSetAlignment(gv, align);
62+
}
63+
}
64+
4565
pub fn addr_of_mut(ccx: &CrateContext,
4666
cv: ValueRef,
4767
align: machine::llalign,
@@ -53,7 +73,7 @@ pub fn addr_of_mut(ccx: &CrateContext,
5373
bug!("symbol `{}` is already defined", name);
5474
});
5575
llvm::LLVMSetInitializer(gv, cv);
56-
llvm::LLVMSetAlignment(gv, align);
76+
set_global_alignment(ccx, gv, align);
5777
llvm::LLVMRustSetLinkage(gv, llvm::Linkage::InternalLinkage);
5878
SetUnnamedAddr(gv, true);
5979
gv
@@ -276,7 +296,7 @@ pub fn trans_static<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
276296
ccx.statics_to_rauw().borrow_mut().push((g, new_g));
277297
new_g
278298
};
279-
llvm::LLVMSetAlignment(g, ccx.align_of(ty));
299+
set_global_alignment(ccx, g, ccx.align_of(ty));
280300
llvm::LLVMSetInitializer(g, v);
281301

282302
// As an optimization, all shared statics which do not have interior

0 commit comments

Comments
 (0)