diff options
-rw-r--r-- | gcc/c/c-decl.c | 7 | ||||
-rw-r--r-- | gcc/config/i386/i386-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 18 | ||||
-rw-r--r-- | gcc/cp/decl.c | 7 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 5 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/target.def | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-1.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-2.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-3.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-4.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-5.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-6.c | 24 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-7.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-8.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/pr95237-9.c | 10 |
16 files changed, 170 insertions, 3 deletions
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 81bd2ee..5d6b504 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -5600,6 +5600,13 @@ finish_decl (tree decl, location_t init_loc, tree init, NULL_TREE, DECL_ATTRIBUTES (decl)); } + /* This is the last point we can lower alignment so give the target the + chance to do so. */ + if (VAR_P (decl) + && !is_global_var (decl) + && !DECL_HARD_REGISTER (decl)) + targetm.lower_local_decl_alignment (decl); + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 7c2ce61..0b95c57 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -223,7 +223,7 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree, int); #ifdef TREE_CODE extern int ix86_data_alignment (tree, unsigned int, bool); extern unsigned int ix86_local_alignment (tree, machine_mode, - unsigned int); + unsigned int, bool = false); extern unsigned int ix86_minimum_alignment (tree, machine_mode, unsigned int); extern tree ix86_handle_shared_attribute (tree *, tree, tree, int, bool *); diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 31757b0..8ea6a4d 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -16633,6 +16633,16 @@ ix86_data_alignment (tree type, unsigned int align, bool opt) return align; } +/* Implememnt TARGET_LOWER_LOCAL_DECL_ALIGNMENT. */ +static void +ix86_lower_local_decl_alignment (tree decl) +{ + unsigned int new_align = ix86_local_alignment (decl, VOIDmode, + DECL_ALIGN (decl), true); + if (new_align < DECL_ALIGN (decl)) + SET_DECL_ALIGN (decl, new_align); +} + /* Compute the alignment for a local variable or a stack slot. EXP is the data type or decl itself, MODE is the widest mode available and ALIGN is the alignment that the object would ordinarily have. The @@ -16641,7 +16651,7 @@ ix86_data_alignment (tree type, unsigned int align, bool opt) unsigned int ix86_local_alignment (tree exp, machine_mode mode, - unsigned int align) + unsigned int align, bool may_lower) { tree type, decl; @@ -16658,7 +16668,8 @@ ix86_local_alignment (tree exp, machine_mode mode, /* Don't do dynamic stack realignment for long long objects with -mpreferred-stack-boundary=2. */ - if (!TARGET_64BIT + if (may_lower + && !TARGET_64BIT && align == 64 && ix86_preferred_stack_boundary < 64 && (mode == DImode || (type && TYPE_MODE (type) == DImode)) @@ -23386,6 +23397,9 @@ ix86_run_selftests (void) #undef TARGET_CAN_CHANGE_MODE_CLASS #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class +#undef TARGET_LOWER_LOCAL_DECL_ALIGNMENT +#define TARGET_LOWER_LOCAL_DECL_ALIGNMENT ix86_lower_local_decl_alignment + #undef TARGET_STATIC_RTX_ALIGNMENT #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment #undef TARGET_CONSTANT_ALIGNMENT diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index db91b50..7d71745 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8012,6 +8012,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p, NULL_TREE, DECL_ATTRIBUTES (decl)); } + /* This is the last point we can lower alignment so give the target the + chance to do so. */ + if (VAR_P (decl) + && !is_global_var (decl) + && !DECL_HARD_REGISTER (decl)) + targetm.lower_local_decl_alignment (decl); + invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl); } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 41b9e10..4371876 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1086,6 +1086,11 @@ On 32-bit ELF the largest supported section alignment in bits is @samp{(0x80000000 * 8)}, but this is not representable on 32-bit hosts. @end defmac +@deftypefn {Target Hook} void TARGET_LOWER_LOCAL_DECL_ALIGNMENT (tree @var{decl}) +Define this hook to lower alignment of local, parm or result +decl @samp{(@var{decl})}. +@end deftypefn + @deftypefn {Target Hook} HOST_WIDE_INT TARGET_STATIC_RTX_ALIGNMENT (machine_mode @var{mode}) This hook returns the preferred alignment in bits for a statically-allocated rtx, such as a constant pool entry. @var{mode} diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 3be984b..d76c85d 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -1036,6 +1036,8 @@ On 32-bit ELF the largest supported section alignment in bits is @samp{(0x80000000 * 8)}, but this is not representable on 32-bit hosts. @end defmac +@hook TARGET_LOWER_LOCAL_DECL_ALIGNMENT + @hook TARGET_STATIC_RTX_ALIGNMENT @defmac DATA_ALIGNMENT (@var{type}, @var{basic-align}) diff --git a/gcc/target.def b/gcc/target.def index f2f314e..c11cab8 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3351,6 +3351,13 @@ HOOK_VECTOR_END (addr_space) #define HOOK_PREFIX "TARGET_" DEFHOOK +(lower_local_decl_alignment, + "Define this hook to lower alignment of local, parm or result\n\ +decl @samp{(@var{decl})}.", + void, (tree decl), + hook_void_tree) + +DEFHOOK (static_rtx_alignment, "This hook returns the preferred alignment in bits for a\n\ statically-allocated rtx, such as a constant pool entry. @var{mode}\n\ diff --git a/gcc/testsuite/c-c++-common/pr95237-1.c b/gcc/testsuite/c-c++-common/pr95237-1.c new file mode 100644 index 0000000..8947a9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-1.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +typedef __UINTPTR_TYPE__ uintptr_t; +void __attribute__((noipa)) foo (long long *p, uintptr_t a) +{ + if ((uintptr_t)p & (a-1)) + __builtin_abort (); +} +int main() +{ + long long x; + uintptr_t a = __alignof__(x); + foo(&x, a); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-2.c b/gcc/testsuite/c-c++-common/pr95237-2.c new file mode 100644 index 0000000..87949a9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-2.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +long long x; +int main() +{ + if (__alignof__(x) != 8) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-3.c b/gcc/testsuite/c-c++-common/pr95237-3.c new file mode 100644 index 0000000..6941b6f --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-3.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +int main() +{ + long long x; + if (__alignof__(x) != 4) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-4.c b/gcc/testsuite/c-c++-common/pr95237-4.c new file mode 100644 index 0000000..deace53 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-4.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=4" { target { i?86-*-* x86_64-*-* } } } */ +int main() +{ + long long x; + if (__alignof__(x) != 8) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-5.c b/gcc/testsuite/c-c++-common/pr95237-5.c new file mode 100644 index 0000000..9dc5cfc --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-5.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-mpreferred-stack-boundary=2 -Os -w" { target { i?86-*-* x86_64-*-* } } } */ + +int a; + +long long __attribute__((noinline)) +b (void) +{ +} + +void +c (void) +{ + if (b()) + a = 1; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-6.c b/gcc/testsuite/c-c++-common/pr95237-6.c new file mode 100644 index 0000000..ce1568f --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-6.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* { dg-options "-O2" { target { i?86-*-* x86_64-*-* } } } */ +#include <stddef.h> +#ifdef __x86_64__ +# define EXP_ALIGN 8 +#else +# define EXP_ALIGN 4 +#endif + +struct test +{ + char a; + long long b; +}; +struct test global_var; +int main() +{ + struct test local_var; + if (__alignof__(global_var) != EXP_ALIGN + || __alignof__(local_var) != EXP_ALIGN + || offsetof(struct test, b) != EXP_ALIGN) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-7.c b/gcc/testsuite/c-c++-common/pr95237-7.c new file mode 100644 index 0000000..8410009 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-7.c @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +#include <stddef.h> +struct test +{ + char a; + long long b; +}; +struct test global_var; +int main() +{ + struct test local_var; + if (__alignof__(global_var) != 4 + || __alignof__(local_var) != 4 + || offsetof(struct test, b) != 4) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-8.c b/gcc/testsuite/c-c++-common/pr95237-8.c new file mode 100644 index 0000000..8ba98ab --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-8.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +int main() +{ + extern long long x; + if (__alignof__(x) != 8) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/pr95237-9.c b/gcc/testsuite/c-c++-common/pr95237-9.c new file mode 100644 index 0000000..687517c --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr95237-9.c @@ -0,0 +1,10 @@ +/* { dg-do run } */ +/* { dg-require-effective-target ia32 } */ +/* { dg-options "-mpreferred-stack-boundary=2" { target { i?86-*-* x86_64-*-* } } } */ +int main() +{ + static long long x; + if (__alignof__(x) != 8) + __builtin_abort(); + return 0; +} |