mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Rollup merge of #155622 - folkertdev:va-arg-llvm-fixes, r=tgross35
c-variadic: `va_arg` fixes tracking issue: https://github.com/rust-lang/rust/issues/44930 extracts some generic LLVM `va_arg` fixes from https://github.com/rust-lang/rust/pull/152576 and https://github.com/rust-lang/rust/pull/155429. r? tgross35
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
use rustc_target::spec::{Arch, Env, LlvmAbi, RustcAbi};
|
||||
|
||||
use crate::builder::Builder;
|
||||
use crate::llvm::{Type, Value};
|
||||
use crate::llvm::Value;
|
||||
use crate::type_of::LayoutLlvmExt;
|
||||
|
||||
fn round_up_to_alignment<'ll>(
|
||||
@@ -27,13 +27,14 @@ fn round_pointer_up_to_alignment<'ll>(
|
||||
bx: &mut Builder<'_, 'll, '_>,
|
||||
addr: &'ll Value,
|
||||
align: Align,
|
||||
ptr_ty: &'ll Type,
|
||||
) -> &'ll Value {
|
||||
let ptr = bx.inbounds_ptradd(addr, bx.const_i32(align.bytes() as i32 - 1));
|
||||
let pointer_width = bx.tcx().sess.target.pointer_width;
|
||||
let mask = align.bytes().wrapping_neg() & (u64::MAX >> (64 - pointer_width));
|
||||
bx.call_intrinsic(
|
||||
"llvm.ptrmask",
|
||||
&[ptr_ty, bx.type_i32()],
|
||||
&[ptr, bx.const_int(bx.isize_ty, -(align.bytes() as isize) as i64)],
|
||||
&[bx.type_ptr(), bx.type_isize()],
|
||||
&[ptr, bx.const_usize(mask)],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -53,7 +54,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
|
||||
let ptr = bx.load(va_list_ty, va_list_addr, ptr_align_abi);
|
||||
|
||||
let (addr, addr_align) = if allow_higher_align && align > slot_size {
|
||||
(round_pointer_up_to_alignment(bx, ptr, align, bx.type_ptr()), align)
|
||||
(round_pointer_up_to_alignment(bx, ptr, align), align)
|
||||
} else {
|
||||
(ptr, slot_size)
|
||||
};
|
||||
@@ -69,7 +70,8 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
|
||||
{
|
||||
let adjusted_size = bx.cx().const_i32((slot_size.bytes() - size.bytes()) as i32);
|
||||
let adjusted = bx.inbounds_ptradd(addr, adjusted_size);
|
||||
(adjusted, addr_align)
|
||||
// We're in the middle of a slot now, so use the type's alignment, not the slot's.
|
||||
(adjusted, align)
|
||||
} else {
|
||||
(addr, addr_align)
|
||||
}
|
||||
@@ -357,12 +359,8 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
|
||||
|
||||
// Round up address of argument to alignment
|
||||
if layout.layout.align.abi > overflow_area_align {
|
||||
overflow_area = round_pointer_up_to_alignment(
|
||||
bx,
|
||||
overflow_area,
|
||||
layout.layout.align.abi,
|
||||
bx.type_ptr(),
|
||||
);
|
||||
overflow_area =
|
||||
round_pointer_up_to_alignment(bx, overflow_area, layout.layout.align.abi);
|
||||
}
|
||||
|
||||
let mem_addr = overflow_area;
|
||||
@@ -827,7 +825,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
|
||||
} else {
|
||||
Align::from_bytes(4).unwrap()
|
||||
};
|
||||
let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align, bx.type_ptr());
|
||||
let aligned_current = round_pointer_up_to_alignment(bx, current_ptr, arg_align);
|
||||
|
||||
// Calculate next pointer position (following LLVM's logic)
|
||||
// Arguments <= 32 bits take 4 bytes, > 32 bits take 8 bytes
|
||||
@@ -849,8 +847,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
|
||||
bx.switch_to_block(from_overflow);
|
||||
|
||||
// Align overflow pointer using the same alignment rules
|
||||
let aligned_overflow =
|
||||
round_pointer_up_to_alignment(bx, overflow_ptr, arg_align, bx.type_ptr());
|
||||
let aligned_overflow = round_pointer_up_to_alignment(bx, overflow_ptr, arg_align);
|
||||
|
||||
let overflow_value_addr = aligned_overflow;
|
||||
// Update overflow pointer - use the same size calculation
|
||||
@@ -890,7 +887,7 @@ fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>(
|
||||
let aligned_ptr = if ty_align.bytes() > 4 {
|
||||
// Ensure alignment is a power of 2
|
||||
debug_assert!(ty_align.bytes().is_power_of_two(), "Alignment is not power of 2!");
|
||||
round_pointer_up_to_alignment(bx, current_ptr, ty_align, bx.type_ptr())
|
||||
round_pointer_up_to_alignment(bx, current_ptr, ty_align)
|
||||
} else {
|
||||
current_ptr
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user