@@ -384,13 +384,28 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
384
384
}
385
385
386
386
pub ( crate ) fn create_stack_slot ( & mut self , size : u32 , align : u32 ) -> Pointer {
387
- let stack_slot = self . bcx . create_sized_stack_slot ( StackSlotData {
388
- kind : StackSlotKind :: ExplicitSlot ,
389
- // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
390
- // specify stack slot alignment.
391
- size : ( size + 15 ) / 16 * 16 ,
392
- } ) ;
393
- Pointer :: stack_slot ( stack_slot)
387
+ if align <= 16 {
388
+ let stack_slot = self . bcx . create_sized_stack_slot ( StackSlotData {
389
+ kind : StackSlotKind :: ExplicitSlot ,
390
+ // FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
391
+ // specify stack slot alignment.
392
+ size : ( size + 15 ) / 16 * 16 ,
393
+ } ) ;
394
+ Pointer :: stack_slot ( stack_slot)
395
+ } else {
396
+ // Alignment is too big to handle using the above hack. Dynamically realign a stack slot
397
+ // instead. This wastes some space for the realignment.
398
+ let stack_slot = self . bcx . create_sized_stack_slot ( StackSlotData {
399
+ kind : StackSlotKind :: ExplicitSlot ,
400
+ // FIXME is this calculation to ensure there is enough space to dyanmically realign
401
+ // as well as keep a 16 byte realignment for the other stack slots correct?
402
+ size : ( ( size + align - 1 ) + 16 ) / 16 * 16 ,
403
+ } ) ;
404
+ let base_ptr = self . bcx . ins ( ) . stack_addr ( self . pointer_type , stack_slot, 0 ) ;
405
+ let misalign_offset = self . bcx . ins ( ) . urem_imm ( base_ptr, i64:: from ( align) ) ;
406
+ let realign_offset = self . bcx . ins ( ) . irsub_imm ( misalign_offset, i64:: from ( align) ) ;
407
+ Pointer :: new ( self . bcx . ins ( ) . iadd ( base_ptr, realign_offset) )
408
+ }
394
409
}
395
410
396
411
pub ( crate ) fn set_debug_loc ( & mut self , source_info : mir:: SourceInfo ) {
0 commit comments