https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86705
--- Comment #1 from Jozef Lawrynowicz <jozef.l at mittosystems dot com> --- Untested patch diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index d6e3c38..573324a 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1258,9 +1258,12 @@ set_parm_rtl (tree parm, rtx x) pointer. ??? We've got a pseudo for sure here, do we actually dynamically allocate its spilling area if needed? ??? Isn't it a problem when POINTER_SIZE also exceeds - MAX_SUPPORTED_STACK_ALIGNMENT, as on cris and lm32? */ + MAX_SUPPORTED_STACK_ALIGNMENT, as on cris and lm32? + POINTER_SIZE may not be a power of 2 e.g. for msp430-elf with the large + data model, so align to the largest power of 2 that is + <= POINTER_SIZE. */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = (unsigned)1 << floor_log2(POINTER_SIZE); record_alignment_for_reg_var (align); } @@ -1381,7 +1384,7 @@ expand_one_ssa_partition (tree var) /* If the variable alignment is very large we'll dynamicaly allocate it, which means that in-frame portion is just a pointer. */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = (unsigned)1 << floor_log2(POINTER_SIZE); record_alignment_for_reg_var (align); @@ -1608,7 +1611,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand) /* If the variable alignment is very large we'll dynamicaly allocate it, which means that in-frame portion is just a pointer. */ if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = POINTER_SIZE; + align = (unsigned)1 << floor_log2(POINTER_SIZE); } record_alignment_for_reg_var (align);