diff --git a/src/abi/pass_mode.rs b/src/abi/pass_mode.rs index 2f91e83386c..1202c23dbe7 100644 --- a/src/abi/pass_mode.rs +++ b/src/abi/pass_mode.rs @@ -227,17 +227,19 @@ pub(super) fn from_casted_value<'tcx>( cast: CastTarget, ) -> CValue<'tcx> { let abi_params = cast_target_to_abi_params(cast); - let size: u32 = abi_params + let abi_param_size: u32 = abi_params .iter() .map(|param| param.value_type.bytes()) .sum(); - // Stack slot size may be bigger for for example `[u8; 3]` which is packed into an `i32`. - assert!(u64::from(size) >= layout.size.bytes()); + let layout_size = u32::try_from(layout.size.bytes()).unwrap(); let stack_slot = fx.bcx.create_stack_slot(StackSlotData { kind: StackSlotKind::ExplicitSlot, // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to // specify stack slot alignment. - size: (size + 15) / 16 * 16, + // Stack slot size may be bigger for for example `[u8; 3]` which is packed into an `i32`. + // It may also be smaller for example when the type is a wrapper around an integer with a + // larger alignment than the integer. + size: (std::cmp::max(abi_param_size, layout_size) + 15) / 16 * 16, offset: None, }); let ptr = Pointer::new(fx.bcx.ins().stack_addr(pointer_ty(fx.tcx), stack_slot, 0));