Patchwork DATA_ALIGNMENT vs. DATA_ABI_ALIGNMENT (PR target/56564)

login
register
mail settings
Submitter Jakub Jelinek
Date June 10, 2013, 3:44 p.m.
Message ID <20130610154421.GU1493@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/250264/
State New
Headers show

Comments

Jakub Jelinek - June 10, 2013, 3:44 p.m.
On Mon, Jun 10, 2013 at 07:51:54AM -0700, Richard Henderson wrote:
> On 06/07/2013 02:14 PM, Jakub Jelinek wrote:
> >> > When the linker merges common blocks, it chooses both maximum size and maximum
> >> > alignment.  Thus for any common block for which we can prove the block must
> >> > reside in the module (any executable, or hidden common in shared object), we
> >> > can go ahead and use the increased alignment.
> > But consider say:
> > one TU:
> > struct S { char buf[15]; } s __attribute__((aligned (32)));
> > 
> > another TU:
> > char c = 7;
> > struct S { char buf[15]; } s = { { 1, 2 } };
> > char d = 8;
> > int main () { return 0; }
> > 
> > (the aligned(32) is there just to simulate the DATA_ALIGNMENT optimization
> > increase).  Linker warns about this (thus the question is if we want to
> > increase the alignment for optimization on commons at all) and doesn't align
> > it.
> > 
> 
> Oh, right.  I hadn't considered commons unifying with non-common variables,
> and the failure of commoning in that case.  I'd mostly been thinking of
> uninitialized Fortran-like common blocks, where it is more common for the
> blocks to have nothing in common but the name.

Ok, here is what I've committed to trunk (will wait for some time before
backporting).  As discussed with Honza on IRC, decl_binds_to_current_def_p
will need further fixing, it does the wrong thing for extern int var
__attribute__((visibility ("hidden"))) or hidden DECL_COMMON symbols.

And, we don't have any feedback about SPE/E500 rs6000 - DATA_ALIGNMENT vs.
DATA_ABI_ALIGNMENT yet.

2013-06-10  Jakub Jelinek  <jakub@redhat.com>

	PR target/56564
	* varasm.c (align_variable): Don't use DATA_ALIGNMENT or
	CONSTANT_ALIGNMENT if !decl_binds_to_current_def_p (decl).
	Use DATA_ABI_ALIGNMENT for that case instead if defined.
	(get_variable_align): New function.
	(get_variable_section, emit_bss, emit_common,
	assemble_variable_contents, place_block_symbol): Use
	get_variable_align instead of DECL_ALIGN.
	(assemble_noswitch_variable): Add align argument, use it
	instead of DECL_ALIGN.
	(assemble_variable): Adjust caller.  Use get_variable_align
	instead of DECL_ALIGN.
	* config/i386/i386.h (DATA_ALIGNMENT): Adjust x86_data_alignment
	caller.
	(DATA_ABI_ALIGNMENT): Define.
	* config/i386/i386-protos.h (x86_data_alignment): Adjust prototype.
	* config/i386/i386.c (x86_data_alignment): Add opt argument.  If
	opt is false, only return the psABI mandated alignment increase.
	* config/c6x/c6x.h (DATA_ALIGNMENT): Renamed to...
	(DATA_ABI_ALIGNMENT): ... this.
	* config/mmix/mmix.h (DATA_ALIGNMENT): Renamed to...
	(DATA_ABI_ALIGNMENT): ... this.
	* config/mmix/mmix.c (mmix_data_alignment): Adjust function comment.
	* config/s390/s390.h (DATA_ALIGNMENT): Renamed to...
	(DATA_ABI_ALIGNMENT): ... this.
	* doc/tm.texi.in (DATA_ABI_ALIGNMENT): Document.
	* doc/tm.texi: Regenerated.

	* gcc.target/i386/pr56564-1.c: New test.
	* gcc.target/i386/pr56564-2.c: New test.
	* gcc.target/i386/pr56564-3.c: New test.
	* gcc.target/i386/pr56564-4.c: New test.
	* gcc.target/i386/avx256-unaligned-load-4.c: Add -fno-common.
	* gcc.target/i386/avx256-unaligned-store-1.c: Likewise.
	* gcc.target/i386/avx256-unaligned-store-3.c: Likewise.
	* gcc.target/i386/avx256-unaligned-store-4.c: Likewise.
	* gcc.target/i386/vect-sizes-1.c: Likewise.
	* gcc.target/i386/memcpy-1.c: Likewise.
	* gcc.dg/vect/costmodel/i386/costmodel-vect-31.c (tmp): Initialize.
	* gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c (tmp): Likewise.



	Jakub
