@@ -11,7 +11,7 @@ use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
1111use rustc_target:: spec:: { Arch , Env , LlvmAbi , RustcAbi } ;
1212
1313use crate :: builder:: Builder ;
14- use crate :: llvm:: { Type , Value } ;
14+ use crate :: llvm:: Value ;
1515use crate :: type_of:: LayoutLlvmExt ;
1616
1717fn round_up_to_alignment < ' ll > (
@@ -27,13 +27,14 @@ fn round_pointer_up_to_alignment<'ll>(
2727 bx : & mut Builder < ' _ , ' ll , ' _ > ,
2828 addr : & ' ll Value ,
2929 align : Align ,
30- ptr_ty : & ' ll Type ,
3130) -> & ' ll Value {
3231 let ptr = bx. inbounds_ptradd ( addr, bx. const_i32 ( align. bytes ( ) as i32 - 1 ) ) ;
32+ let pointer_width = bx. tcx ( ) . sess . target . pointer_width ;
33+ let mask = align. bytes ( ) . wrapping_neg ( ) & ( u64:: MAX >> ( 64 - pointer_width) ) ;
3334 bx. call_intrinsic (
3435 "llvm.ptrmask" ,
35- & [ ptr_ty , bx. type_i32 ( ) ] ,
36- & [ ptr, bx. const_int ( bx . isize_ty , - ( align . bytes ( ) as isize ) as i64 ) ] ,
36+ & [ bx . type_ptr ( ) , bx. type_isize ( ) ] ,
37+ & [ ptr, bx. const_usize ( mask ) ] ,
3738 )
3839}
3940
@@ -53,7 +54,7 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
5354 let ptr = bx. load ( va_list_ty, va_list_addr, ptr_align_abi) ;
5455
5556 let ( addr, addr_align) = if allow_higher_align && align > slot_size {
56- ( round_pointer_up_to_alignment ( bx, ptr, align, bx . type_ptr ( ) ) , align)
57+ ( round_pointer_up_to_alignment ( bx, ptr, align) , align)
5758 } else {
5859 ( ptr, slot_size)
5960 } ;
@@ -69,7 +70,8 @@ fn emit_direct_ptr_va_arg<'ll, 'tcx>(
6970 {
7071 let adjusted_size = bx. cx ( ) . const_i32 ( ( slot_size. bytes ( ) - size. bytes ( ) ) as i32 ) ;
7172 let adjusted = bx. inbounds_ptradd ( addr, adjusted_size) ;
72- ( adjusted, addr_align)
73+ // We're in the middle of a slot now, so use the type's alignment, not the slot's.
74+ ( adjusted, align)
7375 } else {
7476 ( addr, addr_align)
7577 }
@@ -357,12 +359,8 @@ fn emit_powerpc_va_arg<'ll, 'tcx>(
357359
358360 // Round up address of argument to alignment
359361 if layout. layout . align . abi > overflow_area_align {
360- overflow_area = round_pointer_up_to_alignment (
361- bx,
362- overflow_area,
363- layout. layout . align . abi ,
364- bx. type_ptr ( ) ,
365- ) ;
362+ overflow_area =
363+ round_pointer_up_to_alignment ( bx, overflow_area, layout. layout . align . abi ) ;
366364 }
367365
368366 let mem_addr = overflow_area;
@@ -827,7 +825,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
827825 } else {
828826 Align :: from_bytes ( 4 ) . unwrap ( )
829827 } ;
830- let aligned_current = round_pointer_up_to_alignment ( bx, current_ptr, arg_align, bx . type_ptr ( ) ) ;
828+ let aligned_current = round_pointer_up_to_alignment ( bx, current_ptr, arg_align) ;
831829
832830 // Calculate next pointer position (following LLVM's logic)
833831 // Arguments <= 32 bits take 4 bytes, > 32 bits take 8 bytes
@@ -849,8 +847,7 @@ fn emit_hexagon_va_arg_musl<'ll, 'tcx>(
849847 bx. switch_to_block ( from_overflow) ;
850848
851849 // Align overflow pointer using the same alignment rules
852- let aligned_overflow =
853- round_pointer_up_to_alignment ( bx, overflow_ptr, arg_align, bx. type_ptr ( ) ) ;
850+ let aligned_overflow = round_pointer_up_to_alignment ( bx, overflow_ptr, arg_align) ;
854851
855852 let overflow_value_addr = aligned_overflow;
856853 // Update overflow pointer - use the same size calculation
@@ -890,7 +887,7 @@ fn emit_hexagon_va_arg_bare_metal<'ll, 'tcx>(
890887 let aligned_ptr = if ty_align. bytes ( ) > 4 {
891888 // Ensure alignment is a power of 2
892889 debug_assert ! ( ty_align. bytes( ) . is_power_of_two( ) , "Alignment is not power of 2!" ) ;
893- round_pointer_up_to_alignment ( bx, current_ptr, ty_align, bx . type_ptr ( ) )
890+ round_pointer_up_to_alignment ( bx, current_ptr, ty_align)
894891 } else {
895892 current_ptr
896893 } ;
0 commit comments