re PR middle-end/36253 (Caller-save stack slot may not have proper alignment)
authorH.J. Lu <hongjiu.lu@intel.com>
Mon, 26 May 2008 13:59:56 +0000 (13:59 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Mon, 26 May 2008 13:59:56 +0000 (06:59 -0700)
2008-05-26  H.J. Lu  <hongjiu.lu@intel.com>

PR middle-end/36253
* caller-save.c (insert_restore): Verify alignment of spill
space.
(insert_save): Likewise.

* cfgexpand.c (LOCAL_ALIGNMENT): Removed.

* defaults.h (LOCAL_ALIGNMENT): New. Provide default.
(STACK_SLOT_ALIGNMENT): Likewise.

* function.c (LOCAL_ALIGNMENT): Removed.
(get_stack_local_alignment): New.
(assign_stack_local): Use it.  Set alignment on stack slot.
(assign_stack_temp_for_type): Use get_stack_local_alignment.

* config/i386/i386.h (LOCAL_ALIGNMENT): Updated.
(STACK_SLOT_ALIGNMENT): New.

* config/i386/i386.c (ix86_local_alignment): Handle caller-save
stack slot in XFmode.

* doc/tm.texi (STACK_SLOT_ALIGNMENT): New.

From-SVN: r135927

gcc/ChangeLog
gcc/caller-save.c
gcc/cfgexpand.c
gcc/config/i386/i386-protos.h
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/defaults.h
gcc/doc/tm.texi
gcc/function.c

index f12440f1afe82d6ad73d898666a7696538d62c69..a6fad4f55efd1f8e890b0e01ed643c95f218abcf 100644 (file)
@@ -1,3 +1,28 @@
+2008-05-26  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR middle-end/36253
+       * caller-save.c (insert_restore): Verify alignment of spill
+       space.
+       (insert_save): Likewise.
+
+       * cfgexpand.c (LOCAL_ALIGNMENT): Removed.
+
+       * defaults.h (LOCAL_ALIGNMENT): New. Provide default.
+       (STACK_SLOT_ALIGNMENT): Likewise.
+
+       * function.c (LOCAL_ALIGNMENT): Removed.
+       (get_stack_local_alignment): New.
+       (assign_stack_local): Use it.  Set alignment on stack slot.
+       (assign_stack_temp_for_type): Use get_stack_local_alignment.
+
+       * config/i386/i386.h (LOCAL_ALIGNMENT): Updated.
+       (STACK_SLOT_ALIGNMENT): New.
+
+       * config/i386/i386.c (ix86_local_alignment): Handle caller-save
+       stack slot in XFmode.
+
+       * doc/tm.texi (STACK_SLOT_ALIGNMENT): New.
+
 2008-05-26  Kai Tietz  <kai.tietz@onevision.com>
 
        PR/36321
index 7976fd5fd7509b7901f0e11836b2074887392827..c6a685bde9c5a19ba557e965d16ebd11f278b116 100644 (file)
@@ -704,6 +704,11 @@ insert_restore (struct insn_chain *chain, int before_p, int regno,
     mem = adjust_address (mem, save_mode[regno], 0);
   else
     mem = copy_rtx (mem);
+
+  /* Verify that the alignment of spill space is equal to or greater
+     than required.  */
+  gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
+
   pat = gen_rtx_SET (VOIDmode,
                     gen_rtx_REG (GET_MODE (mem),
                                  regno), mem);
@@ -776,6 +781,11 @@ insert_save (struct insn_chain *chain, int before_p, int regno,
     mem = adjust_address (mem, save_mode[regno], 0);
   else
     mem = copy_rtx (mem);
+
+  /* Verify that the alignment of spill space is equal to or greater
+     than required.  */
+  gcc_assert (GET_MODE_ALIGNMENT (GET_MODE (mem)) <= MEM_ALIGN (mem));
+
   pat = gen_rtx_SET (VOIDmode, mem,
                     gen_rtx_REG (GET_MODE (mem),
                                  regno));
index 69a911eac8ef5233467a026c9cab84db5b715600..ffe2366a1084b63867c8de5aa5ea8b50f842854c 100644 (file)
@@ -86,10 +86,6 @@ failed:
 }
 
 
-#ifndef LOCAL_ALIGNMENT
-#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
-#endif
-
 #ifndef STACK_ALIGNMENT_NEEDED
 #define STACK_ALIGNMENT_NEEDED 1
 #endif
index aee90eb65bda927081cd6172ebfc28bbaf913333..6fdea06c51857728953f80fd29e1575adcf177d8 100644 (file)
@@ -187,7 +187,8 @@ extern void function_arg_advance (CUMULATIVE_ARGS *, enum machine_mode,
 extern int ix86_return_pops_args (tree, tree, int);
 
 extern int ix86_data_alignment (tree, int);
-extern int ix86_local_alignment (tree, int);
+extern unsigned int ix86_local_alignment (tree, enum machine_mode,
+                                         unsigned int);
 extern int ix86_constant_alignment (tree, int);
 extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *);
 extern tree ix86_handle_selectany_attribute (tree *, tree, tree, int, bool *);
index 369ae5848678b3c574d64852b8957215a55da041..6cac18ae8aa65c46270bcebe015c5114a041d1a5 100644 (file)
@@ -16996,14 +16996,25 @@ ix86_data_alignment (tree type, int align)
   return align;
 }
 
-/* Compute the alignment for a local variable.
-   TYPE is the data type, and ALIGN is the alignment that
-   the object would ordinarily have.  The value of this macro is used
-   instead of that alignment to align the object.  */
+/* Compute the alignment for a local variable or a stack slot.  TYPE is
+   the data type, MODE is the widest mode available and ALIGN is the
+   alignment that the object would ordinarily have.  The value of this
+   macro is used instead of that alignment to align the object.  */
 
-int
-ix86_local_alignment (tree type, int align)
+unsigned int
+ix86_local_alignment (tree type, enum machine_mode mode,
+                     unsigned int align)
 {
+  /* If TYPE is NULL, we are allocating a stack slot for caller-save
+     register in MODE.  We will return the largest alignment of XF
+     and DF.  */
+  if (!type)
+    {
+      if (mode == XFmode && align < GET_MODE_ALIGNMENT (DFmode))
+       align = GET_MODE_ALIGNMENT (DFmode);
+      return align;
+    }
+
   /* x86-64 ABI requires arrays greater than 16 bytes to be aligned
      to 16byte boundary.  */
   if (TARGET_64BIT)
index 0b5ca139350b18f0d50c972db36147f7d963c653..ef8da17af3ff120bc9261350d95cbcbdcd4f23ee 100644 (file)
@@ -902,7 +902,22 @@ enum target_cpu_default
    One use of this macro is to increase alignment of medium-size
    data to make it all fit in fewer cache lines.  */
 
-#define LOCAL_ALIGNMENT(TYPE, ALIGN) ix86_local_alignment ((TYPE), (ALIGN))
+#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
+  ix86_local_alignment ((TYPE), VOIDmode, (ALIGN))
+
+/* If defined, a C expression to compute the alignment for stack slot.
+   TYPE is the data type, MODE is the widest mode available, and ALIGN
+   is the alignment that the slot would ordinarily have.  The value of
+   this macro is used instead of that alignment to align the slot.
+
+   If this macro is not defined, then ALIGN is used when TYPE is NULL,
+   Otherwise, LOCAL_ALIGNMENT will be used.
+
+   One use of this macro is to set alignment of stack slot to the
+   maximum alignment of all possible modes which the slot may have.  */
+
+#define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \
+  ix86_local_alignment ((TYPE), (MODE), (ALIGN))
 
 /* If defined, a C expression that gives the alignment boundary, in
    bits, of an argument with the specified mode and type.  If it is
index ff5b5c01cf33136f3abee802d169e5a1e23e8b20..392d22cfabb755ae515a7fa22bf699661e9303dd 100644 (file)
@@ -940,4 +940,13 @@ along with GCC; see the file COPYING3.  If not see
 #define OUTGOING_REG_PARM_STACK_SPACE(FNTYPE) 0
 #endif
 
+#ifndef LOCAL_ALIGNMENT
+#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
+#endif
+
+#ifndef STACK_SLOT_ALIGNMENT
+#define STACK_SLOT_ALIGNMENT(TYPE,MODE,ALIGN) \
+  ((TYPE) ? LOCAL_ALIGNMENT ((TYPE), (ALIGN)) : (ALIGN))
+#endif
+
 #endif  /* ! GCC_DEFAULTS_H */
index 8c0de3b41dea5cd53c390b451541ff765a388743..eeb744bd60dccab9bc2c5c7fb6ea60426e3c628c 100644 (file)
@@ -1172,6 +1172,21 @@ One use of this macro is to increase alignment of medium-size data to
 make it all fit in fewer cache lines.
 @end defmac
 
+@defmac STACK_SLOT_ALIGNMENT (@var{type}, @var{mode}, @var{basic-align})
+If defined, a C expression to compute the alignment for stack slot.
+@var{type} is the data type, @var{mode} is the widest mode available,
+and @var{basic-align} is the alignment that the slot would ordinarily
+have.  The value of this macro is used instead of that alignment to
+align the slot.
+
+If this macro is not defined, then @var{basic-align} is used when
+@var{type} is @code{NULL}.  Otherwise, @code{LOCAL_ALIGNMENT} will
+be used.
+
+This macro is to set alignment of stack slot to the maximum alignment
+of all possible modes which the slot may have.
+@end defmac
+
 @defmac EMPTY_FIELD_BOUNDARY
 Alignment in bits to be given to a structure bit-field that follows an
 empty field such as @code{int : 0;}.
index f5a674045622570101cdec8d1bc7540d2da4382d..845017f7124b09bd93d66cbc8dc6a773b2b350d7 100644 (file)
@@ -69,10 +69,6 @@ along with GCC; see the file COPYING3.  If not see
 /* So we can assign to cfun in this file.  */
 #undef cfun
 
-#ifndef LOCAL_ALIGNMENT
-#define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT
-#endif
-
 #ifndef STACK_ALIGNMENT_NEEDED
 #define STACK_ALIGNMENT_NEEDED 1
 #endif
@@ -325,6 +321,26 @@ frame_offset_overflow (HOST_WIDE_INT offset, tree func)
   return FALSE;
 }
 
+/* Return stack slot alignment in bits for TYPE and MODE.  */
+
+static unsigned int
+get_stack_local_alignment (tree type, enum machine_mode mode)
+{
+  unsigned int alignment;
+
+  if (mode == BLKmode)
+    alignment = BIGGEST_ALIGNMENT;
+  else
+    alignment = GET_MODE_ALIGNMENT (mode);
+
+  /* Allow the frond-end to (possibly) increase the alignment of this
+     stack slot.  */
+  if (! type)
+    type = lang_hooks.types.type_for_mode (mode, 0);
+
+  return STACK_SLOT_ALIGNMENT (type, mode, alignment);
+}
+
 /* Allocate a stack slot of SIZE bytes and return a MEM rtx for it
    with machine mode MODE.
 
@@ -341,24 +357,12 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
 {
   rtx x, addr;
   int bigend_correction = 0;
-  unsigned int alignment;
+  unsigned int alignment, alignment_in_bits;
   int frame_off, frame_alignment, frame_phase;
 
   if (align == 0)
     {
-      tree type;
-
-      if (mode == BLKmode)
-       alignment = BIGGEST_ALIGNMENT;
-      else
-       alignment = GET_MODE_ALIGNMENT (mode);
-
-      /* Allow the target to (possibly) increase the alignment of this
-        stack slot.  */
-      type = lang_hooks.types.type_for_mode (mode, 0);
-      if (type)
-       alignment = LOCAL_ALIGNMENT (type, alignment);
-
+      alignment = get_stack_local_alignment (NULL, mode);
       alignment /= BITS_PER_UNIT;
     }
   else if (align == -1)
