mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-17 09:23:05 +00:00
Dynamically realign local variables with large alignment
This works around the lack of a way to specify the alignment of a stack slot in Cranelift. Fixes #1230 Fixes #1381
This commit is contained in:
parent
38e8be9673
commit
55380a5ffd
@ -353,6 +353,17 @@ fn main() {
|
|||||||
|
|
||||||
let f = V([0.0, 1.0]);
|
let f = V([0.0, 1.0]);
|
||||||
let _a = f.0[0];
|
let _a = f.0[0];
|
||||||
|
|
||||||
|
stack_val_align();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
fn stack_val_align() {
|
||||||
|
#[repr(align(8192))]
|
||||||
|
struct Foo(u8);
|
||||||
|
|
||||||
|
let a = Foo(0);
|
||||||
|
assert_eq!(&a as *const Foo as usize % 8192, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(all(
|
#[cfg(all(
|
||||||
|
@ -384,13 +384,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
|
pub(crate) fn create_stack_slot(&mut self, size: u32, align: u32) -> Pointer {
|
||||||
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
if align <= 16 {
|
||||||
kind: StackSlotKind::ExplicitSlot,
|
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
||||||
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
kind: StackSlotKind::ExplicitSlot,
|
||||||
// specify stack slot alignment.
|
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
|
||||||
size: (size + 15) / 16 * 16,
|
// specify stack slot alignment.
|
||||||
});
|
size: (size + 15) / 16 * 16,
|
||||||
Pointer::stack_slot(stack_slot)
|
});
|
||||||
|
Pointer::stack_slot(stack_slot)
|
||||||
|
} else {
|
||||||
|
// Alignment is too big to handle using the above hack. Dynamically realign a stack slot
|
||||||
|
// instead. This wastes some space for the realignment.
|
||||||
|
let stack_slot = self.bcx.create_sized_stack_slot(StackSlotData {
|
||||||
|
kind: StackSlotKind::ExplicitSlot,
|
||||||
|
// FIXME is this calculation to ensure there is enough space to dyanmically realign
|
||||||
|
// as well as keep a 16 byte realignment for the other stack slots correct?
|
||||||
|
size: ((size + align - 1) + 16) / 16 * 16,
|
||||||
|
});
|
||||||
|
let base_ptr = self.bcx.ins().stack_addr(self.pointer_type, stack_slot, 0);
|
||||||
|
let misalign_offset = self.bcx.ins().urem_imm(base_ptr, i64::from(align));
|
||||||
|
let realign_offset = self.bcx.ins().irsub_imm(misalign_offset, i64::from(align));
|
||||||
|
Pointer::new(self.bcx.ins().iadd(base_ptr, realign_offset))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
|
pub(crate) fn set_debug_loc(&mut self, source_info: mir::SourceInfo) {
|
||||||
|
Loading…
Reference in New Issue
Block a user