On Tue, Jun 23, 2020 at 5:31 PM Sunil K Pandey via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> From: Sunil K Pandey <skpg...@gmail.com>
>
> Default for this hook is NOP. For x86, in 32 bit mode, this hook
> sets alignment of long long on stack to 32 bits if preferred stack
> boundary is 32 bits.
>
>  - This patch fixes
>         gcc.target/i386/pr69454-2.c
>         gcc.target/i386/stackalign/longlong-1.c
>  - Regression test on x86-64, no new fail introduced.
I think the name is badly chosen, TARGET_LOWER_LOCAL_DECL_ALIGNMENT
would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
renamed to INCREASE_LOCAL_DECL_ALIGNMENT).

You're calling it from do_type_align which IMHO is dangerous since that's
invoked from FIELD_DECL layout as well.  Instead invoke it from
layout_decl itself where we do

  if (code != FIELD_DECL)
    /* For non-fields, update the alignment from the type.  */
    do_type_align (type, decl);

and invoke the hook _after_ do_type_align.  Also avoid
invoking the hook on globals or hard regs and only
invoke it on VAR_DECLs, thus only

  if (VAR_P (decl) && !is_global_var (decl) && !DECL_HARD_REGISTER (decl))

Comments on the hook itself below.

> Tested on x86-64.
>
> gcc/ChangeLog:
>
>         PR target/95237
>         * config/i386/i386.c (ix86_update_decl_alignment): New
>         function.
>         (TARGET_UPDATE_DECL_ALIGNMENT): Define.
>         * doc/tm.texi: Regenerate.
>         * doc/tm.texi.in (TARGET_UPDATE_DECL_ALIGNMENT): New hook.
>         * stor-layout.c (do_type_align): Call target hook to update
>         decl alignment.
>         * target.def (update_decl_alignment): New hook.
>
> gcc/testsuite/ChangeLog:
>
>         PR target/95237
>         * gcc.target/i386/pr95237-1.c: New test.
>         * gcc.target/i386/pr95237-2.c: New test.
>         * gcc.target/i386/pr95237-3.c: New test.
>         * gcc.target/i386/pr95237-4.c: New test.
>         * gcc.target/i386/pr95237-5.c: New test.
> ---
>  gcc/config/i386/i386.c                    | 22 ++++++++++++++++++++++
>  gcc/doc/tm.texi                           |  5 +++++
>  gcc/doc/tm.texi.in                        |  2 ++
>  gcc/stor-layout.c                         |  2 ++
>  gcc/target.def                            |  7 +++++++
>  gcc/testsuite/gcc.target/i386/pr95237-1.c | 16 ++++++++++++++++
>  gcc/testsuite/gcc.target/i386/pr95237-2.c | 10 ++++++++++
>  gcc/testsuite/gcc.target/i386/pr95237-3.c | 10 ++++++++++
>  gcc/testsuite/gcc.target/i386/pr95237-4.c | 10 ++++++++++
>  gcc/testsuite/gcc.target/i386/pr95237-5.c | 16 ++++++++++++++++
>  10 files changed, 100 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-1.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-2.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-3.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-4.c
>  create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-5.c
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 37aaa49996d..bcd9abd5303 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -16917,6 +16917,25 @@ ix86_minimum_alignment (tree exp, machine_mode mode,
>
>    return align;
>  }
> +
> +/* Implement TARGET_UPDATE_DECL_ALIGNMENT.  */
> +
> +static void
> +ix86_update_decl_alignment (tree decl)
> +{
> +  tree type = TREE_TYPE (decl);
> +
> +  if (cfun != NULL
> +      && !TARGET_64BIT
> +      && DECL_ALIGN (decl) == 64
> +      && ix86_preferred_stack_boundary < 64
> +      && !is_global_var (decl)
> +      && (DECL_MODE (decl) == E_DImode
> +         || (type && TYPE_MODE (type) == E_DImode))
> +      && (!type || !TYPE_USER_ALIGN (type))
> +      && (!decl || !DECL_USER_ALIGN (decl)))

I'd simply do

       unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
       if (new_align < DECL_ALIGN (decl))
         SET_DECL_ALIGN (decl, new_align);

to avoid spreading the logic to multiple places.

Thanks,
Richard.

> +    SET_DECL_ALIGN (decl, 32);
> +}
>
>  /* Find a location for the static chain incoming to a nested function.
>     This is a register, unless all free registers are used by arguments.  */
> @@ -23519,6 +23538,9 @@ ix86_run_selftests (void)
>  #undef TARGET_CAN_CHANGE_MODE_CLASS
>  #define TARGET_CAN_CHANGE_MODE_CLASS ix86_can_change_mode_class
>
> +#undef TARGET_UPDATE_DECL_ALIGNMENT
> +#define TARGET_UPDATE_DECL_ALIGNMENT ix86_update_decl_alignment
> +
>  #undef TARGET_STATIC_RTX_ALIGNMENT
>  #define TARGET_STATIC_RTX_ALIGNMENT ix86_static_rtx_alignment
>  #undef TARGET_CONSTANT_ALIGNMENT
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index 6e7d9dc54a9..c11ef5dca89 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_UPDATE_DECL_ALIGNMENT (tree @var{decl})
> +Define this hook to update alignment of 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 3be984bbd5c..618acd73a1e 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_UPDATE_DECL_ALIGNMENT
> +
>  @hook TARGET_STATIC_RTX_ALIGNMENT
>
>  @defmac DATA_ALIGNMENT (@var{type}, @var{basic-align})
> diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
> index bde6fa22b58..0687a68ba29 100644
> --- a/gcc/stor-layout.c
> +++ b/gcc/stor-layout.c
> @@ -605,6 +605,8 @@ do_type_align (tree type, tree decl)
>    if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
>      {
>        SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> +      /* Update decl alignment */
> +      targetm.update_decl_alignment (decl);
>        if (TREE_CODE (decl) == FIELD_DECL)
>         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
>      }
> diff --git a/gcc/target.def b/gcc/target.def
> index 07059a87caf..e1695753470 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -3348,6 +3348,13 @@ HOOK_VECTOR_END (addr_space)
>  #undef HOOK_PREFIX
>  #define HOOK_PREFIX "TARGET_"
>
> +DEFHOOK
> +(update_decl_alignment,
> + "Define this hook to update alignment of decl\n\
> +@samp{(@var{decl}}.",
> + void, (tree decl),
> + hook_void_tree)
> +
>  DEFHOOK
>  (static_rtx_alignment,
>   "This hook returns the preferred alignment in bits for a\n\
> diff --git a/gcc/testsuite/gcc.target/i386/pr95237-1.c 
> b/gcc/testsuite/gcc.target/i386/pr95237-1.c
> new file mode 100644
> index 00000000000..bc8a84ee0db
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr95237-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target ia32 } */
> +/* { dg-options "-mpreferred-stack-boundary=2" } */
> +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/gcc.target/i386/pr95237-2.c 
> b/gcc/testsuite/gcc.target/i386/pr95237-2.c
> new file mode 100644
> index 00000000000..82ff777669a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr95237-2.c
> @@ -0,0 +1,10 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target ia32 } */
> +/* { dg-options "-mpreferred-stack-boundary=2" } */
> +long long x;
> +int main()
> +{
> +       if (__alignof__(x) != 8)
> +         __builtin_abort();
> +       return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr95237-3.c 
> b/gcc/testsuite/gcc.target/i386/pr95237-3.c
> new file mode 100644
> index 00000000000..2fb1f630362
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr95237-3.c
> @@ -0,0 +1,10 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target ia32 } */
> +/* { dg-options "-mpreferred-stack-boundary=2" } */
> +int main()
> +{
> +       long long x;
> +       if (__alignof__(x) != 4)
> +         __builtin_abort();
> +       return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr95237-4.c 
> b/gcc/testsuite/gcc.target/i386/pr95237-4.c
> new file mode 100644
> index 00000000000..d52a770d703
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr95237-4.c
> @@ -0,0 +1,10 @@
> +/* { dg-do run } */
> +/* { dg-require-effective-target ia32 } */
> +/* { dg-options "-mpreferred-stack-boundary=4" } */
> +int main()
> +{
> +       long long x;
> +       if (__alignof__(x) != 8)
> +         __builtin_abort();
> +       return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/i386/pr95237-5.c 
> b/gcc/testsuite/gcc.target/i386/pr95237-5.c
> new file mode 100644
> index 00000000000..4d9be06a045
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr95237-5.c
> @@ -0,0 +1,16 @@
> +/* { dg-do compile { target ia32 } } */
> +/* { dg-options "-mpreferred-stack-boundary=2 -Os -w" } */
> +
> +int a;
> +
> +long long
> +b (void)
> +{
> +}
> +
> +void
> +c (void)
> +{
> +  if (b())
> +    a = 1;
> +}
> --
> 2.25.4
>

Reply via email to