2013-06-19 Igor Zamyatin * gcc.dg/tree-ssa/loop-19.c: Add -fno-common. 2013-06-12 Jakub Jelinek PR target/56564 * varasm.c (decl_binds_to_current_def_p): Call binds_local_p target hook even for !TREE_PUBLIC decls. If no resolution info is available, return false for common and external decls. * gcc.target/i386/pr56564-1.c: Skip on darwin, mingw and cygwin. * gcc.target/i386/pr56564-3.c: Likewise. 2013-06-11 Jakub Jelinek PR target/56564 * varasm.c (get_variable_align): Move #endif to the right place. 2013-06-10 Jakub Jelinek 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. --- gcc/doc/tm.texi.in (revision 199897) +++ gcc/doc/tm.texi.in (revision 199898) @@ -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 (revision 199897) +++ gcc/doc/tm.texi (revision 199898) @@ -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/varasm.c (revision 199897) +++ gcc/varasm.c (revision 199984) @@ -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 @@ -989,9 +1056,7 @@ align_variable (tree decl, bool dont_out #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) { @@ -6709,10 +6781,10 @@ bool decl_binds_to_current_def_p (tree decl) { gcc_assert (DECL_P (decl)); - if (!TREE_PUBLIC (decl)) - return true; if (!targetm.binds_local_p (decl)) return false; + if (!TREE_PUBLIC (decl)) + return true; /* When resolution is available, just use it. */ if (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) @@ -6730,10 +6802,20 @@ decl_binds_to_current_def_p (tree decl) return resolution_to_local_definition_p (node->symbol.resolution); } /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks - binds locally but still can be overwritten). + binds locally but still can be overwritten), DECL_COMMON (can be merged + with a non-common definition somewhere in the same module) or + DECL_EXTERNAL. This rely on fact that binds_local_p behave as decl_replaceable_p for all other declaration types. */ - return !DECL_WEAK (decl); + if (DECL_WEAK (decl)) + return false; + if (DECL_COMMON (decl) + && (DECL_INITIAL (decl) == NULL + || DECL_INITIAL (decl) == error_mark_node)) + return false; + if (DECL_EXTERNAL (decl)) + return false; + return true; } /* A replaceable function or variable is one which may be replaced @@ -6959,7 +7041,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/config/s390/s390.h (revision 199897) +++ gcc/config/s390/s390.h (revision 199898) @@ -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 (revision 199897) +++ gcc/config/i386/i386.h (revision 199898) @@ -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 (revision 199897) +++ gcc/config/i386/i386-protos.h (revision 199898) @@ -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 (revision 199897) +++ gcc/config/i386/i386.c (revision 199898) @@ -25292,12 +25292,13 @@ 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 @@ -25309,14 +25310,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/config/c6x/c6x.h (revision 199897) +++ gcc/config/c6x/c6x.h (revision 199898) @@ -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 (revision 199897) +++ gcc/config/mmix/mmix.h (revision 199898) @@ -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 (revision 199897) +++ gcc/config/mmix/mmix.c (revision 199898) @@ -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/testsuite/gcc.target/i386/memcpy-1.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/memcpy-1.c (revision 199898) @@ -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/vect-sizes-1.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/vect-sizes-1.c (revision 199898) @@ -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/avx256-unaligned-load-4.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/avx256-unaligned-load-4.c (revision 199898) @@ -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-store-1.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-1.c (revision 199898) @@ -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.target/i386/avx256-unaligned-store-3.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-3.c (revision 199898) @@ -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/avx256-unaligned-store-4.c (revision 199897) +++ gcc/testsuite/gcc.target/i386/avx256-unaligned-store-4.c (revision 199898) @@ -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-1.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr56564-1.c (revision 199985) @@ -0,0 +1,26 @@ +/* PR target/56564 */ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-skip-if "No symbol interposition for PIC" { *-*-mingw* *-*-cygwin* *-*-darwin* } } */ +/* { 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-2.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr56564-2.c (revision 199898) @@ -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/pr56564-3.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr56564-3.c (revision 199985) @@ -0,0 +1,29 @@ +/* PR target/56564 */ +/* { dg-do compile { target { fpic && lp64 } } } */ +/* { dg-skip-if "No symbol interposition for PIC" { *-*-mingw* *-*-cygwin* *-*-darwin* } } */ +/* { 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-4.c (revision 0) +++ gcc/testsuite/gcc.target/i386/pr56564-4.c (revision 199898) @@ -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.dg/vect/costmodel/i386/costmodel-vect-31.c (revision 199897) +++ gcc/testsuite/gcc.dg/vect/costmodel/i386/costmodel-vect-31.c (revision 199898) @@ -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 (revision 199897) +++ gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-31.c (revision 199898) @@ -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/tree-ssa/loop-19.c (revision 200212) +++ gcc/testsuite/gcc.dg/tree-ssa/loop-19.c (revision 200213) @@ -6,7 +6,7 @@ /* { dg-do compile { target { i?86-*-* || { x86_64-*-* || powerpc_hard_double } } } } */ /* { dg-require-effective-target nonpic } */ -/* { dg-options "-O3 -fno-tree-loop-distribute-patterns -fno-prefetch-loop-arrays -fdump-tree-optimized" } */ +/* { dg-options "-O3 -fno-tree-loop-distribute-patterns -fno-prefetch-loop-arrays -fdump-tree-optimized -fno-common" } */ # define N 2000000 double a[N],c[N];