David Edelsohn - June 10, 2013, 7:44 p.m.
On Mon, Jun 10, 2013 at 11:44 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Mon, Jun 10, 2013 at 07:51:54AM -0700, Richard Henderson wrote:
>> On 06/07/2013 02:14 PM, Jakub Jelinek wrote:
>> >> > When the linker merges common blocks, it chooses both maximum size and maximum
>> >> > alignment.  Thus for any common block for which we can prove the block must
>> >> > reside in the module (any executable, or hidden common in shared object), we
>> >> > can go ahead and use the increased alignment.
>> > But consider say:
>> > one TU:
>> > struct S { char buf[15]; } s __attribute__((aligned (32)));
>> >
>> > another TU:
>> > char c = 7;
>> > struct S { char buf[15]; } s = { { 1, 2 } };
>> > char d = 8;
>> > int main () { return 0; }
>> >
>> > (the aligned(32) is there just to simulate the DATA_ALIGNMENT optimization
>> > increase).  Linker warns about this (thus the question is if we want to
>> > increase the alignment for optimization on commons at all) and doesn't align
>> > it.
>> >
>>
>> Oh, right.  I hadn't considered commons unifying with non-common variables,
>> and the failure of commoning in that case.  I'd mostly been thinking of
>> uninitialized Fortran-like common blocks, where it is more common for the
>> blocks to have nothing in common but the name.
>
> Ok, here is what I've committed to trunk (will wait for some time before
> backporting).  As discussed with Honza on IRC, decl_binds_to_current_def_p
> will need further fixing, it does the wrong thing for extern int var
> __attribute__((visibility ("hidden"))) or hidden DECL_COMMON symbols.
>
> And, we don't have any feedback about SPE/E500 rs6000 - DATA_ALIGNMENT vs.
> DATA_ABI_ALIGNMENT yet.

SPE/e500 support was written by Aldy.  He or someone from Freescale
needs to comment.

- David
DJ Delorie - June 11, 2013, 12:44 a.m.
> @@ -986,12 +1053,10 @@ align_variable (tree decl, bool dont_out
>  	  if (! DECL_THREAD_LOCAL_P (decl) || const_align <= BITS_PER_WORD)
>  	    align = const_align;
>  	}
> -#endif
>      }
> +#endif

I think this change in get_variable_align() is wrong; it results in
unbalanced braces inside an #ifdef, if the #ifdef body is not included
(i.e. CONSTANT_ALIGNMENT not defined), the compile fails...

Patch

--- gcc/config/c6x/c6x.h.jj	2013-02-26 16:39:34.000000000 +0100
+++ gcc/config/c6x/c6x.h	2013-06-10 17:36:44.850082918 +0200
@@ -134,7 +134,7 @@  extern c6x_cpu_t c6x_arch;
    Really only externally visible arrays must be aligned this way, as
    only those are directly visible from another compilation unit.  But
    we don't have that information available here.  */
-#define DATA_ALIGNMENT(TYPE, ALIGN)					\
+#define DATA_ABI_ALIGNMENT(TYPE, ALIGN)					\
   (((ALIGN) < BITS_PER_UNIT * 8 && TREE_CODE (TYPE) == ARRAY_TYPE)	\
    ? BITS_PER_UNIT * 8 : (ALIGN))
 