@@ -378,8 +382,10 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
   if (alignment * BITS_PER_UNIT > PREFERRED_STACK_BOUNDARY)
     alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
 
-  if (crtl->stack_alignment_needed < alignment * BITS_PER_UNIT)
-    crtl->stack_alignment_needed = alignment * BITS_PER_UNIT;
+  alignment_in_bits = alignment * BITS_PER_UNIT;
+
+  if (crtl->stack_alignment_needed < alignment_in_bits)
+    crtl->stack_alignment_needed = alignment_in_bits;
 
   /* Calculate how many bytes the start of local variables is off from
      stack alignment.  */
@@ -432,6 +438,7 @@ assign_stack_local (enum machine_mode mode, HOST_WIDE_INT size, int align)
     frame_offset += size;
 
   x = gen_rtx_MEM (mode, addr);
+  set_mem_align (x, alignment_in_bits);
   MEM_NOTRAP_P (x) = 1;
 
   stack_slot_list
@@ -544,16 +551,7 @@ assign_stack_temp_for_type (enum machine_mode mode, HOST_WIDE_INT size,
   /* These are now unused.  */
   gcc_assert (keep <= 1);
 
-  if (mode == BLKmode)
-    align = BIGGEST_ALIGNMENT;
-  else
-    align = GET_MODE_ALIGNMENT (mode);
-
-  if (! type)
-    type = lang_hooks.types.type_for_mode (mode, 0);
-
-  if (type)
-    align = LOCAL_ALIGNMENT (type, align);
+  align = get_stack_local_alignment (type, mode);
 
   /* Try to find an available, already-allocated temporary of the proper
      mode which meets the size and alignment requirements.  Choose the