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);

Reply via email to