--- gcc/config/mmix/mmix.h.jj	2013-01-11 09:03:16.000000000 +0100
+++ gcc/config/mmix/mmix.h	2013-06-10 17:36:05.585730695 +0200
@@ -164,7 +164,7 @@  struct GTY(()) machine_function
 /* Copied from elfos.h.  */
 #define MAX_OFILE_ALIGNMENT (32768 * 8)
 
-#define DATA_ALIGNMENT(TYPE, BASIC_ALIGN) \
+#define DATA_ABI_ALIGNMENT(TYPE, BASIC_ALIGN) \
  mmix_data_alignment (TYPE, BASIC_ALIGN)
 
 #define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \
--- gcc/config/mmix/mmix.c.jj	2013-03-26 10:03:58.000000000 +0100
+++ gcc/config/mmix/mmix.c	2013-06-10 17:36:28.012360493 +0200
@@ -313,7 +313,7 @@  mmix_init_machine_status (void)
   return ggc_alloc_cleared_machine_function ();
 }
 
-/* DATA_ALIGNMENT.
+/* DATA_ABI_ALIGNMENT.
    We have trouble getting the address of stuff that is located at other
    than 32-bit alignments (GETA requirements), so try to give everything
    at least 32-bit alignment.  */
--- gcc/config/s390/s390.h.jj	2013-03-27 12:52:21.000000000 +0100
+++ gcc/config/s390/s390.h	2013-06-10 17:37:32.506293505 +0200
@@ -221,7 +221,7 @@  enum processor_flags
 
 /* Alignment on even addresses for LARL instruction.  */
 #define CONSTANT_ALIGNMENT(EXP, ALIGN) (ALIGN) < 16 ? 16 : (ALIGN)
-#define DATA_ALIGNMENT(TYPE, ALIGN) (ALIGN) < 16 ? 16 : (ALIGN)
+#define DATA_ABI_ALIGNMENT(TYPE, ALIGN) (ALIGN) < 16 ? 16 : (ALIGN)
 
 /* Alignment is not required by the hardware.  */
 #define STRICT_ALIGNMENT 0
--- gcc/config/i386/i386.h.jj	2013-06-09 20:27:03.727336138 +0200
+++ gcc/config/i386/i386.h	2013-06-10 17:35:32.922269839 +0200
@@ -859,7 +859,18 @@  enum target_cpu_default
    cause character arrays to be word-aligned so that `strcpy' calls
    that copy constants to character arrays can be done inline.  */
 
-#define DATA_ALIGNMENT(TYPE, ALIGN) ix86_data_alignment ((TYPE), (ALIGN))
+#define DATA_ALIGNMENT(TYPE, ALIGN) \
+  ix86_data_alignment ((TYPE), (ALIGN), true)
+
+/* Similar to DATA_ALIGNMENT, but for the cases where the ABI mandates
+   some alignment increase, instead of optimization only purposes.  E.g.
+   AMD x86-64 psABI says that variables with array type larger than 15 bytes
+   must be aligned to 16 byte boundaries.
+
+   If this macro is not defined, then ALIGN is used.  */
+
+#define DATA_ABI_ALIGNMENT(TYPE, ALIGN) \
+  ix86_data_alignment ((TYPE), (ALIGN), false)
 
 /* If defined, a C expression to compute the alignment for a local
    variable.  TYPE is the data type, and ALIGN is the alignment that
--- gcc/config/i386/i386-protos.h.jj	2013-06-09 20:27:03.899333325 +0200
+++ gcc/config/i386/i386-protos.h	2013-06-10 17:35:32.926269775 +0200
@@ -207,7 +207,7 @@  extern void init_cumulative_args (CUMULA
 #endif	/* RTX_CODE  */
 
 #ifdef TREE_CODE
-extern int ix86_data_alignment (tree, int);
+extern int ix86_data_alignment (tree, int, bool);
 extern unsigned int ix86_local_alignment (tree, enum machine_mode,
 					  unsigned int);
 extern unsigned int ix86_minimum_alignment (tree, enum machine_mode,
--- gcc/config/i386/i386.c.jj	2013-06-09 20:27:03.674336994 +0200
+++ gcc/config/i386/i386.c	2013-06-10 17:35:32.934269642 +0200
@@ -25375,11 +25375,12 @@  ix86_constant_alignment (tree exp, int a
    instead of that alignment to align the object.  */
 
 int
-ix86_data_alignment (tree type, int align)
+ix86_data_alignment (tree type, int align, bool opt)
 {
   int max_align = optimize_size ? BITS_PER_WORD : MIN (256, MAX_OFILE_ALIGNMENT);
 
-  if (AGGREGATE_TYPE_P (type)
+  if (opt
+      && AGGREGATE_TYPE_P (type)
       && TYPE_SIZE (type)
       && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
       && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= (unsigned) max_align
@@ -25391,14 +25392,17 @@  ix86_data_alignment (tree type, int alig
      to 16byte boundary.  */
   if (TARGET_64BIT)
     {
-      if (AGGREGATE_TYPE_P (type)
-	   && TYPE_SIZE (type)
-	   && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
-	   && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
-	       || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
+      if ((opt ? AGGREGATE_TYPE_P (type) : TREE_CODE (type) == ARRAY_TYPE)
+	  && TYPE_SIZE (type)
+	  && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
+	  && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
+	      || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
 	return 128;
     }
 
+  if (!opt)
+    return align;
+
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
       if (TYPE_MODE (TREE_TYPE (type)) == DFmode && align < 64)
--- gcc/varasm.c.jj	2013-06-09 20:27:57.214463944 +0200
+++ gcc/varasm.c	2013-06-10 17:35:32.921269856 +0200
@@ -966,13 +966,80 @@  align_variable (tree decl, bool dont_out
       align = MAX_OFILE_ALIGNMENT;
     }
 
-  /* On some machines, it is good to increase alignment sometimes.  */
   if (! DECL_USER_ALIGN (decl))
     {
+#ifdef DATA_ABI_ALIGNMENT
+      unsigned int data_abi_align
+	= DATA_ABI_ALIGNMENT (TREE_TYPE (decl), align);
+      /* For backwards compatibility, don't assume the ABI alignment for
+	 TLS variables.  */
+      if (! DECL_THREAD_LOCAL_P (decl) || data_abi_align <= BITS_PER_WORD)
+	align = data_abi_align;
+#endif
+
+      /* On some machines, it is good to increase alignment sometimes.
+	 But as DECL_ALIGN is used both for actually emitting the variable
+	 and for code accessing the variable as guaranteed alignment, we
+	 can only increase the alignment if it is a performance optimization
+	 if the references to it must bind to the current definition.  */
+      if (decl_binds_to_current_def_p (decl))
+	{
+#ifdef DATA_ALIGNMENT
+	  unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
+	  /* Don't increase alignment too much for TLS variables - TLS space
+	     is too precious.  */
+	  if (! DECL_THREAD_LOCAL_P (decl) || data_align <= BITS_PER_WORD)
+	    align = data_align;
+#endif
+#ifdef CONSTANT_ALIGNMENT
+	  if (DECL_INITIAL (decl) != 0
+	      && DECL_INITIAL (decl) != error_mark_node)
+	    {
+	      unsigned int const_align
+		= CONSTANT_ALIGNMENT (DECL_INITIAL (decl), align);
+	      /* Don't increase alignment too much for TLS variables - TLS
+		 space is too precious.  */
+	      if (! DECL_THREAD_LOCAL_P (decl) || const_align <= BITS_PER_WORD)
+		align = const_align;
+	    }
+#endif
+	}
+    }
+
+  /* Reset the alignment in case we have made it tighter, so we can benefit
+     from it in get_pointer_alignment.  */
+  DECL_ALIGN (decl) = align;
+}
+
+/* Return DECL_ALIGN (decl), possibly increased for optimization purposes
+   beyond what align_variable returned.  */
+
+static unsigned int
+get_variable_align (tree decl)
+{
+  unsigned int align = DECL_ALIGN (decl);
+
+  /* For user aligned vars or static vars align_variable already did
+     everything.  */
+  if (DECL_USER_ALIGN (decl) || !TREE_PUBLIC (decl))
+    return align;
+
+#ifdef DATA_ABI_ALIGNMENT
+  if (DECL_THREAD_LOCAL_P (decl))
+    align = DATA_ABI_ALIGNMENT (TREE_TYPE (decl), align);
+#endif
+
+  /* For decls that bind to the current definition, align_variable
+     did also everything, except for not assuming ABI required alignment
+     of TLS variables.  For other vars, increase the alignment here
+     as an optimization.  */
+  if (!decl_binds_to_current_def_p (decl))
+    {
+      /* On some machines, it is good to increase alignment sometimes.  */
 #ifdef DATA_ALIGNMENT
       unsigned int data_align = DATA_ALIGNMENT (TREE_TYPE (decl), align);
       /* Don't increase alignment too much for TLS variables - TLS space
-	 is too precious.  */
+         is too precious.  */
       if (! DECL_THREAD_LOCAL_P (decl) || data_align <= BITS_PER_WORD)
 	align = data_align;
 #endif
@@ -986,12 +1053,10 @@  align_variable (tree decl, bool dont_out
 	  if (! DECL_THREAD_LOCAL_P (decl) || const_align <= BITS_PER_WORD)
 	    align = const_align;
 	}
-#endif
     }
+#endif
 
-  /* Reset the alignment in case we have made it tighter, so we can benefit
-     from it in get_pointer_alignment.  */
-  DECL_ALIGN (decl) = align;
+  return align;
 }
 
 /* Return the section into which the given VAR_DECL or CONST_DECL
@@ -1043,7 +1108,8 @@  get_variable_section (tree decl, bool pr
 	return bss_noswitch_section;
     }
 
-  return targetm.asm_out.select_section (decl, reloc, DECL_ALIGN (decl));
+  return targetm.asm_out.select_section (decl, reloc,
+					 get_variable_align (decl));
 }
 
 /* Return the block into which object_block DECL should be placed.  */
@@ -1780,7 +1846,8 @@  emit_bss (tree decl ATTRIBUTE_UNUSED,
 	  unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED)
 {
 #if defined ASM_OUTPUT_ALIGNED_BSS
-  ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size, DECL_ALIGN (decl));
+  ASM_OUTPUT_ALIGNED_BSS (asm_out_file, decl, name, size,
+			  get_variable_align (decl));
   return true;
 #endif
 }
@@ -1796,10 +1863,11 @@  emit_common (tree decl ATTRIBUTE_UNUSED,
 {
 #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON
   ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, decl, name,
-				  size, DECL_ALIGN (decl));
+				  size, get_variable_align (decl));
   return true;
 #elif defined ASM_OUTPUT_ALIGNED_COMMON
-  ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size, DECL_ALIGN (decl));
+  ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, name, size,
+			     get_variable_align (decl));
   return true;
 #else
   ASM_OUTPUT_COMMON (asm_out_file, name, size, rounded);
@@ -1828,7 +1896,8 @@  emit_tls_common (tree decl ATTRIBUTE_UNU
    NAME is the name of DECL's SYMBOL_REF.  */
 
 static void
-assemble_noswitch_variable (tree decl, const char *name, section *sect)
+assemble_noswitch_variable (tree decl, const char *name, section *sect,
+			    unsigned int align)
 {
   unsigned HOST_WIDE_INT size, rounded;
 
@@ -1850,7 +1919,7 @@  assemble_noswitch_variable (tree decl, c
 	     * (BIGGEST_ALIGNMENT / BITS_PER_UNIT));
 
   if (!sect->noswitch.callback (decl, name, size, rounded)
-      && (unsigned HOST_WIDE_INT) DECL_ALIGN_UNIT (decl) > rounded)
+      && (unsigned HOST_WIDE_INT) (align / BITS_PER_UNIT) > rounded)
     warning (0, "requested alignment for %q+D is greater than "
 	     "implemented alignment of %wu", decl, rounded);
 }
@@ -1880,7 +1949,7 @@  assemble_variable_contents (tree decl, c
 	/* Output the actual data.  */
 	output_constant (DECL_INITIAL (decl),
 			 tree_low_cst (DECL_SIZE_UNIT (decl), 1),
-			 DECL_ALIGN (decl));
+			 get_variable_align (decl));
       else
 	/* Leave space for it.  */
 	assemble_zeros (tree_low_cst (DECL_SIZE_UNIT (decl), 1));
@@ -1904,6 +1973,7 @@  assemble_variable (tree decl, int top_le
   const char *name;
   rtx decl_rtl, symbol;
   section *sect;
+  unsigned int align;
   bool asan_protected = false;
 
   /* This function is supposed to handle VARIABLES.  Ensure we have one.  */
@@ -2003,6 +2073,8 @@  assemble_variable (tree decl, int top_le
 
   set_mem_align (decl_rtl, DECL_ALIGN (decl));
 
+  align = get_variable_align (decl);
+
   if (TREE_PUBLIC (decl))
     maybe_assemble_visibility (decl);
 
@@ -2032,12 +2104,12 @@  assemble_variable (tree decl, int top_le
       place_block_symbol (symbol);
     }
   else if (SECTION_STYLE (sect) == SECTION_NOSWITCH)
-    assemble_noswitch_variable (decl, name, sect);
+    assemble_noswitch_variable (decl, name, sect, align);
   else
     {
       switch_to_section (sect);
-      if (DECL_ALIGN (decl) > BITS_PER_UNIT)
-	ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (DECL_ALIGN_UNIT (decl)));
+      if (align > BITS_PER_UNIT)
+	ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
       assemble_variable_contents (decl, name, dont_output_data);
       if (asan_protected)
 	{
@@ -6959,7 +7031,7 @@  place_block_symbol (rtx symbol)
   else
     {
       decl = SYMBOL_REF_DECL (symbol);
-      alignment = DECL_ALIGN (decl);
+      alignment = get_variable_align (decl);
       size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
       if (flag_asan && asan_protect_global (decl))
 	{
--- gcc/doc/tm.texi.in.jj	2013-06-09 20:27:03.641337535 +0200
+++ gcc/doc/tm.texi.in	2013-06-10 17:35:32.983268835 +0200
@@ -1062,6 +1062,15 @@  arrays to be word-aligned so that @code{
 constants to character arrays can be done inline.
 @end defmac
 
+@defmac DATA_ABI_ALIGNMENT (@var{type}, @var{basic-align})
+Similar to @code{DATA_ALIGNMENT}, but for the cases where the ABI mandates
+some alignment increase, instead of optimization only purposes.  E.g.@
+AMD x86-64 psABI says that variables with array type larger than 15 bytes
+must be aligned to 16 byte boundaries.
+
+If this macro is not defined, then @var{basic-align} is used.
+@end defmac
+
 @defmac CONSTANT_ALIGNMENT (@var{constant}, @var{basic-align})
 If defined, a C expression to compute the alignment given to a constant
 that is being placed in memory.  @var{constant} is the constant and
--- gcc/doc/tm.texi.jj	2013-06-09 20:27:03.511339649 +0200
+++ gcc/doc/tm.texi	2013-06-10 17:35:33.053267681 +0200
@@ -1078,6 +1078,15 @@  arrays to be word-aligned so that @code{
 constants to character arrays can be done inline.
 @end defmac
 
+@defmac DATA_ABI_ALIGNMENT (@var{type}, @var{basic-align})
+Similar to @code{DATA_ALIGNMENT}, but for the cases where the ABI mandates
+some alignment increase, instead of optimization only purposes.  E.g.@
+AMD x86-64 psABI says that variables with array type larger than 15 bytes
+must be aligned to 16 byte boundaries.
+
+If this macro is not defined, then @var{basic-align} is used.
+@end defmac
+
 @defmac CONSTANT_ALIGNMENT (@var{constant}, @var{basic-align})
 If defined, a C expression to compute the alignment given to a constant
 that is being placed in memory.  @var{constant} is the constant and
--- gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c.jj	2013-06-09 20:27:03.333342550 +0200
+++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c	2013-06-10 17:35:33.184265514 +0200
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store" } */
+/* { dg-options "-O3 -dp -mavx -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store -fno-common" } */
 
 #define N 1024
 
--- gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c.jj	2013-06-09 20:27:03.299343104 +0200
+++ gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c	2013-06-10 17:35:33.106266802 +0200
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store" } */
+/* { dg-options "-O3 -dp -mavx -mno-avx256-split-unaligned-load -mno-avx256-split-unaligned-store -fno-common" } */
 
 #define N 1024
 
--- gcc/testsuite/gcc.target/i386/pr56564-4.c.jj	2013-06-10 17:35:33.086267133 +0200
+++ gcc/testsuite/gcc.target/i386/pr56564-4.c	2013-06-10 17:35:33.087267116 +0200
@@ -0,0 +1,22 @@ 
+/* PR target/56564 */
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O3 -fno-pic -fdump-tree-optimized" } */
+
+__thread struct S { long a, b; } s = { 5, 6 };
+__thread char t[16] = { 7 };
+
+int
+foo (void)
+{
+  return ((__UINTPTR_TYPE__) &s) & 15;
+}
+
+int
+bar (void)
+{
+  return ((__UINTPTR_TYPE__) &t[0]) & 15;
+}
+
+/* { dg-final { scan-assembler-not ".align\[ \t]*16\[^:]*\[\n\r]s:" { target { *-*-linux* } } } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]t:" { target { *-*-linux* } } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.target/i386/memcpy-1.c.jj	2013-06-09 20:27:03.248343936 +0200
+++ gcc/testsuite/gcc.target/i386/memcpy-1.c	2013-06-10 17:35:33.229264767 +0200
@@ -1,6 +1,6 @@ 
 /* { dg-do compile } */
 /* { dg-require-effective-target ia32 } */
-/* { dg-options "-O2 -march=pentiumpro -minline-all-stringops" } */
+/* { dg-options "-O2 -march=pentiumpro -minline-all-stringops -fno-common" } */
 /* { dg-final { scan-assembler "rep" } } */
 /* { dg-final { scan-assembler "movs" } } */
 /* { dg-final { scan-assembler-not "test" } } */
--- gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c.jj	2013-06-09 20:27:03.276343479 +0200
+++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c	2013-06-10 17:35:33.128266441 +0200
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic" } */
+/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -mtune=generic -fno-common" } */
 
 #define N 1024
 
--- gcc/testsuite/gcc.target/i386/vect-sizes-1.c.jj	2013-06-09 20:27:03.328342631 +0200
+++ gcc/testsuite/gcc.target/i386/vect-sizes-1.c	2013-06-10 17:35:33.194265350 +0200
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O3 -ffast-math -mavx -mtune=generic" } */
+/* { dg-options "-O3 -ffast-math -mavx -mtune=generic -fno-common" } */
 
 double a[1024];
 
--- gcc/testsuite/gcc.target/i386/pr56564-1.c.jj	2013-06-10 17:35:33.062267530 +0200
+++ gcc/testsuite/gcc.target/i386/pr56564-1.c	2013-06-10 17:35:33.075267314 +0200
@@ -0,0 +1,25 @@ 
+/* PR target/56564 */
+/* { dg-do compile { target { fpic && lp64 } } } */
+/* { dg-options "-O3 -fpic -fdump-tree-optimized" } */
+
+struct S { long a, b; } s = { 5, 6 };
+char t[16] = { 7 };
+
+int
+foo (void)
+{
+  return ((__UINTPTR_TYPE__) &s) & 15;
+}
+
+int
+bar (void)
+{
+  return ((__UINTPTR_TYPE__) &t[0]) & 15;
+}
+
+/* { dg-final { scan-tree-dump-times "&s" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&t" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]s:" { target { *-*-linux* } } } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]t:" { target { *-*-linux* } } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.target/i386/pr56564-3.c.jj	2013-06-10 17:35:33.086267133 +0200
+++ gcc/testsuite/gcc.target/i386/pr56564-3.c	2013-06-10 17:35:33.086267133 +0200
@@ -0,0 +1,28 @@ 
+/* PR target/56564 */
+/* { dg-do compile { target { fpic && lp64 } } } */
+/* { dg-options "-O3 -fpic -fdump-tree-optimized" } */
+
+__thread struct S { long a, b; } s = { 5, 6 };
+__thread char t[16] = { 7 };
+
+int
+foo (void)
+{
+  return ((__UINTPTR_TYPE__) &s) & 15;
+}
+
+/* For backwards compatibility we don't assume that t must
+   be aligned to 16 bytes, but align it anyway.  */
+
+int
+bar (void)
+{
+  return ((__UINTPTR_TYPE__) &t[0]) & 15;
+}
+
+/* { dg-final { scan-tree-dump-times "&s" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&t" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0" 0 "optimized" } } */
+/* { dg-final { scan-assembler-not ".align\[ \t]*16\[^:]*\[\n\r]s:" { target { *-*-linux* } } } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]t:" { target { *-*-linux* } } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.target/i386/pr56564-2.c.jj	2013-06-10 17:35:33.075267314 +0200
+++ gcc/testsuite/gcc.target/i386/pr56564-2.c	2013-06-10 17:35:33.075267314 +0200
@@ -0,0 +1,25 @@ 
+/* PR target/56564 */
+/* { dg-do compile { target { *-*-linux* && lp64 } } } */
+/* { dg-options "-O3 -fno-pic -fdump-tree-optimized" } */
+
+struct S { long a, b; } s = { 5, 6 };
+char t[16] = { 7 };
+
+int
+foo (void)
+{
+  return ((__UINTPTR_TYPE__) &s) & 15;
+}
+
+int
+bar (void)
+{
+  return ((__UINTPTR_TYPE__) &t[0]) & 15;
+}
+
+/* { dg-final { scan-tree-dump-times "&s" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "&t" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0" 2 "optimized" } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]s:" { target { *-*-linux* } } } } */
+/* { dg-final { scan-assembler ".align\[ \t]*16\[^:]*\[\n\r]t:" { target { *-*-linux* } } } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c.jj	2013-06-09 20:27:03.354342207 +0200
+++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c	2013-06-10 17:35:33.115266654 +0200
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store" } */
+/* { dg-options "-O3 -dp -mavx -mavx256-split-unaligned-store -fno-common" } */
 
 #define N 1024
 
--- gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c.jj	2013-06-09 20:27:03.475340236 +0200
+++ gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c	2013-06-10 17:35:33.237264640 +0200
@@ -18,7 +18,7 @@  struct s{
   struct t e;   /* unaligned (offset 2N+4N+4 B) */
 };
  
-struct s tmp;
+struct s tmp = { 1 };
 
 int main1 ()
 {  
--- gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c.jj	2013-06-09 20:27:03.475340236 +0200
+++ gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c	2013-06-10 17:35:33.248264459 +0200
@@ -18,7 +18,7 @@  struct s{
   struct t e;   /* unaligned (offset 2N+4N+4 B) */
 };
  
-struct s tmp;
+struct s tmp = { 1 };
 
 int main1 ()
 {