public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237]
@ 2020-06-23 15:29 Sunil K Pandey
  2020-06-24  7:30 ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil K Pandey @ 2020-06-23 15:29 UTC (permalink / raw)
  To: gcc-patches; +Cc: hjl.tools, Sunil K Pandey

From: Sunil K Pandey <skpgkp1@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.

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)))
+    SET_DECL_ALIGN (decl, 32);
+}
 \f
 /* 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


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237]
  2020-06-23 15:29 [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237] Sunil K Pandey
@ 2020-06-24  7:30 ` Richard Biener
  2020-06-25  0:52   ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-06-24  7:30 UTC (permalink / raw)
  To: Sunil K Pandey, H. J. Lu; +Cc: GCC Patches, Sunil K Pandey

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 <skpgkp1@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
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237]
  2020-06-24  7:30 ` Richard Biener
@ 2020-06-25  0:52   ` Sunil Pandey
  2020-06-25  8:10     ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-06-25  0:52 UTC (permalink / raw)
  To: Richard Biener; +Cc: Sunil K Pandey, H. J. Lu, GCC Patches

On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> 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 <skpgkp1@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

Yes, I can change the target hook name.

> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).

It seems like LOCAL_DECL_ALIGNMENT macro documentation is incorrect.
It increases as well as decreases alignment based on condition(-m32
-mpreferred-stack-boundary=2)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885

>
> 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))

It seems like decl property is not fully populated at this point call
to is_global_var (decl) on global variable return false.

$ cat foo.c
long long x;
int main()
{
if (__alignof__(x) != 8)
  __builtin_abort();
return 0;
}

Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
    at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
674     do_type_align (type, decl);
Missing separate debuginfos, use: dnf debuginfo-install
gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
zlib-1.2.11-20.fc31.x86_64
(gdb) call debug_tree(decl)
 <var_decl 0x7ffff7ffbb40 x
    type <integer_type 0x7fffea801888 long long int DI
        size <integer_cst 0x7fffea7e8d38 constant 64>
        unit-size <integer_cst 0x7fffea7e8d50 constant 8>
        align:64 warn_if_not_align:0 symtab:0 alias-set -1
canonical-type 0x7fffea801888 precision:64 min <integer_cst
0x7fffea7e8fd8 -9223372036854775808> max <integer_cst 0x7fffea806000
9223372036854775807>
        pointer_to_this <pointer_type 0x7fffea8110a8>>
    DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
<integer_cst 0x7fffea7e8d50 8>
    align:1 warn_if_not_align:0>

(gdb) p is_global_var(decl)
$1 = false
(gdb)


What about calling hook here

 603 do_type_align (tree type, tree decl)
 604 {
 605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
 606     {
 607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
 608       if (TREE_CODE (decl) == FIELD_DECL)
 609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
 610       else
 611         /* Lower local decl alignment */
 612         if (VAR_P (decl)
 613             && !is_global_var (decl)
 614             && !DECL_HARD_REGISTER (decl)
 615             && cfun != NULL)
 616           targetm.lower_local_decl_alignment (decl);
 617     }

>
> 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.

Sure, I will incorporate this.

>
> 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
> >

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237]
  2020-06-25  0:52   ` Sunil Pandey
@ 2020-06-25  8:10     ` Richard Biener
  2020-06-26 20:11       ` [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237] H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-06-25  8:10 UTC (permalink / raw)
  To: Sunil Pandey, Joseph S. Myers; +Cc: Sunil K Pandey, H. J. Lu, GCC Patches

On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>
> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > 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 <skpgkp1@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
>
> Yes, I can change the target hook name.
>
> > would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
> > renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
>
> It seems like LOCAL_DECL_ALIGNMENT macro documentation is incorrect.
> It increases as well as decreases alignment based on condition(-m32
> -mpreferred-stack-boundary=2)
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
>
> >
> > 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))
>
> It seems like decl property is not fully populated at this point call
> to is_global_var (decl) on global variable return false.
>
> $ cat foo.c
> long long x;
> int main()
> {
> if (__alignof__(x) != 8)
>   __builtin_abort();
> return 0;
> }
>
> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
>     at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> 674     do_type_align (type, decl);
> Missing separate debuginfos, use: dnf debuginfo-install
> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> zlib-1.2.11-20.fc31.x86_64
> (gdb) call debug_tree(decl)
>  <var_decl 0x7ffff7ffbb40 x
>     type <integer_type 0x7fffea801888 long long int DI
>         size <integer_cst 0x7fffea7e8d38 constant 64>
>         unit-size <integer_cst 0x7fffea7e8d50 constant 8>
>         align:64 warn_if_not_align:0 symtab:0 alias-set -1
> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst 0x7fffea806000
> 9223372036854775807>
>         pointer_to_this <pointer_type 0x7fffea8110a8>>
>     DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> <integer_cst 0x7fffea7e8d50 8>
>     align:1 warn_if_not_align:0>
>
> (gdb) p is_global_var(decl)
> $1 = false
> (gdb)
>
>
> What about calling hook here
>
>  603 do_type_align (tree type, tree decl)
>  604 {
>  605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
>  606     {
>  607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
>  608       if (TREE_CODE (decl) == FIELD_DECL)
>  609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
>  610       else
>  611         /* Lower local decl alignment */
>  612         if (VAR_P (decl)
>  613             && !is_global_var (decl)
>  614             && !DECL_HARD_REGISTER (decl)
>  615             && cfun != NULL)
>  616           targetm.lower_local_decl_alignment (decl);
>  617     }

But that doesn't change anything (obviously).  layout_decl
is called quite early, too early it looks like.

Now there doesn't seem to be any other good place where
we are sure to catch the decl before we evaluate things
like __alignof__

void __attribute__((noipa))
foo (__SIZE_TYPE__ align, long long *p)
{
  if ((__SIZE_TYPE__)p & (align-1))
    __builtin_abort ();
}
int main()
{
  long long y;
  foo (_Alignof y, &y);
  return 0;
}

Joseph/Jason - do you have a good recommendation
how to deal with targets where natural alignment
is supposed to be lowered for optimization purposes?
(this case is for i?86 to avoid dynamic stack re-alignment
to align long long to 8 bytes with -mpreferred-stack-boundary=2)

I note that for -mincoming-stack-boundary=2 we do perform
dynamic stack re-alignment already.

I can't find a suitable existing target macro/hook for this,
but my gut feeling is that the default alignment should
instead be the lower one and instead the alignment for
globals should be raised as optimization?

Thanks,
Richard.

> >
> > 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.
>
> Sure, I will incorporate this.
>
> >
> > 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
> > >

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-06-25  8:10     ` Richard Biener
@ 2020-06-26 20:11       ` H.J. Lu
  2020-06-29  9:00         ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-06-26 20:11 UTC (permalink / raw)
  To: Richard Biener; +Cc: Sunil Pandey, Joseph S. Myers, Sunil K Pandey, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 5074 bytes --]

On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> >
> > On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > <richard.guenther@gmail.com> wrote:
> > >
> > > 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 <skpgkp1@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
> >
> > Yes, I can change the target hook name.
> >
> > > would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
> > > renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> >
> > It seems like LOCAL_DECL_ALIGNMENT macro documentation is incorrect.
> > It increases as well as decreases alignment based on condition(-m32
> > -mpreferred-stack-boundary=2)
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> >
> > >
> > > 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))
> >
> > It seems like decl property is not fully populated at this point call
> > to is_global_var (decl) on global variable return false.
> >
> > $ cat foo.c
> > long long x;
> > int main()
> > {
> > if (__alignof__(x) != 8)
> >   __builtin_abort();
> > return 0;
> > }
> >
> > Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> >     at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > 674     do_type_align (type, decl);
> > Missing separate debuginfos, use: dnf debuginfo-install
> > gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > zlib-1.2.11-20.fc31.x86_64
> > (gdb) call debug_tree(decl)
> >  <var_decl 0x7ffff7ffbb40 x
> >     type <integer_type 0x7fffea801888 long long int DI
> >         size <integer_cst 0x7fffea7e8d38 constant 64>
> >         unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> >         align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst 0x7fffea806000
> > 9223372036854775807>
> >         pointer_to_this <pointer_type 0x7fffea8110a8>>
> >     DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > <integer_cst 0x7fffea7e8d50 8>
> >     align:1 warn_if_not_align:0>
> >
> > (gdb) p is_global_var(decl)
> > $1 = false
> > (gdb)
> >
> >
> > What about calling hook here
> >
> >  603 do_type_align (tree type, tree decl)
> >  604 {
> >  605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> >  606     {
> >  607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> >  608       if (TREE_CODE (decl) == FIELD_DECL)
> >  609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> >  610       else
> >  611         /* Lower local decl alignment */
> >  612         if (VAR_P (decl)
> >  613             && !is_global_var (decl)
> >  614             && !DECL_HARD_REGISTER (decl)
> >  615             && cfun != NULL)
> >  616           targetm.lower_local_decl_alignment (decl);
> >  617     }
>
> But that doesn't change anything (obviously).  layout_decl
> is called quite early, too early it looks like.
>
> Now there doesn't seem to be any other good place where
> we are sure to catch the decl before we evaluate things
> like __alignof__
>
> void __attribute__((noipa))
> foo (__SIZE_TYPE__ align, long long *p)
> {
>   if ((__SIZE_TYPE__)p & (align-1))
>     __builtin_abort ();
> }
> int main()
> {
>   long long y;
>   foo (_Alignof y, &y);
>   return 0;
> }
>
> Joseph/Jason - do you have a good recommendation
> how to deal with targets where natural alignment
> is supposed to be lowered for optimization purposes?
> (this case is for i?86 to avoid dynamic stack re-alignment
> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
>
> I note that for -mincoming-stack-boundary=2 we do perform
> dynamic stack re-alignment already.
>
> I can't find a suitable existing target macro/hook for this,
> but my gut feeling is that the default alignment should
> instead be the lower one and instead the alignment for
> globals should be raised as optimization?
>

Here is the updated patch from Sunil.

-- 
H.J.

[-- Attachment #2: 0001-Add-TARGET_LOWER_LOCAL_DECL_ALIGNMENT-PR95237.patch --]
[-- Type: application/octet-stream, Size: 9515 bytes --]

From d6fcbe8370a04b897273e31585bb932ee398289e Mon Sep 17 00:00:00 2001
From: Sunil K Pandey <skpgkp1@gmail.com>
Date: Thu, 18 Jun 2020 08:40:45 -0700
Subject: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]

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.

Tested on x86-64.

gcc/ChangeLog:

	PR target/95237
	* config/i386/i386.c (ix86_lower_local_decl_alignment): New
	function.
	(TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New
	hook.
	* stor-layout.c (do_type_align): Call target hook to lower
	local decl alignment.
	* target.def (lower_local_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.target/i386/pr95237-6.c: New test.
	* gcc.target/i386/pr95237-7.c: New test.
---
 gcc/config/i386/i386.c                    | 13 ++++++++++++
 gcc/doc/tm.texi                           |  6 ++++++
 gcc/doc/tm.texi.in                        |  2 ++
 gcc/stor-layout.c                         |  6 ++++++
 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 +++++++++++++++
 gcc/testsuite/gcc.target/i386/pr95237-6.c | 24 +++++++++++++++++++++++
 gcc/testsuite/gcc.target/i386/pr95237-7.c | 19 ++++++++++++++++++
 12 files changed, 139 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
 create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-6.c
 create mode 100644 gcc/testsuite/gcc.target/i386/pr95237-7.c

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 37aaa49996d..0eb2930ac74 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16917,6 +16917,16 @@ ix86_minimum_alignment (tree exp, machine_mode mode,
 
   return align;
 }
+
+/* Implement TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
+
+static void
+ix86_lower_local_decl_alignment (tree decl)
+{
+  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
+  if (new_align < DECL_ALIGN (decl))
+    SET_DECL_ALIGN (decl, new_align);
+}
 \f
 /* 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 +23529,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/doc/tm.texi b/gcc/doc/tm.texi
index 6e7d9dc54a9..60421c3cb5a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1086,6 +1086,12 @@ 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 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..d76c85d5800 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/stor-layout.c b/gcc/stor-layout.c
index bde6fa22b58..24c66e68083 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -607,6 +607,12 @@ do_type_align (tree type, tree decl)
       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
       if (TREE_CODE (decl) == FIELD_DECL)
 	DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
+      /* Lower local decl alignment.  */
+      else if (cfun != NULL
+	       && VAR_P (decl)
+	       && !is_global_var (decl)
+	       && !DECL_HARD_REGISTER (decl))
+	targetm.lower_local_decl_alignment (decl);
     }
   if (TYPE_WARN_IF_NOT_ALIGN (type) > DECL_WARN_IF_NOT_ALIGN (decl))
     SET_DECL_WARN_IF_NOT_ALIGN (decl, TYPE_WARN_IF_NOT_ALIGN (type));
diff --git a/gcc/target.def b/gcc/target.def
index 07059a87caf..6efaee62c19 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
+(lower_local_decl_alignment,
+ "Define this hook to lower alignment of local 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;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr95237-6.c b/gcc/testsuite/gcc.target/i386/pr95237-6.c
new file mode 100644
index 00000000000..a1357de2c48
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr95237-6.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+#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/gcc.target/i386/pr95237-7.c b/gcc/testsuite/gcc.target/i386/pr95237-7.c
new file mode 100644
index 00000000000..d612eb4a1f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr95237-7.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-require-effective-target ia32 } */
+/* { dg-options "-mpreferred-stack-boundary=2" } */
+#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;
+}
-- 
2.26.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-06-26 20:11       ` [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237] H.J. Lu
@ 2020-06-29  9:00         ` Richard Biener
  2020-07-03 21:16           ` Jason Merrill
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-06-29  9:00 UTC (permalink / raw)
  To: H.J. Lu
  Cc: Sunil Pandey, Joseph S. Myers, Sunil K Pandey, GCC Patches,
	Jason Merrill

On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>
> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > >
> > > On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > >
> > > > 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 <skpgkp1@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
> > >
> > > Yes, I can change the target hook name.
> > >
> > > > would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
> > > > renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > >
> > > It seems like LOCAL_DECL_ALIGNMENT macro documentation is incorrect.
> > > It increases as well as decreases alignment based on condition(-m32
> > > -mpreferred-stack-boundary=2)
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > >
> > > >
> > > > 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))
> > >
> > > It seems like decl property is not fully populated at this point call
> > > to is_global_var (decl) on global variable return false.
> > >
> > > $ cat foo.c
> > > long long x;
> > > int main()
> > > {
> > > if (__alignof__(x) != 8)
> > >   __builtin_abort();
> > > return 0;
> > > }
> > >
> > > Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > >     at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > > 674     do_type_align (type, decl);
> > > Missing separate debuginfos, use: dnf debuginfo-install
> > > gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > > libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > > zlib-1.2.11-20.fc31.x86_64
> > > (gdb) call debug_tree(decl)
> > >  <var_decl 0x7ffff7ffbb40 x
> > >     type <integer_type 0x7fffea801888 long long int DI
> > >         size <integer_cst 0x7fffea7e8d38 constant 64>
> > >         unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > >         align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > > canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > > 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst 0x7fffea806000
> > > 9223372036854775807>
> > >         pointer_to_this <pointer_type 0x7fffea8110a8>>
> > >     DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > > <integer_cst 0x7fffea7e8d50 8>
> > >     align:1 warn_if_not_align:0>
> > >
> > > (gdb) p is_global_var(decl)
> > > $1 = false
> > > (gdb)
> > >
> > >
> > > What about calling hook here
> > >
> > >  603 do_type_align (tree type, tree decl)
> > >  604 {
> > >  605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > >  606     {
> > >  607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > >  608       if (TREE_CODE (decl) == FIELD_DECL)
> > >  609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > >  610       else
> > >  611         /* Lower local decl alignment */
> > >  612         if (VAR_P (decl)
> > >  613             && !is_global_var (decl)
> > >  614             && !DECL_HARD_REGISTER (decl)
> > >  615             && cfun != NULL)
> > >  616           targetm.lower_local_decl_alignment (decl);
> > >  617     }
> >
> > But that doesn't change anything (obviously).  layout_decl
> > is called quite early, too early it looks like.
> >
> > Now there doesn't seem to be any other good place where
> > we are sure to catch the decl before we evaluate things
> > like __alignof__
> >
> > void __attribute__((noipa))
> > foo (__SIZE_TYPE__ align, long long *p)
> > {
> >   if ((__SIZE_TYPE__)p & (align-1))
> >     __builtin_abort ();
> > }
> > int main()
> > {
> >   long long y;
> >   foo (_Alignof y, &y);
> >   return 0;
> > }
> >
> > Joseph/Jason - do you have a good recommendation
> > how to deal with targets where natural alignment
> > is supposed to be lowered for optimization purposes?
> > (this case is for i?86 to avoid dynamic stack re-alignment
> > to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> >
> > I note that for -mincoming-stack-boundary=2 we do perform
> > dynamic stack re-alignment already.
> >
> > I can't find a suitable existing target macro/hook for this,
> > but my gut feeling is that the default alignment should
> > instead be the lower one and instead the alignment for
> > globals should be raised as optimization?
> >
>
> Here is the updated patch from Sunil.

It does not address the fundamental issue that during
do_type_align the is_global_var predicate is not
reliable.  This means that for

int main()
{
  extern long z;
}

the new hook (with -m32 -mpreferred-stack-boundary=2)
will lower the alignment of 'z' which looks wrong.  During
layout_decl we can unfortunately not distinguish between
locals and globals.  We need to find another spot to adjust
alignment of locals.  For C that might be in finish_decl,
for C++ there's probably another suitable place.  Note
it needs to be a place before the frontends possibly
inspect the alignment of the decl - I hope there's no
self-reflective way of using it like

void foo()
{
  long a[__alignof__(this)];
}

with 'this' refering to the actual declarator.  But you
never know C++ ...

In C++ constexpr evalualtion might also expose alignment
"early" so we really need a frontend solution here.  My
limited C++ fu would come up with sth like

constexpr int a = []() { long x; return __alignof__(x); };

or so.  I guess even local templates might expose alignment?

void foo()
{
  long a;
  template <int> struct X;
  template <> struct X<4> {};
  X<__alignof__(a)> b;
}

and eventually the alignof might be even dependent.

Richard.

> --
> H.J.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-06-29  9:00         ` Richard Biener
@ 2020-07-03 21:16           ` Jason Merrill
  2020-07-04 16:11             ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Jason Merrill @ 2020-07-03 21:16 UTC (permalink / raw)
  To: Richard Biener, H.J. Lu
  Cc: Sunil Pandey, Joseph S. Myers, Sunil K Pandey, GCC Patches

On 6/29/20 5:00 AM, Richard Biener wrote:
> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>>
>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
>> <richard.guenther@gmail.com> wrote:
>>>
>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>>>>
>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
>>>> <richard.guenther@gmail.com> wrote:
>>>>>
>>>>> 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 <skpgkp1@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
>>>>
>>>> Yes, I can change the target hook name.
>>>>
>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to be
>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
>>>>
>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is incorrect.
>>>> It increases as well as decreases alignment based on condition(-m32
>>>> -mpreferred-stack-boundary=2)
>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
>>>>
>>>>>
>>>>> 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))
>>>>
>>>> It seems like decl property is not fully populated at this point call
>>>> to is_global_var (decl) on global variable return false.
>>>>
>>>> $ cat foo.c
>>>> long long x;
>>>> int main()
>>>> {
>>>> if (__alignof__(x) != 8)
>>>>    __builtin_abort();
>>>> return 0;
>>>> }
>>>>
>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
>>>> 674     do_type_align (type, decl);
>>>> Missing separate debuginfos, use: dnf debuginfo-install
>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
>>>> zlib-1.2.11-20.fc31.x86_64
>>>> (gdb) call debug_tree(decl)
>>>>   <var_decl 0x7ffff7ffbb40 x
>>>>      type <integer_type 0x7fffea801888 long long int DI
>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst 0x7fffea806000
>>>> 9223372036854775807>
>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
>>>> <integer_cst 0x7fffea7e8d50 8>
>>>>      align:1 warn_if_not_align:0>
>>>>
>>>> (gdb) p is_global_var(decl)
>>>> $1 = false
>>>> (gdb)
>>>>
>>>>
>>>> What about calling hook here
>>>>
>>>>   603 do_type_align (tree type, tree decl)
>>>>   604 {
>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
>>>>   606     {
>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
>>>>   610       else
>>>>   611         /* Lower local decl alignment */
>>>>   612         if (VAR_P (decl)
>>>>   613             && !is_global_var (decl)
>>>>   614             && !DECL_HARD_REGISTER (decl)
>>>>   615             && cfun != NULL)
>>>>   616           targetm.lower_local_decl_alignment (decl);
>>>>   617     }
>>>
>>> But that doesn't change anything (obviously).  layout_decl
>>> is called quite early, too early it looks like.
>>>
>>> Now there doesn't seem to be any other good place where
>>> we are sure to catch the decl before we evaluate things
>>> like __alignof__
>>>
>>> void __attribute__((noipa))
>>> foo (__SIZE_TYPE__ align, long long *p)
>>> {
>>>    if ((__SIZE_TYPE__)p & (align-1))
>>>      __builtin_abort ();
>>> }
>>> int main()
>>> {
>>>    long long y;
>>>    foo (_Alignof y, &y);
>>>    return 0;
>>> }
>>>
>>> Joseph/Jason - do you have a good recommendation
>>> how to deal with targets where natural alignment
>>> is supposed to be lowered for optimization purposes?
>>> (this case is for i?86 to avoid dynamic stack re-alignment
>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
>>>
>>> I note that for -mincoming-stack-boundary=2 we do perform
>>> dynamic stack re-alignment already.
>>>
>>> I can't find a suitable existing target macro/hook for this,
>>> but my gut feeling is that the default alignment should
>>> instead be the lower one and instead the alignment for
>>> globals should be raised as optimization?
>>>
>>
>> Here is the updated patch from Sunil.
> 
> It does not address the fundamental issue that during
> do_type_align the is_global_var predicate is not
> reliable.  This means that for
> 
> int main()
> {
>    extern long z;
> }
> 
> the new hook (with -m32 -mpreferred-stack-boundary=2)
> will lower the alignment of 'z' which looks wrong.  During
> layout_decl we can unfortunately not distinguish between
> locals and globals.  We need to find another spot to adjust
> alignment of locals.  For C that might be in finish_decl,
> for C++ there's probably another suitable place.

cp_finish_decl could work, but layout_decl seems like the right spot; if 
the problem is that the appropriate flags currently aren't being set in 
time, can't we fix that?

> Note it needs to be a place before the frontends possibly
> inspect the alignment of the decl
> In C++ constexpr evalualtion might also expose alignment
> "early" so we really need a frontend solution here.

Yes, we need to know the alignment right after the declaration.

Jason


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-03 21:16           ` Jason Merrill
@ 2020-07-04 16:11             ` Richard Biener
  2020-07-14 15:37               ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-07-04 16:11 UTC (permalink / raw)
  To: Jason Merrill, H.J. Lu
  Cc: Sunil Pandey, Joseph S. Myers, Sunil K Pandey, GCC Patches

On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
>On 6/29/20 5:00 AM, Richard Biener wrote:
>> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>>>
>>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
>>> <richard.guenther@gmail.com> wrote:
>>>>
>>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
>wrote:
>>>>>
>>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
>>>>> <richard.guenther@gmail.com> wrote:
>>>>>>
>>>>>> 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 <skpgkp1@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
>>>>>
>>>>> Yes, I can change the target hook name.
>>>>>
>>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
>be
>>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
>>>>>
>>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
>incorrect.
>>>>> It increases as well as decreases alignment based on
>condition(-m32
>>>>> -mpreferred-stack-boundary=2)
>>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
>>>>>
>>>>>>
>>>>>> 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))
>>>>>
>>>>> It seems like decl property is not fully populated at this point
>call
>>>>> to is_global_var (decl) on global variable return false.
>>>>>
>>>>> $ cat foo.c
>>>>> long long x;
>>>>> int main()
>>>>> {
>>>>> if (__alignof__(x) != 8)
>>>>>    __builtin_abort();
>>>>> return 0;
>>>>> }
>>>>>
>>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
>>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
>>>>> 674     do_type_align (type, decl);
>>>>> Missing separate debuginfos, use: dnf debuginfo-install
>>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
>>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
>>>>> zlib-1.2.11-20.fc31.x86_64
>>>>> (gdb) call debug_tree(decl)
>>>>>   <var_decl 0x7ffff7ffbb40 x
>>>>>      type <integer_type 0x7fffea801888 long long int DI
>>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
>>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
>>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
>>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
>>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
>0x7fffea806000
>>>>> 9223372036854775807>
>>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
>>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
>>>>> <integer_cst 0x7fffea7e8d50 8>
>>>>>      align:1 warn_if_not_align:0>
>>>>>
>>>>> (gdb) p is_global_var(decl)
>>>>> $1 = false
>>>>> (gdb)
>>>>>
>>>>>
>>>>> What about calling hook here
>>>>>
>>>>>   603 do_type_align (tree type, tree decl)
>>>>>   604 {
>>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
>>>>>   606     {
>>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
>>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
>>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
>>>>>   610       else
>>>>>   611         /* Lower local decl alignment */
>>>>>   612         if (VAR_P (decl)
>>>>>   613             && !is_global_var (decl)
>>>>>   614             && !DECL_HARD_REGISTER (decl)
>>>>>   615             && cfun != NULL)
>>>>>   616           targetm.lower_local_decl_alignment (decl);
>>>>>   617     }
>>>>
>>>> But that doesn't change anything (obviously).  layout_decl
>>>> is called quite early, too early it looks like.
>>>>
>>>> Now there doesn't seem to be any other good place where
>>>> we are sure to catch the decl before we evaluate things
>>>> like __alignof__
>>>>
>>>> void __attribute__((noipa))
>>>> foo (__SIZE_TYPE__ align, long long *p)
>>>> {
>>>>    if ((__SIZE_TYPE__)p & (align-1))
>>>>      __builtin_abort ();
>>>> }
>>>> int main()
>>>> {
>>>>    long long y;
>>>>    foo (_Alignof y, &y);
>>>>    return 0;
>>>> }
>>>>
>>>> Joseph/Jason - do you have a good recommendation
>>>> how to deal with targets where natural alignment
>>>> is supposed to be lowered for optimization purposes?
>>>> (this case is for i?86 to avoid dynamic stack re-alignment
>>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
>>>>
>>>> I note that for -mincoming-stack-boundary=2 we do perform
>>>> dynamic stack re-alignment already.
>>>>
>>>> I can't find a suitable existing target macro/hook for this,
>>>> but my gut feeling is that the default alignment should
>>>> instead be the lower one and instead the alignment for
>>>> globals should be raised as optimization?
>>>>
>>>
>>> Here is the updated patch from Sunil.
>> 
>> It does not address the fundamental issue that during
>> do_type_align the is_global_var predicate is not
>> reliable.  This means that for
>> 
>> int main()
>> {
>>    extern long z;
>> }
>> 
>> the new hook (with -m32 -mpreferred-stack-boundary=2)
>> will lower the alignment of 'z' which looks wrong.  During
>> layout_decl we can unfortunately not distinguish between
>> locals and globals.  We need to find another spot to adjust
>> alignment of locals.  For C that might be in finish_decl,
>> for C++ there's probably another suitable place.
>
>cp_finish_decl could work, but layout_decl seems like the right spot;
>if 
>the problem is that the appropriate flags currently aren't being set in
>
>time, can't we fix that?

The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't. 

>> Note it needs to be a place before the frontends possibly
>> inspect the alignment of the decl
>> In C++ constexpr evalualtion might also expose alignment
>> "early" so we really need a frontend solution here.
>
>Yes, we need to know the alignment right after the declaration.
>
>Jason


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-04 16:11             ` Richard Biener
@ 2020-07-14 15:37               ` Sunil Pandey
  2020-07-17  5:15                 ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-07-14 15:37 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jason Merrill, H.J. Lu, Joseph S. Myers, Sunil K Pandey, GCC Patches

[-- Attachment #1: Type: text/plain, Size: 7384 bytes --]

On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> >On 6/29/20 5:00 AM, Richard Biener wrote:
> >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >>>
> >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> >>> <richard.guenther@gmail.com> wrote:
> >>>>
> >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> >wrote:
> >>>>>
> >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> >>>>> <richard.guenther@gmail.com> wrote:
> >>>>>>
> >>>>>> 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 <skpgkp1@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
> >>>>>
> >>>>> Yes, I can change the target hook name.
> >>>>>
> >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> >be
> >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> >>>>>
> >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> >incorrect.
> >>>>> It increases as well as decreases alignment based on
> >condition(-m32
> >>>>> -mpreferred-stack-boundary=2)
> >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> >>>>>
> >>>>>>
> >>>>>> 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))
> >>>>>
> >>>>> It seems like decl property is not fully populated at this point
> >call
> >>>>> to is_global_var (decl) on global variable return false.
> >>>>>
> >>>>> $ cat foo.c
> >>>>> long long x;
> >>>>> int main()
> >>>>> {
> >>>>> if (__alignof__(x) != 8)
> >>>>>    __builtin_abort();
> >>>>> return 0;
> >>>>> }
> >>>>>
> >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> >>>>> 674     do_type_align (type, decl);
> >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> >>>>> zlib-1.2.11-20.fc31.x86_64
> >>>>> (gdb) call debug_tree(decl)
> >>>>>   <var_decl 0x7ffff7ffbb40 x
> >>>>>      type <integer_type 0x7fffea801888 long long int DI
> >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> >0x7fffea806000
> >>>>> 9223372036854775807>
> >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> >>>>> <integer_cst 0x7fffea7e8d50 8>
> >>>>>      align:1 warn_if_not_align:0>
> >>>>>
> >>>>> (gdb) p is_global_var(decl)
> >>>>> $1 = false
> >>>>> (gdb)
> >>>>>
> >>>>>
> >>>>> What about calling hook here
> >>>>>
> >>>>>   603 do_type_align (tree type, tree decl)
> >>>>>   604 {
> >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> >>>>>   606     {
> >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> >>>>>   610       else
> >>>>>   611         /* Lower local decl alignment */
> >>>>>   612         if (VAR_P (decl)
> >>>>>   613             && !is_global_var (decl)
> >>>>>   614             && !DECL_HARD_REGISTER (decl)
> >>>>>   615             && cfun != NULL)
> >>>>>   616           targetm.lower_local_decl_alignment (decl);
> >>>>>   617     }
> >>>>
> >>>> But that doesn't change anything (obviously).  layout_decl
> >>>> is called quite early, too early it looks like.
> >>>>
> >>>> Now there doesn't seem to be any other good place where
> >>>> we are sure to catch the decl before we evaluate things
> >>>> like __alignof__
> >>>>
> >>>> void __attribute__((noipa))
> >>>> foo (__SIZE_TYPE__ align, long long *p)
> >>>> {
> >>>>    if ((__SIZE_TYPE__)p & (align-1))
> >>>>      __builtin_abort ();
> >>>> }
> >>>> int main()
> >>>> {
> >>>>    long long y;
> >>>>    foo (_Alignof y, &y);
> >>>>    return 0;
> >>>> }
> >>>>
> >>>> Joseph/Jason - do you have a good recommendation
> >>>> how to deal with targets where natural alignment
> >>>> is supposed to be lowered for optimization purposes?
> >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> >>>>
> >>>> I note that for -mincoming-stack-boundary=2 we do perform
> >>>> dynamic stack re-alignment already.
> >>>>
> >>>> I can't find a suitable existing target macro/hook for this,
> >>>> but my gut feeling is that the default alignment should
> >>>> instead be the lower one and instead the alignment for
> >>>> globals should be raised as optimization?
> >>>>
> >>>
> >>> Here is the updated patch from Sunil.
> >>
> >> It does not address the fundamental issue that during
> >> do_type_align the is_global_var predicate is not
> >> reliable.  This means that for
> >>
> >> int main()
> >> {
> >>    extern long z;
> >> }
> >>
> >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> >> will lower the alignment of 'z' which looks wrong.  During
> >> layout_decl we can unfortunately not distinguish between
> >> locals and globals.  We need to find another spot to adjust
> >> alignment of locals.  For C that might be in finish_decl,
> >> for C++ there's probably another suitable place.
> >
> >cp_finish_decl could work, but layout_decl seems like the right spot;
> >if
> >the problem is that the appropriate flags currently aren't being set in
> >
> >time, can't we fix that?
>
> The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.

I added a new function lower_decl_alignment and invoked from
cp_decl_finish/decl_finish. Attached is revised patch.
>
> >> Note it needs to be a place before the frontends possibly
> >> inspect the alignment of the decl
> >> In C++ constexpr evalualtion might also expose alignment
> >> "early" so we really need a frontend solution here.
> >
> >Yes, we need to know the alignment right after the declaration.
> >
> >Jason
>

[-- Attachment #2: pr95237.patch.txt --]
[-- Type: text/plain, Size: 12566 bytes --]

From 95c521f974ee90c47a236164e0f030347936bc2e Mon Sep 17 00:00:00 2001
From: Sunil K Pandey <skpgkp1@gmail.com>
Date: Thu, 18 Jun 2020 08:40:45 -0700
Subject: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]

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.

Tested on x86-64.

gcc/c/ChangeLog:

	* c-decl.c (finish_decl): Call lower_decl_alignment to
	lower local decl alignment.

gcc/ChangeLog:

	* config/i386/i386.c (ix86_lower_local_decl_alignment): New
	function.
	(TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in: TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New
	hook.
	* stor-layout.c (lower_decl_alignment): New function.
	* stor-layout.h (lower_decl_alignment): Declare.
	* target.def (lower_local_decl_alignment): New hook.

gcc/cp/ChangeLog:

	* decl.c (cp_finish_decl): Call lower_decl_alignment to
	lower local decl alignment.

gcc/testsuite/ChangeLog:

	* c-c++-common/pr95237-1.c: New test.
	* c-c++-common/pr95237-2.c: New test.
	* c-c++-common/pr95237-3.c: New test.
	* c-c++-common/pr95237-4.c: New test.
	* c-c++-common/pr95237-5.c: New test.
	* c-c++-common/pr95237-6.c: New test.
	* c-c++-common/pr95237-7.c: New test.
	* c-c++-common/pr95237-8.c: New test.
	* c-c++-common/pr95237-9.c: New test.
---
 gcc/c/c-decl.c                         |  2 ++
 gcc/config/i386/i386.c                 | 13 +++++++++++++
 gcc/cp/decl.c                          |  2 ++
 gcc/doc/tm.texi                        |  5 +++++
 gcc/doc/tm.texi.in                     |  2 ++
 gcc/stor-layout.c                      | 11 +++++++++++
 gcc/stor-layout.h                      |  1 +
 gcc/target.def                         |  7 +++++++
 gcc/testsuite/c-c++-common/pr95237-1.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-2.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-3.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-4.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-5.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-6.c | 24 ++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-7.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-8.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-9.c | 10 ++++++++++
 17 files changed, 168 insertions(+)
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-1.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-2.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-3.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-4.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-5.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-6.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-7.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-8.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-9.c

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 81bd2ee94f0..1ae99e30ed1 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
     }
 
   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+  /* Lower local decl alignment.  */
+  lower_decl_alignment (decl);
 }
 
 /* Given a parsed parameter declaration, decode it into a PARM_DECL.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 5c373c091ce..25706654b3e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16919,6 +16919,16 @@ ix86_minimum_alignment (tree exp, machine_mode mode,
 
   return align;
 }
+
+/* Implement TARGET_LOWER_LOCAL_DECL_ALIGNMENT.  */
+
+static void
+ix86_lower_local_decl_alignment (tree decl)
+{
+  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
+  if (new_align < DECL_ALIGN (decl))
+    SET_DECL_ALIGN (decl, new_align);
+}
 \f
 /* Find a location for the static chain incoming to a nested function.
    This is a register, unless all free registers are used by arguments.  */
@@ -23521,6 +23531,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 60a09e9497a..184ceacf1db 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8008,6 +8008,8 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
     }
 
   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+  /* Lower local decl alignment.  */
+  lower_decl_alignment (decl);
 }
 
 /* For class TYPE return itself or some its bases that contain
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 6e7d9dc54a9..91867280b42 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 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..d76c85d5800 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/stor-layout.c b/gcc/stor-layout.c
index bde6fa22b58..d41aadc4877 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -1137,6 +1137,17 @@ update_alignment_for_field (record_layout_info rli, tree field,
   return desired_align;
 }
 
+/* Lower DECL alignment.  */
+
+void
+lower_decl_alignment (tree decl)
+{
+  if (VAR_P (decl)
+      && !is_global_var (decl)
+      && !DECL_HARD_REGISTER (decl))
+    targetm.lower_local_decl_alignment (decl);
+}
+
 /* Issue a warning if the record alignment, RECORD_ALIGN, is less than
    the field alignment of FIELD or FIELD isn't aligned. */
 
diff --git a/gcc/stor-layout.h b/gcc/stor-layout.h
index 48c89992f53..4650afa19ce 100644
--- a/gcc/stor-layout.h
+++ b/gcc/stor-layout.h
@@ -24,6 +24,7 @@ extern void set_min_and_max_values_for_integral_type (tree, int, signop);
 extern void fixup_signed_type (tree);
 extern unsigned int update_alignment_for_field (record_layout_info, tree,
                                                 unsigned int);
+extern void lower_decl_alignment (tree);
 extern record_layout_info start_record_layout (tree);
 extern tree bit_from_pos (tree, tree);
 extern tree byte_from_pos (tree, tree);
diff --git a/gcc/target.def b/gcc/target.def
index 07059a87caf..6efaee62c19 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
+(lower_local_decl_alignment,
+ "Define this hook to lower alignment of local 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/c-c++-common/pr95237-1.c b/gcc/testsuite/c-c++-common/pr95237-1.c
new file mode 100644
index 00000000000..8947a9fed26
--- /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 00000000000..87949a9e122
--- /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 00000000000..6941b6f154b
--- /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 00000000000..deace53cc26
--- /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 00000000000..9dc5cfcd739
--- /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 00000000000..ce1568fa282
--- /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 00000000000..8410009d00e
--- /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 00000000000..8ba98abafc9
--- /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 00000000000..687517cbc0a
--- /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;
+}
-- 
2.25.4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-14 15:37               ` Sunil Pandey
@ 2020-07-17  5:15                 ` Sunil Pandey
  2020-07-17  8:22                   ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-07-17  5:15 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, H.J. Lu, Jason Merrill, Joseph S. Myers, Sunil K Pandey

Any comment on revised patch? At least,  in finish_decl, decl global
attributes are populated.

On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:

> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com>
> wrote:
> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >>>
> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> > >>> <richard.guenther@gmail.com> wrote:
> > >>>>
> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> > >wrote:
> > >>>>>
> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > >>>>> <richard.guenther@gmail.com> wrote:
> > >>>>>>
> > >>>>>> 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 <skpgkp1@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
> > >>>>>
> > >>>>> Yes, I can change the target hook name.
> > >>>>>
> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> > >be
> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > >>>>>
> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> > >incorrect.
> > >>>>> It increases as well as decreases alignment based on
> > >condition(-m32
> > >>>>> -mpreferred-stack-boundary=2)
> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > >>>>>
> > >>>>>>
> > >>>>>> 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))
> > >>>>>
> > >>>>> It seems like decl property is not fully populated at this point
> > >call
> > >>>>> to is_global_var (decl) on global variable return false.
> > >>>>>
> > >>>>> $ cat foo.c
> > >>>>> long long x;
> > >>>>> int main()
> > >>>>> {
> > >>>>> if (__alignof__(x) != 8)
> > >>>>>    __builtin_abort();
> > >>>>> return 0;
> > >>>>> }
> > >>>>>
> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > >>>>> 674     do_type_align (type, decl);
> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > >>>>> zlib-1.2.11-20.fc31.x86_64
> > >>>>> (gdb) call debug_tree(decl)
> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> > >0x7fffea806000
> > >>>>> 9223372036854775807>
> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> > >>>>>      align:1 warn_if_not_align:0>
> > >>>>>
> > >>>>> (gdb) p is_global_var(decl)
> > >>>>> $1 = false
> > >>>>> (gdb)
> > >>>>>
> > >>>>>
> > >>>>> What about calling hook here
> > >>>>>
> > >>>>>   603 do_type_align (tree type, tree decl)
> > >>>>>   604 {
> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > >>>>>   606     {
> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > >>>>>   610       else
> > >>>>>   611         /* Lower local decl alignment */
> > >>>>>   612         if (VAR_P (decl)
> > >>>>>   613             && !is_global_var (decl)
> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> > >>>>>   615             && cfun != NULL)
> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> > >>>>>   617     }
> > >>>>
> > >>>> But that doesn't change anything (obviously).  layout_decl
> > >>>> is called quite early, too early it looks like.
> > >>>>
> > >>>> Now there doesn't seem to be any other good place where
> > >>>> we are sure to catch the decl before we evaluate things
> > >>>> like __alignof__
> > >>>>
> > >>>> void __attribute__((noipa))
> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> > >>>> {
> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> > >>>>      __builtin_abort ();
> > >>>> }
> > >>>> int main()
> > >>>> {
> > >>>>    long long y;
> > >>>>    foo (_Alignof y, &y);
> > >>>>    return 0;
> > >>>> }
> > >>>>
> > >>>> Joseph/Jason - do you have a good recommendation
> > >>>> how to deal with targets where natural alignment
> > >>>> is supposed to be lowered for optimization purposes?
> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> > >>>>
> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> > >>>> dynamic stack re-alignment already.
> > >>>>
> > >>>> I can't find a suitable existing target macro/hook for this,
> > >>>> but my gut feeling is that the default alignment should
> > >>>> instead be the lower one and instead the alignment for
> > >>>> globals should be raised as optimization?
> > >>>>
> > >>>
> > >>> Here is the updated patch from Sunil.
> > >>
> > >> It does not address the fundamental issue that during
> > >> do_type_align the is_global_var predicate is not
> > >> reliable.  This means that for
> > >>
> > >> int main()
> > >> {
> > >>    extern long z;
> > >> }
> > >>
> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> > >> will lower the alignment of 'z' which looks wrong.  During
> > >> layout_decl we can unfortunately not distinguish between
> > >> locals and globals.  We need to find another spot to adjust
> > >> alignment of locals.  For C that might be in finish_decl,
> > >> for C++ there's probably another suitable place.
> > >
> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> > >if
> > >the problem is that the appropriate flags currently aren't being set in
> > >
> > >time, can't we fix that?
> >
> > The first and usually only call to layout_decl is from build_decl which
> gets nothing more than the type... But yes, I also initially thought that's
> the correct spot but it turns out it isn't.
>
> I added a new function lower_decl_alignment and invoked from
> cp_decl_finish/decl_finish. Attached is revised patch.
> >
> > >> Note it needs to be a place before the frontends possibly
> > >> inspect the alignment of the decl
> > >> In C++ constexpr evalualtion might also expose alignment
> > >> "early" so we really need a frontend solution here.
> > >
> > >Yes, we need to know the alignment right after the declaration.
> > >
> > >Jason
> >
>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-17  5:15                 ` Sunil Pandey
@ 2020-07-17  8:22                   ` Richard Biener
  2020-07-18  5:57                     ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-07-17  8:22 UTC (permalink / raw)
  To: Sunil Pandey
  Cc: GCC Patches, H.J. Lu, Jason Merrill, Joseph S. Myers, Sunil K Pandey

On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>
> Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.

+static void
+ix86_lower_local_decl_alignment (tree decl)
+{
+  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);

please use the macro-expanded call here since we want to amend
ix86_local_alignment to _not_ return a lower alignment when
called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
to ix86_local_alignment).  Can you also amend the patch in this
way?

+  if (new_align < DECL_ALIGN (decl))
+    SET_DECL_ALIGN (decl, new_align);

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 81bd2ee94f0..1ae99e30ed1 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
     }

   invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+  /* Lower local decl alignment.  */
+  lower_decl_alignment (decl);
 }

should come before plugin hook invocation, likewise for the cp_finish_decl case.

+/* Lower DECL alignment.  */
+
+void
+lower_decl_alignment (tree decl)
+{
+  if (VAR_P (decl)
+      && !is_global_var (decl)
+      && !DECL_HARD_REGISTER (decl))
+    targetm.lower_local_decl_alignment (decl);
+}

please avoid this function, it's name sounds too generic and it's not worth
adding a public API for two calls.

Alltogether this should avoid the x86 issue leaving left-overs (your identified
inliner case) as missed optimization [for the linux kernel which appearantly
decided that -mpreferred-stack-boundary=2 is a good ABI to use].

Richard.


> On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>>
>> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
>> <richard.guenther@gmail.com> wrote:
>> >
>> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
>> > >On 6/29/20 5:00 AM, Richard Biener wrote:
>> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
>> > >>>
>> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
>> > >>> <richard.guenther@gmail.com> wrote:
>> > >>>>
>> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
>> > >wrote:
>> > >>>>>
>> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
>> > >>>>> <richard.guenther@gmail.com> wrote:
>> > >>>>>>
>> > >>>>>> 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 <skpgkp1@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
>> > >>>>>
>> > >>>>> Yes, I can change the target hook name.
>> > >>>>>
>> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
>> > >be
>> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
>> > >>>>>
>> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
>> > >incorrect.
>> > >>>>> It increases as well as decreases alignment based on
>> > >condition(-m32
>> > >>>>> -mpreferred-stack-boundary=2)
>> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
>> > >>>>>
>> > >>>>>>
>> > >>>>>> 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))
>> > >>>>>
>> > >>>>> It seems like decl property is not fully populated at this point
>> > >call
>> > >>>>> to is_global_var (decl) on global variable return false.
>> > >>>>>
>> > >>>>> $ cat foo.c
>> > >>>>> long long x;
>> > >>>>> int main()
>> > >>>>> {
>> > >>>>> if (__alignof__(x) != 8)
>> > >>>>>    __builtin_abort();
>> > >>>>> return 0;
>> > >>>>> }
>> > >>>>>
>> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
>> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
>> > >>>>> 674     do_type_align (type, decl);
>> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
>> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
>> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
>> > >>>>> zlib-1.2.11-20.fc31.x86_64
>> > >>>>> (gdb) call debug_tree(decl)
>> > >>>>>   <var_decl 0x7ffff7ffbb40 x
>> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
>> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
>> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
>> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
>> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
>> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
>> > >0x7fffea806000
>> > >>>>> 9223372036854775807>
>> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
>> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
>> > >>>>> <integer_cst 0x7fffea7e8d50 8>
>> > >>>>>      align:1 warn_if_not_align:0>
>> > >>>>>
>> > >>>>> (gdb) p is_global_var(decl)
>> > >>>>> $1 = false
>> > >>>>> (gdb)
>> > >>>>>
>> > >>>>>
>> > >>>>> What about calling hook here
>> > >>>>>
>> > >>>>>   603 do_type_align (tree type, tree decl)
>> > >>>>>   604 {
>> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
>> > >>>>>   606     {
>> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
>> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
>> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
>> > >>>>>   610       else
>> > >>>>>   611         /* Lower local decl alignment */
>> > >>>>>   612         if (VAR_P (decl)
>> > >>>>>   613             && !is_global_var (decl)
>> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
>> > >>>>>   615             && cfun != NULL)
>> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
>> > >>>>>   617     }
>> > >>>>
>> > >>>> But that doesn't change anything (obviously).  layout_decl
>> > >>>> is called quite early, too early it looks like.
>> > >>>>
>> > >>>> Now there doesn't seem to be any other good place where
>> > >>>> we are sure to catch the decl before we evaluate things
>> > >>>> like __alignof__
>> > >>>>
>> > >>>> void __attribute__((noipa))
>> > >>>> foo (__SIZE_TYPE__ align, long long *p)
>> > >>>> {
>> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
>> > >>>>      __builtin_abort ();
>> > >>>> }
>> > >>>> int main()
>> > >>>> {
>> > >>>>    long long y;
>> > >>>>    foo (_Alignof y, &y);
>> > >>>>    return 0;
>> > >>>> }
>> > >>>>
>> > >>>> Joseph/Jason - do you have a good recommendation
>> > >>>> how to deal with targets where natural alignment
>> > >>>> is supposed to be lowered for optimization purposes?
>> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
>> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
>> > >>>>
>> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
>> > >>>> dynamic stack re-alignment already.
>> > >>>>
>> > >>>> I can't find a suitable existing target macro/hook for this,
>> > >>>> but my gut feeling is that the default alignment should
>> > >>>> instead be the lower one and instead the alignment for
>> > >>>> globals should be raised as optimization?
>> > >>>>
>> > >>>
>> > >>> Here is the updated patch from Sunil.
>> > >>
>> > >> It does not address the fundamental issue that during
>> > >> do_type_align the is_global_var predicate is not
>> > >> reliable.  This means that for
>> > >>
>> > >> int main()
>> > >> {
>> > >>    extern long z;
>> > >> }
>> > >>
>> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
>> > >> will lower the alignment of 'z' which looks wrong.  During
>> > >> layout_decl we can unfortunately not distinguish between
>> > >> locals and globals.  We need to find another spot to adjust
>> > >> alignment of locals.  For C that might be in finish_decl,
>> > >> for C++ there's probably another suitable place.
>> > >
>> > >cp_finish_decl could work, but layout_decl seems like the right spot;
>> > >if
>> > >the problem is that the appropriate flags currently aren't being set in
>> > >
>> > >time, can't we fix that?
>> >
>> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
>>
>> I added a new function lower_decl_alignment and invoked from
>> cp_decl_finish/decl_finish. Attached is revised patch.
>> >
>> > >> Note it needs to be a place before the frontends possibly
>> > >> inspect the alignment of the decl
>> > >> In C++ constexpr evalualtion might also expose alignment
>> > >> "early" so we really need a frontend solution here.
>> > >
>> > >Yes, we need to know the alignment right after the declaration.
>> > >
>> > >Jason
>> >

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-17  8:22                   ` Richard Biener
@ 2020-07-18  5:57                     ` Sunil Pandey
  2020-07-20 12:06                       ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-07-18  5:57 UTC (permalink / raw)
  To: Richard Biener
  Cc: GCC Patches, H.J. Lu, Jason Merrill, Joseph S. Myers, Sunil K Pandey

[-- Attachment #1: Type: text/plain, Size: 10244 bytes --]

On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> >
> > Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.
>
> +static void
> +ix86_lower_local_decl_alignment (tree decl)
> +{
> +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
>
> please use the macro-expanded call here since we want to amend
> ix86_local_alignment to _not_ return a lower alignment when
> called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> to ix86_local_alignment).  Can you also amend the patch in this
> way?
>
> +  if (new_align < DECL_ALIGN (decl))
> +    SET_DECL_ALIGN (decl, new_align);
>
> diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> index 81bd2ee94f0..1ae99e30ed1 100644
> --- a/gcc/c/c-decl.c
> +++ b/gcc/c/c-decl.c
> @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
>      }
>
>    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> +  /* Lower local decl alignment.  */
> +  lower_decl_alignment (decl);
>  }
>
> should come before plugin hook invocation, likewise for the cp_finish_decl case.
>
> +/* Lower DECL alignment.  */
> +
> +void
> +lower_decl_alignment (tree decl)
> +{
> +  if (VAR_P (decl)
> +      && !is_global_var (decl)
> +      && !DECL_HARD_REGISTER (decl))
> +    targetm.lower_local_decl_alignment (decl);
> +}
>
> please avoid this function, it's name sounds too generic and it's not worth
> adding a public API for two calls.
>
> Alltogether this should avoid the x86 issue leaving left-overs (your identified
> inliner case) as missed optimization [for the linux kernel which appearantly
> decided that -mpreferred-stack-boundary=2 is a good ABI to use].
>
> Richard.
>
>
Revised patch attached.

> > On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> >>
> >> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> >> <richard.guenther@gmail.com> wrote:
> >> >
> >> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> >> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> >> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> >> > >>>
> >> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> >> > >>> <richard.guenther@gmail.com> wrote:
> >> > >>>>
> >> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> >> > >wrote:
> >> > >>>>>
> >> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> >> > >>>>> <richard.guenther@gmail.com> wrote:
> >> > >>>>>>
> >> > >>>>>> 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 <skpgkp1@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
> >> > >>>>>
> >> > >>>>> Yes, I can change the target hook name.
> >> > >>>>>
> >> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> >> > >be
> >> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> >> > >>>>>
> >> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> >> > >incorrect.
> >> > >>>>> It increases as well as decreases alignment based on
> >> > >condition(-m32
> >> > >>>>> -mpreferred-stack-boundary=2)
> >> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> >> > >>>>>
> >> > >>>>>>
> >> > >>>>>> 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))
> >> > >>>>>
> >> > >>>>> It seems like decl property is not fully populated at this point
> >> > >call
> >> > >>>>> to is_global_var (decl) on global variable return false.
> >> > >>>>>
> >> > >>>>> $ cat foo.c
> >> > >>>>> long long x;
> >> > >>>>> int main()
> >> > >>>>> {
> >> > >>>>> if (__alignof__(x) != 8)
> >> > >>>>>    __builtin_abort();
> >> > >>>>> return 0;
> >> > >>>>> }
> >> > >>>>>
> >> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> >> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> >> > >>>>> 674     do_type_align (type, decl);
> >> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> >> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> >> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> >> > >>>>> zlib-1.2.11-20.fc31.x86_64
> >> > >>>>> (gdb) call debug_tree(decl)
> >> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> >> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> >> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> >> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> >> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> >> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> >> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> >> > >0x7fffea806000
> >> > >>>>> 9223372036854775807>
> >> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> >> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> >> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> >> > >>>>>      align:1 warn_if_not_align:0>
> >> > >>>>>
> >> > >>>>> (gdb) p is_global_var(decl)
> >> > >>>>> $1 = false
> >> > >>>>> (gdb)
> >> > >>>>>
> >> > >>>>>
> >> > >>>>> What about calling hook here
> >> > >>>>>
> >> > >>>>>   603 do_type_align (tree type, tree decl)
> >> > >>>>>   604 {
> >> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> >> > >>>>>   606     {
> >> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> >> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> >> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> >> > >>>>>   610       else
> >> > >>>>>   611         /* Lower local decl alignment */
> >> > >>>>>   612         if (VAR_P (decl)
> >> > >>>>>   613             && !is_global_var (decl)
> >> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> >> > >>>>>   615             && cfun != NULL)
> >> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> >> > >>>>>   617     }
> >> > >>>>
> >> > >>>> But that doesn't change anything (obviously).  layout_decl
> >> > >>>> is called quite early, too early it looks like.
> >> > >>>>
> >> > >>>> Now there doesn't seem to be any other good place where
> >> > >>>> we are sure to catch the decl before we evaluate things
> >> > >>>> like __alignof__
> >> > >>>>
> >> > >>>> void __attribute__((noipa))
> >> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> >> > >>>> {
> >> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> >> > >>>>      __builtin_abort ();
> >> > >>>> }
> >> > >>>> int main()
> >> > >>>> {
> >> > >>>>    long long y;
> >> > >>>>    foo (_Alignof y, &y);
> >> > >>>>    return 0;
> >> > >>>> }
> >> > >>>>
> >> > >>>> Joseph/Jason - do you have a good recommendation
> >> > >>>> how to deal with targets where natural alignment
> >> > >>>> is supposed to be lowered for optimization purposes?
> >> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> >> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> >> > >>>>
> >> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> >> > >>>> dynamic stack re-alignment already.
> >> > >>>>
> >> > >>>> I can't find a suitable existing target macro/hook for this,
> >> > >>>> but my gut feeling is that the default alignment should
> >> > >>>> instead be the lower one and instead the alignment for
> >> > >>>> globals should be raised as optimization?
> >> > >>>>
> >> > >>>
> >> > >>> Here is the updated patch from Sunil.
> >> > >>
> >> > >> It does not address the fundamental issue that during
> >> > >> do_type_align the is_global_var predicate is not
> >> > >> reliable.  This means that for
> >> > >>
> >> > >> int main()
> >> > >> {
> >> > >>    extern long z;
> >> > >> }
> >> > >>
> >> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> >> > >> will lower the alignment of 'z' which looks wrong.  During
> >> > >> layout_decl we can unfortunately not distinguish between
> >> > >> locals and globals.  We need to find another spot to adjust
> >> > >> alignment of locals.  For C that might be in finish_decl,
> >> > >> for C++ there's probably another suitable place.
> >> > >
> >> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> >> > >if
> >> > >the problem is that the appropriate flags currently aren't being set in
> >> > >
> >> > >time, can't we fix that?
> >> >
> >> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
> >>
> >> I added a new function lower_decl_alignment and invoked from
> >> cp_decl_finish/decl_finish. Attached is revised patch.
> >> >
> >> > >> Note it needs to be a place before the frontends possibly
> >> > >> inspect the alignment of the decl
> >> > >> In C++ constexpr evalualtion might also expose alignment
> >> > >> "early" so we really need a frontend solution here.
> >> > >
> >> > >Yes, we need to know the alignment right after the declaration.
> >> > >
> >> > >Jason
> >> >

[-- Attachment #2: pr95237_v1.patch.txt --]
[-- Type: text/plain, Size: 14891 bytes --]

From 4676b7095c7f608b036411dd14fd5bc736208293 Mon Sep 17 00:00:00 2001
From: Sunil K Pandey <skpgkp2@gmail.com>
Date: Fri, 17 Jul 2020 19:42:09 -0700
Subject: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]

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.

Tested on x86-64.

gcc/c/ChangeLog:

	PR target/95237
	* c-decl.c (finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/ChangeLog:

	PR target/95237
	* config/i386/i386-protos.h (ix86_local_alignment): Add
	another function parameter.
	* config/i386/i386.c (ix86_lower_local_decl_alignment): New
	function.
	(ix86_local_alignment): Amend ix86_local_alignment to accept
	another parameter setalign. If setalign is true and new align
	value is lower, it will set decl align to new value. No
	change if setalign false.
	(TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define.
	* config/i386/i386.h (LOCAL_ALIGNMENT): Add another function
	parameter.
	(STACK_SLOT_ALIGNMENT): Add another function parameter.
	(LOCAL_DECL_ALIGNMENT): Add another function parameter.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New
	hook.
	* target.def (lower_local_decl_alignment): New hook.

gcc/cp/ChangeLog:

	PR target/95237
	* decl.c (cp_finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/testsuite/ChangeLog:

	PR target/95237
	* c-c++-common/pr95237-1.c: New test.
	* c-c++-common/pr95237-2.c: New test.
	* c-c++-common/pr95237-3.c: New test.
	* c-c++-common/pr95237-4.c: New test.
	* c-c++-common/pr95237-5.c: New test.
	* c-c++-common/pr95237-6.c: New test.
	* c-c++-common/pr95237-7.c: New test.
	* c-c++-common/pr95237-8.c: New test.
	* c-c++-common/pr95237-9.c: New test.
---
 gcc/c/c-decl.c                         |  7 +++++++
 gcc/config/i386/i386-protos.h          |  2 +-
 gcc/config/i386/i386.c                 | 16 +++++++++++++++-
 gcc/config/i386/i386.h                 |  6 +++---
 gcc/cp/decl.c                          |  7 +++++++
 gcc/doc/tm.texi                        |  5 +++++
 gcc/doc/tm.texi.in                     |  2 ++
 gcc/target.def                         |  7 +++++++
 gcc/testsuite/c-c++-common/pr95237-1.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-2.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-3.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-4.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-5.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-6.c | 24 ++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-7.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-8.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-9.c | 10 ++++++++++
 17 files changed, 172 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-1.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-2.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-3.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-4.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-5.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-6.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-7.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-8.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-9.c

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 81bd2ee94f0..4ee9e02d35d 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));
     }
 
+  /* Lower local decl alignment.  */
+
+  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 7c2ce618f3f..034276ebb99 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);
 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 5c373c091ce..b92193dfaa8 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16768,6 +16768,13 @@ 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)
+{
+  ix86_local_alignment (decl, VOIDmode, DECL_ALIGN (decl), true);
+}
+
 /* 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
@@ -16776,7 +16783,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 setalign)
 {
   tree type, decl;
 
@@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode mode,
       && (!decl || !DECL_USER_ALIGN (decl)))
     align = 32;
 
+  /* Lower decl alignment.  */
+  if (setalign && align < DECL_ALIGN (decl))
+    SET_DECL_ALIGN (decl, 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.  */
@@ -23521,6 +23532,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/config/i386/i386.h b/gcc/config/i386/i386.h
index f4a8f1391fa..a7d4f410a0d 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -994,7 +994,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    data to make it all fit in fewer cache lines.  */
 
 #define LOCAL_ALIGNMENT(TYPE, ALIGN) \
-  ix86_local_alignment ((TYPE), VOIDmode, (ALIGN))
+  ix86_local_alignment ((TYPE), VOIDmode, (ALIGN), false)
 
 /* 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
@@ -1008,7 +1008,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    maximum alignment of all possible modes which the slot may have.  */
 
 #define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \
-  ix86_local_alignment ((TYPE), (MODE), (ALIGN))
+  ix86_local_alignment ((TYPE), (MODE), (ALIGN), false)
 
 /* If defined, a C expression to compute the alignment for a local
    variable DECL.
@@ -1020,7 +1020,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    data to make it all fit in fewer cache lines.  */
 
 #define LOCAL_DECL_ALIGNMENT(DECL) \
-  ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL))
+  ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL), false)
 
 /* If defined, a C expression to compute the minimum required alignment
    for dynamic stack realignment purposes for EXP (a TYPE or DECL),
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6e4d546d55e..67aa7b7602e 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));
     }
 
+  /* Lower local decl alignment.  */
+
+  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 6e7d9dc54a9..1058221842d 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 3be984bbd5c..d76c85d5800 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 07059a87caf..e122d3c32c2 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
+(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\
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 00000000000..8947a9fed26
--- /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 00000000000..87949a9e122
--- /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 00000000000..6941b6f154b
--- /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 00000000000..deace53cc26
--- /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 00000000000..9dc5cfcd739
--- /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 00000000000..ce1568fa282
--- /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 00000000000..8410009d00e
--- /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 00000000000..8ba98abafc9
--- /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 00000000000..687517cbc0a
--- /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;
+}
-- 
2.25.4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-18  5:57                     ` Sunil Pandey
@ 2020-07-20 12:06                       ` Richard Biener
  2020-07-21  5:16                         ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-07-20 12:06 UTC (permalink / raw)
  To: Sunil Pandey, Jakub Jelinek, Jeff Law
  Cc: GCC Patches, H.J. Lu, Sunil K Pandey

On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>
> On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > >
> > > Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.
> >
> > +static void
> > +ix86_lower_local_decl_alignment (tree decl)
> > +{
> > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> >
> > please use the macro-expanded call here since we want to amend
> > ix86_local_alignment to _not_ return a lower alignment when
> > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > to ix86_local_alignment).  Can you also amend the patch in this
> > way?
> >
> > +  if (new_align < DECL_ALIGN (decl))
> > +    SET_DECL_ALIGN (decl, new_align);
> >
> > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > index 81bd2ee94f0..1ae99e30ed1 100644
> > --- a/gcc/c/c-decl.c
> > +++ b/gcc/c/c-decl.c
> > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
> >      }
> >
> >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > +  /* Lower local decl alignment.  */
> > +  lower_decl_alignment (decl);
> >  }
> >
> > should come before plugin hook invocation, likewise for the cp_finish_decl case.
> >
> > +/* Lower DECL alignment.  */
> > +
> > +void
> > +lower_decl_alignment (tree decl)
> > +{
> > +  if (VAR_P (decl)
> > +      && !is_global_var (decl)
> > +      && !DECL_HARD_REGISTER (decl))
> > +    targetm.lower_local_decl_alignment (decl);
> > +}
> >
> > please avoid this function, it's name sounds too generic and it's not worth
> > adding a public API for two calls.
> >
> > Alltogether this should avoid the x86 issue leaving left-overs (your identified
> > inliner case) as missed optimization [for the linux kernel which appearantly
> > decided that -mpreferred-stack-boundary=2 is a good ABI to use].
> >
> > Richard.
> >
> >
> Revised patch attached.

@@ -16776,7 +16783,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 setalign)
 {
   tree type, decl;

@@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode mode,
       && (!decl || !DECL_USER_ALIGN (decl)))
     align = 32;

+  /* Lower decl alignment.  */
+  if (setalign && align < DECL_ALIGN (decl))
+    SET_DECL_ALIGN (decl, 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.  */

sorry for not being clear - the parameter should indicate whether an
alignment lower
than natural alignment is OK to return thus sth like

diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 31757b044c8..19703cbceb9 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16641,7 +16641,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 +16658,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))

I also believe that spill_slot_alignment () should be able to get the
lower alignment
for long long but not get_stack_local_alignment () (both use
STACK_SLOT_ALIGNMENT).
Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem attributes
and alignment.

Otherwise the patch looks reasonable to salvage a misguided optimization for
a non-standard ABI.  If it is sufficient to make the people using that ABI happy
is of course another question.  I'd rather see them stop using it ...

That said, I'm hesitant to be the only one OKing this ugliness but I'd
immediately
OK a patch removing the questionable hunk from ix86_local_alignment ;)

Jakub, Jeff - any opinion?

Richard.

> > > On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > >>
> > >> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> > >> <richard.guenther@gmail.com> wrote:
> > >> >
> > >> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> > >> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> > >> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > >> > >>>
> > >> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> > >> > >>> <richard.guenther@gmail.com> wrote:
> > >> > >>>>
> > >> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> > >> > >wrote:
> > >> > >>>>>
> > >> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > >> > >>>>> <richard.guenther@gmail.com> wrote:
> > >> > >>>>>>
> > >> > >>>>>> 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 <skpgkp1@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
> > >> > >>>>>
> > >> > >>>>> Yes, I can change the target hook name.
> > >> > >>>>>
> > >> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> > >> > >be
> > >> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > >> > >>>>>
> > >> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> > >> > >incorrect.
> > >> > >>>>> It increases as well as decreases alignment based on
> > >> > >condition(-m32
> > >> > >>>>> -mpreferred-stack-boundary=2)
> > >> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > >> > >>>>>
> > >> > >>>>>>
> > >> > >>>>>> 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))
> > >> > >>>>>
> > >> > >>>>> It seems like decl property is not fully populated at this point
> > >> > >call
> > >> > >>>>> to is_global_var (decl) on global variable return false.
> > >> > >>>>>
> > >> > >>>>> $ cat foo.c
> > >> > >>>>> long long x;
> > >> > >>>>> int main()
> > >> > >>>>> {
> > >> > >>>>> if (__alignof__(x) != 8)
> > >> > >>>>>    __builtin_abort();
> > >> > >>>>> return 0;
> > >> > >>>>> }
> > >> > >>>>>
> > >> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > >> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > >> > >>>>> 674     do_type_align (type, decl);
> > >> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> > >> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > >> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > >> > >>>>> zlib-1.2.11-20.fc31.x86_64
> > >> > >>>>> (gdb) call debug_tree(decl)
> > >> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> > >> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> > >> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> > >> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > >> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > >> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > >> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> > >> > >0x7fffea806000
> > >> > >>>>> 9223372036854775807>
> > >> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> > >> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > >> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> > >> > >>>>>      align:1 warn_if_not_align:0>
> > >> > >>>>>
> > >> > >>>>> (gdb) p is_global_var(decl)
> > >> > >>>>> $1 = false
> > >> > >>>>> (gdb)
> > >> > >>>>>
> > >> > >>>>>
> > >> > >>>>> What about calling hook here
> > >> > >>>>>
> > >> > >>>>>   603 do_type_align (tree type, tree decl)
> > >> > >>>>>   604 {
> > >> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > >> > >>>>>   606     {
> > >> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > >> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> > >> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > >> > >>>>>   610       else
> > >> > >>>>>   611         /* Lower local decl alignment */
> > >> > >>>>>   612         if (VAR_P (decl)
> > >> > >>>>>   613             && !is_global_var (decl)
> > >> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> > >> > >>>>>   615             && cfun != NULL)
> > >> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> > >> > >>>>>   617     }
> > >> > >>>>
> > >> > >>>> But that doesn't change anything (obviously).  layout_decl
> > >> > >>>> is called quite early, too early it looks like.
> > >> > >>>>
> > >> > >>>> Now there doesn't seem to be any other good place where
> > >> > >>>> we are sure to catch the decl before we evaluate things
> > >> > >>>> like __alignof__
> > >> > >>>>
> > >> > >>>> void __attribute__((noipa))
> > >> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> > >> > >>>> {
> > >> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> > >> > >>>>      __builtin_abort ();
> > >> > >>>> }
> > >> > >>>> int main()
> > >> > >>>> {
> > >> > >>>>    long long y;
> > >> > >>>>    foo (_Alignof y, &y);
> > >> > >>>>    return 0;
> > >> > >>>> }
> > >> > >>>>
> > >> > >>>> Joseph/Jason - do you have a good recommendation
> > >> > >>>> how to deal with targets where natural alignment
> > >> > >>>> is supposed to be lowered for optimization purposes?
> > >> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> > >> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> > >> > >>>>
> > >> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> > >> > >>>> dynamic stack re-alignment already.
> > >> > >>>>
> > >> > >>>> I can't find a suitable existing target macro/hook for this,
> > >> > >>>> but my gut feeling is that the default alignment should
> > >> > >>>> instead be the lower one and instead the alignment for
> > >> > >>>> globals should be raised as optimization?
> > >> > >>>>
> > >> > >>>
> > >> > >>> Here is the updated patch from Sunil.
> > >> > >>
> > >> > >> It does not address the fundamental issue that during
> > >> > >> do_type_align the is_global_var predicate is not
> > >> > >> reliable.  This means that for
> > >> > >>
> > >> > >> int main()
> > >> > >> {
> > >> > >>    extern long z;
> > >> > >> }
> > >> > >>
> > >> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> > >> > >> will lower the alignment of 'z' which looks wrong.  During
> > >> > >> layout_decl we can unfortunately not distinguish between
> > >> > >> locals and globals.  We need to find another spot to adjust
> > >> > >> alignment of locals.  For C that might be in finish_decl,
> > >> > >> for C++ there's probably another suitable place.
> > >> > >
> > >> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> > >> > >if
> > >> > >the problem is that the appropriate flags currently aren't being set in
> > >> > >
> > >> > >time, can't we fix that?
> > >> >
> > >> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
> > >>
> > >> I added a new function lower_decl_alignment and invoked from
> > >> cp_decl_finish/decl_finish. Attached is revised patch.
> > >> >
> > >> > >> Note it needs to be a place before the frontends possibly
> > >> > >> inspect the alignment of the decl
> > >> > >> In C++ constexpr evalualtion might also expose alignment
> > >> > >> "early" so we really need a frontend solution here.
> > >> > >
> > >> > >Yes, we need to know the alignment right after the declaration.
> > >> > >
> > >> > >Jason
> > >> >

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-20 12:06                       ` Richard Biener
@ 2020-07-21  5:16                         ` Sunil Pandey
  2020-07-21  7:50                           ` Richard Biener
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-07-21  5:16 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jakub Jelinek, Jeff Law, GCC Patches, H.J. Lu, Sunil K Pandey

[-- Attachment #1: Type: text/plain, Size: 13907 bytes --]

On Mon, Jul 20, 2020 at 5:06 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> >
> > On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> > <richard.guenther@gmail.com> wrote:
> > >
> > > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > >
> > > > Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.
> > >
> > > +static void
> > > +ix86_lower_local_decl_alignment (tree decl)
> > > +{
> > > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> > >
> > > please use the macro-expanded call here since we want to amend
> > > ix86_local_alignment to _not_ return a lower alignment when
> > > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > > to ix86_local_alignment).  Can you also amend the patch in this
> > > way?
> > >
> > > +  if (new_align < DECL_ALIGN (decl))
> > > +    SET_DECL_ALIGN (decl, new_align);
> > >
> > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > > index 81bd2ee94f0..1ae99e30ed1 100644
> > > --- a/gcc/c/c-decl.c
> > > +++ b/gcc/c/c-decl.c
> > > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
> > >      }
> > >
> > >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > > +  /* Lower local decl alignment.  */
> > > +  lower_decl_alignment (decl);
> > >  }
> > >
> > > should come before plugin hook invocation, likewise for the cp_finish_decl case.
> > >
> > > +/* Lower DECL alignment.  */
> > > +
> > > +void
> > > +lower_decl_alignment (tree decl)
> > > +{
> > > +  if (VAR_P (decl)
> > > +      && !is_global_var (decl)
> > > +      && !DECL_HARD_REGISTER (decl))
> > > +    targetm.lower_local_decl_alignment (decl);
> > > +}
> > >
> > > please avoid this function, it's name sounds too generic and it's not worth
> > > adding a public API for two calls.
> > >
> > > Alltogether this should avoid the x86 issue leaving left-overs (your identified
> > > inliner case) as missed optimization [for the linux kernel which appearantly
> > > decided that -mpreferred-stack-boundary=2 is a good ABI to use].
> > >
> > > Richard.
> > >
> > >
> > Revised patch attached.
>
> @@ -16776,7 +16783,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 setalign)
>  {
>    tree type, decl;
>
> @@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode mode,
>        && (!decl || !DECL_USER_ALIGN (decl)))
>      align = 32;
>
> +  /* Lower decl alignment.  */
> +  if (setalign && align < DECL_ALIGN (decl))
> +    SET_DECL_ALIGN (decl, 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.  */
>
> sorry for not being clear - the parameter should indicate whether an
> alignment lower
> than natural alignment is OK to return thus sth like
>
> diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> index 31757b044c8..19703cbceb9 100644
> --- a/gcc/config/i386/i386.c
> +++ b/gcc/config/i386/i386.c
> @@ -16641,7 +16641,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 +16658,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))
>
> I also believe that spill_slot_alignment () should be able to get the
> lower alignment
> for long long but not get_stack_local_alignment () (both use
> STACK_SLOT_ALIGNMENT).
> Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem attributes
> and alignment.
>
> Otherwise the patch looks reasonable to salvage a misguided optimization for
> a non-standard ABI.  If it is sufficient to make the people using that ABI happy
> is of course another question.  I'd rather see them stop using it ...
>
> That said, I'm hesitant to be the only one OKing this ugliness but I'd
> immediately
> OK a patch removing the questionable hunk from ix86_local_alignment ;)
>
> Jakub, Jeff - any opinion?
>
> Richard.
>

Revised patch attached.

> > > > On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > >>
> > > >> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> > > >> <richard.guenther@gmail.com> wrote:
> > > >> >
> > > >> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> > > >> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> > > >> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > >> > >>>
> > > >> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> > > >> > >>> <richard.guenther@gmail.com> wrote:
> > > >> > >>>>
> > > >> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> > > >> > >wrote:
> > > >> > >>>>>
> > > >> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > > >> > >>>>> <richard.guenther@gmail.com> wrote:
> > > >> > >>>>>>
> > > >> > >>>>>> 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 <skpgkp1@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
> > > >> > >>>>>
> > > >> > >>>>> Yes, I can change the target hook name.
> > > >> > >>>>>
> > > >> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> > > >> > >be
> > > >> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > > >> > >>>>>
> > > >> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> > > >> > >incorrect.
> > > >> > >>>>> It increases as well as decreases alignment based on
> > > >> > >condition(-m32
> > > >> > >>>>> -mpreferred-stack-boundary=2)
> > > >> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > > >> > >>>>>
> > > >> > >>>>>>
> > > >> > >>>>>> 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))
> > > >> > >>>>>
> > > >> > >>>>> It seems like decl property is not fully populated at this point
> > > >> > >call
> > > >> > >>>>> to is_global_var (decl) on global variable return false.
> > > >> > >>>>>
> > > >> > >>>>> $ cat foo.c
> > > >> > >>>>> long long x;
> > > >> > >>>>> int main()
> > > >> > >>>>> {
> > > >> > >>>>> if (__alignof__(x) != 8)
> > > >> > >>>>>    __builtin_abort();
> > > >> > >>>>> return 0;
> > > >> > >>>>> }
> > > >> > >>>>>
> > > >> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > > >> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > > >> > >>>>> 674     do_type_align (type, decl);
> > > >> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> > > >> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > > >> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > > >> > >>>>> zlib-1.2.11-20.fc31.x86_64
> > > >> > >>>>> (gdb) call debug_tree(decl)
> > > >> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> > > >> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> > > >> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> > > >> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > > >> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > > >> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > > >> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> > > >> > >0x7fffea806000
> > > >> > >>>>> 9223372036854775807>
> > > >> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> > > >> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > > >> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> > > >> > >>>>>      align:1 warn_if_not_align:0>
> > > >> > >>>>>
> > > >> > >>>>> (gdb) p is_global_var(decl)
> > > >> > >>>>> $1 = false
> > > >> > >>>>> (gdb)
> > > >> > >>>>>
> > > >> > >>>>>
> > > >> > >>>>> What about calling hook here
> > > >> > >>>>>
> > > >> > >>>>>   603 do_type_align (tree type, tree decl)
> > > >> > >>>>>   604 {
> > > >> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > > >> > >>>>>   606     {
> > > >> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > > >> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> > > >> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > > >> > >>>>>   610       else
> > > >> > >>>>>   611         /* Lower local decl alignment */
> > > >> > >>>>>   612         if (VAR_P (decl)
> > > >> > >>>>>   613             && !is_global_var (decl)
> > > >> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> > > >> > >>>>>   615             && cfun != NULL)
> > > >> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> > > >> > >>>>>   617     }
> > > >> > >>>>
> > > >> > >>>> But that doesn't change anything (obviously).  layout_decl
> > > >> > >>>> is called quite early, too early it looks like.
> > > >> > >>>>
> > > >> > >>>> Now there doesn't seem to be any other good place where
> > > >> > >>>> we are sure to catch the decl before we evaluate things
> > > >> > >>>> like __alignof__
> > > >> > >>>>
> > > >> > >>>> void __attribute__((noipa))
> > > >> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> > > >> > >>>> {
> > > >> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> > > >> > >>>>      __builtin_abort ();
> > > >> > >>>> }
> > > >> > >>>> int main()
> > > >> > >>>> {
> > > >> > >>>>    long long y;
> > > >> > >>>>    foo (_Alignof y, &y);
> > > >> > >>>>    return 0;
> > > >> > >>>> }
> > > >> > >>>>
> > > >> > >>>> Joseph/Jason - do you have a good recommendation
> > > >> > >>>> how to deal with targets where natural alignment
> > > >> > >>>> is supposed to be lowered for optimization purposes?
> > > >> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> > > >> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> > > >> > >>>>
> > > >> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> > > >> > >>>> dynamic stack re-alignment already.
> > > >> > >>>>
> > > >> > >>>> I can't find a suitable existing target macro/hook for this,
> > > >> > >>>> but my gut feeling is that the default alignment should
> > > >> > >>>> instead be the lower one and instead the alignment for
> > > >> > >>>> globals should be raised as optimization?
> > > >> > >>>>
> > > >> > >>>
> > > >> > >>> Here is the updated patch from Sunil.
> > > >> > >>
> > > >> > >> It does not address the fundamental issue that during
> > > >> > >> do_type_align the is_global_var predicate is not
> > > >> > >> reliable.  This means that for
> > > >> > >>
> > > >> > >> int main()
> > > >> > >> {
> > > >> > >>    extern long z;
> > > >> > >> }
> > > >> > >>
> > > >> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> > > >> > >> will lower the alignment of 'z' which looks wrong.  During
> > > >> > >> layout_decl we can unfortunately not distinguish between
> > > >> > >> locals and globals.  We need to find another spot to adjust
> > > >> > >> alignment of locals.  For C that might be in finish_decl,
> > > >> > >> for C++ there's probably another suitable place.
> > > >> > >
> > > >> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> > > >> > >if
> > > >> > >the problem is that the appropriate flags currently aren't being set in
> > > >> > >
> > > >> > >time, can't we fix that?
> > > >> >
> > > >> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
> > > >>
> > > >> I added a new function lower_decl_alignment and invoked from
> > > >> cp_decl_finish/decl_finish. Attached is revised patch.
> > > >> >
> > > >> > >> Note it needs to be a place before the frontends possibly
> > > >> > >> inspect the alignment of the decl
> > > >> > >> In C++ constexpr evalualtion might also expose alignment
> > > >> > >> "early" so we really need a frontend solution here.
> > > >> > >
> > > >> > >Yes, we need to know the alignment right after the declaration.
> > > >> > >
> > > >> > >Jason
> > > >> >

[-- Attachment #2: pr95237_v2.patch.txt --]
[-- Type: text/plain, Size: 15039 bytes --]

From 20ecd6e4494d2d224ae3032444c945aadb757765 Mon Sep 17 00:00:00 2001
From: Sunil K Pandey <skpgkp2@gmail.com>
Date: Fri, 17 Jul 2020 19:42:09 -0700
Subject: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]

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.

Tested on x86-64.

gcc/c/ChangeLog:

	PR target/95237
	* c-decl.c (finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/ChangeLog:

	PR target/95237
	* config/i386/i386-protos.h (ix86_local_alignment): Add
	another function parameter.
	* config/i386/i386.c (ix86_lower_local_decl_alignment): New
	function.
	(ix86_local_alignment): Amend ix86_local_alignment to accept
	another parameter may_lower. If may_lower is true, new align
	may be lower than incoming alignment. If may_lower is false,
	new align will be greater or equal to incoming alignment.
	(TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define.
	* config/i386/i386.h (LOCAL_ALIGNMENT): Add another function
	parameter.
	(STACK_SLOT_ALIGNMENT): Add another function parameter.
	(LOCAL_DECL_ALIGNMENT): Add another function parameter.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New
	hook.
	* target.def (lower_local_decl_alignment): New hook.

gcc/cp/ChangeLog:

	PR target/95237
	* decl.c (cp_finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/testsuite/ChangeLog:

	PR target/95237
	* c-c++-common/pr95237-1.c: New test.
	* c-c++-common/pr95237-2.c: New test.
	* c-c++-common/pr95237-3.c: New test.
	* c-c++-common/pr95237-4.c: New test.
	* c-c++-common/pr95237-5.c: New test.
	* c-c++-common/pr95237-6.c: New test.
	* c-c++-common/pr95237-7.c: New test.
	* c-c++-common/pr95237-8.c: New test.
	* c-c++-common/pr95237-9.c: New test.
---
 gcc/c/c-decl.c                         |  7 +++++++
 gcc/config/i386/i386-protos.h          |  2 +-
 gcc/config/i386/i386.c                 | 19 +++++++++++++++++--
 gcc/config/i386/i386.h                 |  6 +++---
 gcc/cp/decl.c                          |  7 +++++++
 gcc/doc/tm.texi                        |  5 +++++
 gcc/doc/tm.texi.in                     |  2 ++
 gcc/target.def                         |  7 +++++++
 gcc/testsuite/c-c++-common/pr95237-1.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-2.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-3.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-4.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-5.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-6.c | 24 ++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-7.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-8.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-9.c | 10 ++++++++++
 17 files changed, 174 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-1.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-2.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-3.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-4.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-5.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-6.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-7.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-8.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-9.c

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 81bd2ee94f0..4ee9e02d35d 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));
     }
 
+  /* Lower local decl alignment.  */
+
+  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 7c2ce618f3f..034276ebb99 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);
 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 5c373c091ce..6a8f575404e 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16768,6 +16768,17 @@ 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)
+{
+  /* Lower decl alignment.  */
+  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
@@ -16776,7 +16787,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;
 
@@ -16793,7 +16804,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))
@@ -23521,6 +23533,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/config/i386/i386.h b/gcc/config/i386/i386.h
index f4a8f1391fa..23cb6fbf1c6 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -994,7 +994,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    data to make it all fit in fewer cache lines.  */
 
 #define LOCAL_ALIGNMENT(TYPE, ALIGN) \
-  ix86_local_alignment ((TYPE), VOIDmode, (ALIGN))
+  ix86_local_alignment ((TYPE), VOIDmode, (ALIGN), true)
 
 /* 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
@@ -1008,7 +1008,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    maximum alignment of all possible modes which the slot may have.  */
 
 #define STACK_SLOT_ALIGNMENT(TYPE, MODE, ALIGN) \
-  ix86_local_alignment ((TYPE), (MODE), (ALIGN))
+  ix86_local_alignment ((TYPE), (MODE), (ALIGN), true)
 
 /* If defined, a C expression to compute the alignment for a local
    variable DECL.
@@ -1020,7 +1020,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
    data to make it all fit in fewer cache lines.  */
 
 #define LOCAL_DECL_ALIGNMENT(DECL) \
-  ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL))
+  ix86_local_alignment ((DECL), VOIDmode, DECL_ALIGN (DECL), true)
 
 /* If defined, a C expression to compute the minimum required alignment
    for dynamic stack realignment purposes for EXP (a TYPE or DECL),
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6e4d546d55e..67aa7b7602e 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));
     }
 
+  /* Lower local decl alignment.  */
+
+  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 6e7d9dc54a9..1058221842d 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 3be984bbd5c..d76c85d5800 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 07059a87caf..e122d3c32c2 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
+(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\
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 00000000000..8947a9fed26
--- /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 00000000000..87949a9e122
--- /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 00000000000..6941b6f154b
--- /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 00000000000..deace53cc26
--- /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 00000000000..9dc5cfcd739
--- /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 00000000000..ce1568fa282
--- /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 00000000000..8410009d00e
--- /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 00000000000..8ba98abafc9
--- /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 00000000000..687517cbc0a
--- /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;
+}
-- 
2.25.4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-21  5:16                         ` Sunil Pandey
@ 2020-07-21  7:50                           ` Richard Biener
  2020-07-21 23:04                             ` Sunil Pandey
  0 siblings, 1 reply; 18+ messages in thread
From: Richard Biener @ 2020-07-21  7:50 UTC (permalink / raw)
  To: Sunil Pandey
  Cc: Jakub Jelinek, Jeff Law, GCC Patches, H.J. Lu, Sunil K Pandey

On Tue, Jul 21, 2020 at 7:16 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
>
> On Mon, Jul 20, 2020 at 5:06 AM Richard Biener
> <richard.guenther@gmail.com> wrote:
> >
> > On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > >
> > > On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> > > <richard.guenther@gmail.com> wrote:
> > > >
> > > > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > > >
> > > > > Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.
> > > >
> > > > +static void
> > > > +ix86_lower_local_decl_alignment (tree decl)
> > > > +{
> > > > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> > > >
> > > > please use the macro-expanded call here since we want to amend
> > > > ix86_local_alignment to _not_ return a lower alignment when
> > > > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > > > to ix86_local_alignment).  Can you also amend the patch in this
> > > > way?
> > > >
> > > > +  if (new_align < DECL_ALIGN (decl))
> > > > +    SET_DECL_ALIGN (decl, new_align);
> > > >
> > > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > > > index 81bd2ee94f0..1ae99e30ed1 100644
> > > > --- a/gcc/c/c-decl.c
> > > > +++ b/gcc/c/c-decl.c
> > > > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
> > > >      }
> > > >
> > > >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > > > +  /* Lower local decl alignment.  */
> > > > +  lower_decl_alignment (decl);
> > > >  }
> > > >
> > > > should come before plugin hook invocation, likewise for the cp_finish_decl case.
> > > >
> > > > +/* Lower DECL alignment.  */
> > > > +
> > > > +void
> > > > +lower_decl_alignment (tree decl)
> > > > +{
> > > > +  if (VAR_P (decl)
> > > > +      && !is_global_var (decl)
> > > > +      && !DECL_HARD_REGISTER (decl))
> > > > +    targetm.lower_local_decl_alignment (decl);
> > > > +}
> > > >
> > > > please avoid this function, it's name sounds too generic and it's not worth
> > > > adding a public API for two calls.
> > > >
> > > > Alltogether this should avoid the x86 issue leaving left-overs (your identified
> > > > inliner case) as missed optimization [for the linux kernel which appearantly
> > > > decided that -mpreferred-stack-boundary=2 is a good ABI to use].
> > > >
> > > > Richard.
> > > >
> > > >
> > > Revised patch attached.
> >
> > @@ -16776,7 +16783,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 setalign)
> >  {
> >    tree type, decl;
> >
> > @@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode mode,
> >        && (!decl || !DECL_USER_ALIGN (decl)))
> >      align = 32;
> >
> > +  /* Lower decl alignment.  */
> > +  if (setalign && align < DECL_ALIGN (decl))
> > +    SET_DECL_ALIGN (decl, 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.  */
> >
> > sorry for not being clear - the parameter should indicate whether an
> > alignment lower
> > than natural alignment is OK to return thus sth like
> >
> > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > index 31757b044c8..19703cbceb9 100644
> > --- a/gcc/config/i386/i386.c
> > +++ b/gcc/config/i386/i386.c
> > @@ -16641,7 +16641,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 +16658,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))
> >
> > I also believe that spill_slot_alignment () should be able to get the
> > lower alignment
> > for long long but not get_stack_local_alignment () (both use
> > STACK_SLOT_ALIGNMENT).
> > Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem attributes
> > and alignment.
> >
> > Otherwise the patch looks reasonable to salvage a misguided optimization for
> > a non-standard ABI.  If it is sufficient to make the people using that ABI happy
> > is of course another question.  I'd rather see them stop using it ...
> >
> > That said, I'm hesitant to be the only one OKing this ugliness but I'd
> > immediately
> > OK a patch removing the questionable hunk from ix86_local_alignment ;)
> >
> > Jakub, Jeff - any opinion?
> >
> > Richard.
> >
>
> Revised patch attached.

You are now passing 'true' to ix86_local_alignment for all callers,
that's not correct.
I said at most STACK_SLOT_ALIGNMENT _might_ be able to take the lower alignment
but some callers look suspicious so I wasn't sure.

Which means - please pass false for LOCAL_ALIGNMENT, STACK_SLOT_ALIGNMENT
and LOCAL_DECL_ALIGNMENT.

+  /* Lower local decl alignment.  */
+
+  if (VAR_P (decl)
+      && !is_global_var (decl)
+      && !DECL_HARD_REGISTER (decl))
+    targetm.lower_local_decl_alignment (decl);

the comment is quite useless, just repeating what the code does.
Please rephrase it
as

  /* This is the last point we can lower alignment so give the target the
     chance to do so.  */

and remove the vertical space after the comment.

OK with those changes.
Richard.

> > > > > On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > > >>
> > > > >> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> > > > >> <richard.guenther@gmail.com> wrote:
> > > > >> >
> > > > >> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> > > > >> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> > > > >> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > >> > >>>
> > > > >> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> > > > >> > >>> <richard.guenther@gmail.com> wrote:
> > > > >> > >>>>
> > > > >> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> > > > >> > >wrote:
> > > > >> > >>>>>
> > > > >> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > > > >> > >>>>> <richard.guenther@gmail.com> wrote:
> > > > >> > >>>>>>
> > > > >> > >>>>>> 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 <skpgkp1@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
> > > > >> > >>>>>
> > > > >> > >>>>> Yes, I can change the target hook name.
> > > > >> > >>>>>
> > > > >> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> > > > >> > >be
> > > > >> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > > > >> > >>>>>
> > > > >> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> > > > >> > >incorrect.
> > > > >> > >>>>> It increases as well as decreases alignment based on
> > > > >> > >condition(-m32
> > > > >> > >>>>> -mpreferred-stack-boundary=2)
> > > > >> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > > > >> > >>>>>
> > > > >> > >>>>>>
> > > > >> > >>>>>> 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))
> > > > >> > >>>>>
> > > > >> > >>>>> It seems like decl property is not fully populated at this point
> > > > >> > >call
> > > > >> > >>>>> to is_global_var (decl) on global variable return false.
> > > > >> > >>>>>
> > > > >> > >>>>> $ cat foo.c
> > > > >> > >>>>> long long x;
> > > > >> > >>>>> int main()
> > > > >> > >>>>> {
> > > > >> > >>>>> if (__alignof__(x) != 8)
> > > > >> > >>>>>    __builtin_abort();
> > > > >> > >>>>> return 0;
> > > > >> > >>>>> }
> > > > >> > >>>>>
> > > > >> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > > > >> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > > > >> > >>>>> 674     do_type_align (type, decl);
> > > > >> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> > > > >> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > > > >> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > > > >> > >>>>> zlib-1.2.11-20.fc31.x86_64
> > > > >> > >>>>> (gdb) call debug_tree(decl)
> > > > >> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> > > > >> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> > > > >> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> > > > >> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > > > >> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > > > >> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > > > >> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> > > > >> > >0x7fffea806000
> > > > >> > >>>>> 9223372036854775807>
> > > > >> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> > > > >> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > > > >> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> > > > >> > >>>>>      align:1 warn_if_not_align:0>
> > > > >> > >>>>>
> > > > >> > >>>>> (gdb) p is_global_var(decl)
> > > > >> > >>>>> $1 = false
> > > > >> > >>>>> (gdb)
> > > > >> > >>>>>
> > > > >> > >>>>>
> > > > >> > >>>>> What about calling hook here
> > > > >> > >>>>>
> > > > >> > >>>>>   603 do_type_align (tree type, tree decl)
> > > > >> > >>>>>   604 {
> > > > >> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > > > >> > >>>>>   606     {
> > > > >> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > > > >> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> > > > >> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > > > >> > >>>>>   610       else
> > > > >> > >>>>>   611         /* Lower local decl alignment */
> > > > >> > >>>>>   612         if (VAR_P (decl)
> > > > >> > >>>>>   613             && !is_global_var (decl)
> > > > >> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> > > > >> > >>>>>   615             && cfun != NULL)
> > > > >> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> > > > >> > >>>>>   617     }
> > > > >> > >>>>
> > > > >> > >>>> But that doesn't change anything (obviously).  layout_decl
> > > > >> > >>>> is called quite early, too early it looks like.
> > > > >> > >>>>
> > > > >> > >>>> Now there doesn't seem to be any other good place where
> > > > >> > >>>> we are sure to catch the decl before we evaluate things
> > > > >> > >>>> like __alignof__
> > > > >> > >>>>
> > > > >> > >>>> void __attribute__((noipa))
> > > > >> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> > > > >> > >>>> {
> > > > >> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> > > > >> > >>>>      __builtin_abort ();
> > > > >> > >>>> }
> > > > >> > >>>> int main()
> > > > >> > >>>> {
> > > > >> > >>>>    long long y;
> > > > >> > >>>>    foo (_Alignof y, &y);
> > > > >> > >>>>    return 0;
> > > > >> > >>>> }
> > > > >> > >>>>
> > > > >> > >>>> Joseph/Jason - do you have a good recommendation
> > > > >> > >>>> how to deal with targets where natural alignment
> > > > >> > >>>> is supposed to be lowered for optimization purposes?
> > > > >> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> > > > >> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> > > > >> > >>>>
> > > > >> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> > > > >> > >>>> dynamic stack re-alignment already.
> > > > >> > >>>>
> > > > >> > >>>> I can't find a suitable existing target macro/hook for this,
> > > > >> > >>>> but my gut feeling is that the default alignment should
> > > > >> > >>>> instead be the lower one and instead the alignment for
> > > > >> > >>>> globals should be raised as optimization?
> > > > >> > >>>>
> > > > >> > >>>
> > > > >> > >>> Here is the updated patch from Sunil.
> > > > >> > >>
> > > > >> > >> It does not address the fundamental issue that during
> > > > >> > >> do_type_align the is_global_var predicate is not
> > > > >> > >> reliable.  This means that for
> > > > >> > >>
> > > > >> > >> int main()
> > > > >> > >> {
> > > > >> > >>    extern long z;
> > > > >> > >> }
> > > > >> > >>
> > > > >> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> > > > >> > >> will lower the alignment of 'z' which looks wrong.  During
> > > > >> > >> layout_decl we can unfortunately not distinguish between
> > > > >> > >> locals and globals.  We need to find another spot to adjust
> > > > >> > >> alignment of locals.  For C that might be in finish_decl,
> > > > >> > >> for C++ there's probably another suitable place.
> > > > >> > >
> > > > >> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> > > > >> > >if
> > > > >> > >the problem is that the appropriate flags currently aren't being set in
> > > > >> > >
> > > > >> > >time, can't we fix that?
> > > > >> >
> > > > >> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
> > > > >>
> > > > >> I added a new function lower_decl_alignment and invoked from
> > > > >> cp_decl_finish/decl_finish. Attached is revised patch.
> > > > >> >
> > > > >> > >> Note it needs to be a place before the frontends possibly
> > > > >> > >> inspect the alignment of the decl
> > > > >> > >> In C++ constexpr evalualtion might also expose alignment
> > > > >> > >> "early" so we really need a frontend solution here.
> > > > >> > >
> > > > >> > >Yes, we need to know the alignment right after the declaration.
> > > > >> > >
> > > > >> > >Jason
> > > > >> >

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-21  7:50                           ` Richard Biener
@ 2020-07-21 23:04                             ` Sunil Pandey
  2020-07-22 14:24                               ` Dimitar Dimitrov
  0 siblings, 1 reply; 18+ messages in thread
From: Sunil Pandey @ 2020-07-21 23:04 UTC (permalink / raw)
  To: Richard Biener
  Cc: Jakub Jelinek, Jeff Law, GCC Patches, H.J. Lu, Sunil K Pandey

[-- Attachment #1: Type: text/plain, Size: 16291 bytes --]

On Tue, Jul 21, 2020 at 12:50 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On Tue, Jul 21, 2020 at 7:16 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> >
> > On Mon, Jul 20, 2020 at 5:06 AM Richard Biener
> > <richard.guenther@gmail.com> wrote:
> > >
> > > On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > >
> > > > On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> > > > <richard.guenther@gmail.com> wrote:
> > > > >
> > > > > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > > > >
> > > > > > Any comment on revised patch? At least,  in finish_decl, decl global attributes are populated.
> > > > >
> > > > > +static void
> > > > > +ix86_lower_local_decl_alignment (tree decl)
> > > > > +{
> > > > > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> > > > >
> > > > > please use the macro-expanded call here since we want to amend
> > > > > ix86_local_alignment to _not_ return a lower alignment when
> > > > > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > > > > to ix86_local_alignment).  Can you also amend the patch in this
> > > > > way?
> > > > >
> > > > > +  if (new_align < DECL_ALIGN (decl))
> > > > > +    SET_DECL_ALIGN (decl, new_align);
> > > > >
> > > > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > > > > index 81bd2ee94f0..1ae99e30ed1 100644
> > > > > --- a/gcc/c/c-decl.c
> > > > > +++ b/gcc/c/c-decl.c
> > > > > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc, tree init,
> > > > >      }
> > > > >
> > > > >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > > > > +  /* Lower local decl alignment.  */
> > > > > +  lower_decl_alignment (decl);
> > > > >  }
> > > > >
> > > > > should come before plugin hook invocation, likewise for the cp_finish_decl case.
> > > > >
> > > > > +/* Lower DECL alignment.  */
> > > > > +
> > > > > +void
> > > > > +lower_decl_alignment (tree decl)
> > > > > +{
> > > > > +  if (VAR_P (decl)
> > > > > +      && !is_global_var (decl)
> > > > > +      && !DECL_HARD_REGISTER (decl))
> > > > > +    targetm.lower_local_decl_alignment (decl);
> > > > > +}
> > > > >
> > > > > please avoid this function, it's name sounds too generic and it's not worth
> > > > > adding a public API for two calls.
> > > > >
> > > > > Alltogether this should avoid the x86 issue leaving left-overs (your identified
> > > > > inliner case) as missed optimization [for the linux kernel which appearantly
> > > > > decided that -mpreferred-stack-boundary=2 is a good ABI to use].
> > > > >
> > > > > Richard.
> > > > >
> > > > >
> > > > Revised patch attached.
> > >
> > > @@ -16776,7 +16783,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 setalign)
> > >  {
> > >    tree type, decl;
> > >
> > > @@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode mode,
> > >        && (!decl || !DECL_USER_ALIGN (decl)))
> > >      align = 32;
> > >
> > > +  /* Lower decl alignment.  */
> > > +  if (setalign && align < DECL_ALIGN (decl))
> > > +    SET_DECL_ALIGN (decl, 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.  */
> > >
> > > sorry for not being clear - the parameter should indicate whether an
> > > alignment lower
> > > than natural alignment is OK to return thus sth like
> > >
> > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > > index 31757b044c8..19703cbceb9 100644
> > > --- a/gcc/config/i386/i386.c
> > > +++ b/gcc/config/i386/i386.c
> > > @@ -16641,7 +16641,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 +16658,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))
> > >
> > > I also believe that spill_slot_alignment () should be able to get the
> > > lower alignment
> > > for long long but not get_stack_local_alignment () (both use
> > > STACK_SLOT_ALIGNMENT).
> > > Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem attributes
> > > and alignment.
> > >
> > > Otherwise the patch looks reasonable to salvage a misguided optimization for
> > > a non-standard ABI.  If it is sufficient to make the people using that ABI happy
> > > is of course another question.  I'd rather see them stop using it ...
> > >
> > > That said, I'm hesitant to be the only one OKing this ugliness but I'd
> > > immediately
> > > OK a patch removing the questionable hunk from ix86_local_alignment ;)
> > >
> > > Jakub, Jeff - any opinion?
> > >
> > > Richard.
> > >
> >
> > Revised patch attached.
>
> You are now passing 'true' to ix86_local_alignment for all callers,
> that's not correct.
> I said at most STACK_SLOT_ALIGNMENT _might_ be able to take the lower alignment
> but some callers look suspicious so I wasn't sure.
>
> Which means - please pass false for LOCAL_ALIGNMENT, STACK_SLOT_ALIGNMENT
> and LOCAL_DECL_ALIGNMENT.
>
> +  /* Lower local decl alignment.  */
> +
> +  if (VAR_P (decl)
> +      && !is_global_var (decl)
> +      && !DECL_HARD_REGISTER (decl))
> +    targetm.lower_local_decl_alignment (decl);
>
> the comment is quite useless, just repeating what the code does.
> Please rephrase it
> as
>
>   /* This is the last point we can lower alignment so give the target the
>      chance to do so.  */
>
> and remove the vertical space after the comment.
>
> OK with those changes.
> Richard.
>

Updated patch attached. I will ask H.J. to check it in for me.
--Sunil

> > > > > > On Tue, Jul 14, 2020 at 8:37 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > > > >>
> > > > > >> On Sat, Jul 4, 2020 at 9:11 AM Richard Biener
> > > > > >> <richard.guenther@gmail.com> wrote:
> > > > > >> >
> > > > > >> > On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <jason@redhat.com> wrote:
> > > > > >> > >On 6/29/20 5:00 AM, Richard Biener wrote:
> > > > > >> > >> On Fri, Jun 26, 2020 at 10:11 PM H.J. Lu <hjl.tools@gmail.com> wrote:
> > > > > >> > >>>
> > > > > >> > >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener
> > > > > >> > >>> <richard.guenther@gmail.com> wrote:
> > > > > >> > >>>>
> > > > > >> > >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpgkp1@gmail.com>
> > > > > >> > >wrote:
> > > > > >> > >>>>>
> > > > > >> > >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener
> > > > > >> > >>>>> <richard.guenther@gmail.com> wrote:
> > > > > >> > >>>>>>
> > > > > >> > >>>>>> 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 <skpgkp1@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
> > > > > >> > >>>>>
> > > > > >> > >>>>> Yes, I can change the target hook name.
> > > > > >> > >>>>>
> > > > > >> > >>>>>> would be better suited (and then asks for LOCAL_DECL_ALIGNMENT to
> > > > > >> > >be
> > > > > >> > >>>>>> renamed to INCREASE_LOCAL_DECL_ALIGNMENT).
> > > > > >> > >>>>>
> > > > > >> > >>>>> It seems like LOCAL_DECL_ALIGNMENT macro documentation is
> > > > > >> > >incorrect.
> > > > > >> > >>>>> It increases as well as decreases alignment based on
> > > > > >> > >condition(-m32
> > > > > >> > >>>>> -mpreferred-stack-boundary=2)
> > > > > >> > >>>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95885
> > > > > >> > >>>>>
> > > > > >> > >>>>>>
> > > > > >> > >>>>>> 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))
> > > > > >> > >>>>>
> > > > > >> > >>>>> It seems like decl property is not fully populated at this point
> > > > > >> > >call
> > > > > >> > >>>>> to is_global_var (decl) on global variable return false.
> > > > > >> > >>>>>
> > > > > >> > >>>>> $ cat foo.c
> > > > > >> > >>>>> long long x;
> > > > > >> > >>>>> int main()
> > > > > >> > >>>>> {
> > > > > >> > >>>>> if (__alignof__(x) != 8)
> > > > > >> > >>>>>    __builtin_abort();
> > > > > >> > >>>>> return 0;
> > > > > >> > >>>>> }
> > > > > >> > >>>>>
> > > > > >> > >>>>> Breakpoint 1, layout_decl (decl=0x7ffff7ffbb40, known_align=0)
> > > > > >> > >>>>>      at /local/skpandey/gccwork/gccwork/gcc/gcc/stor-layout.c:674
> > > > > >> > >>>>> 674     do_type_align (type, decl);
> > > > > >> > >>>>> Missing separate debuginfos, use: dnf debuginfo-install
> > > > > >> > >>>>> gmp-6.1.2-10.fc31.x86_64 isl-0.16.1-9.fc31.x86_64
> > > > > >> > >>>>> libmpc-1.1.0-4.fc31.x86_64 mpfr-3.1.6-5.fc31.x86_64
> > > > > >> > >>>>> zlib-1.2.11-20.fc31.x86_64
> > > > > >> > >>>>> (gdb) call debug_tree(decl)
> > > > > >> > >>>>>   <var_decl 0x7ffff7ffbb40 x
> > > > > >> > >>>>>      type <integer_type 0x7fffea801888 long long int DI
> > > > > >> > >>>>>          size <integer_cst 0x7fffea7e8d38 constant 64>
> > > > > >> > >>>>>          unit-size <integer_cst 0x7fffea7e8d50 constant 8>
> > > > > >> > >>>>>          align:64 warn_if_not_align:0 symtab:0 alias-set -1
> > > > > >> > >>>>> canonical-type 0x7fffea801888 precision:64 min <integer_cst
> > > > > >> > >>>>> 0x7fffea7e8fd8 -9223372036854775808> max <integer_cst
> > > > > >> > >0x7fffea806000
> > > > > >> > >>>>> 9223372036854775807>
> > > > > >> > >>>>>          pointer_to_this <pointer_type 0x7fffea8110a8>>
> > > > > >> > >>>>>      DI foo.c:1:11 size <integer_cst 0x7fffea7e8d38 64> unit-size
> > > > > >> > >>>>> <integer_cst 0x7fffea7e8d50 8>
> > > > > >> > >>>>>      align:1 warn_if_not_align:0>
> > > > > >> > >>>>>
> > > > > >> > >>>>> (gdb) p is_global_var(decl)
> > > > > >> > >>>>> $1 = false
> > > > > >> > >>>>> (gdb)
> > > > > >> > >>>>>
> > > > > >> > >>>>>
> > > > > >> > >>>>> What about calling hook here
> > > > > >> > >>>>>
> > > > > >> > >>>>>   603 do_type_align (tree type, tree decl)
> > > > > >> > >>>>>   604 {
> > > > > >> > >>>>>   605   if (TYPE_ALIGN (type) > DECL_ALIGN (decl))
> > > > > >> > >>>>>   606     {
> > > > > >> > >>>>>   607       SET_DECL_ALIGN (decl, TYPE_ALIGN (type));
> > > > > >> > >>>>>   608       if (TREE_CODE (decl) == FIELD_DECL)
> > > > > >> > >>>>>   609         DECL_USER_ALIGN (decl) = TYPE_USER_ALIGN (type);
> > > > > >> > >>>>>   610       else
> > > > > >> > >>>>>   611         /* Lower local decl alignment */
> > > > > >> > >>>>>   612         if (VAR_P (decl)
> > > > > >> > >>>>>   613             && !is_global_var (decl)
> > > > > >> > >>>>>   614             && !DECL_HARD_REGISTER (decl)
> > > > > >> > >>>>>   615             && cfun != NULL)
> > > > > >> > >>>>>   616           targetm.lower_local_decl_alignment (decl);
> > > > > >> > >>>>>   617     }
> > > > > >> > >>>>
> > > > > >> > >>>> But that doesn't change anything (obviously).  layout_decl
> > > > > >> > >>>> is called quite early, too early it looks like.
> > > > > >> > >>>>
> > > > > >> > >>>> Now there doesn't seem to be any other good place where
> > > > > >> > >>>> we are sure to catch the decl before we evaluate things
> > > > > >> > >>>> like __alignof__
> > > > > >> > >>>>
> > > > > >> > >>>> void __attribute__((noipa))
> > > > > >> > >>>> foo (__SIZE_TYPE__ align, long long *p)
> > > > > >> > >>>> {
> > > > > >> > >>>>    if ((__SIZE_TYPE__)p & (align-1))
> > > > > >> > >>>>      __builtin_abort ();
> > > > > >> > >>>> }
> > > > > >> > >>>> int main()
> > > > > >> > >>>> {
> > > > > >> > >>>>    long long y;
> > > > > >> > >>>>    foo (_Alignof y, &y);
> > > > > >> > >>>>    return 0;
> > > > > >> > >>>> }
> > > > > >> > >>>>
> > > > > >> > >>>> Joseph/Jason - do you have a good recommendation
> > > > > >> > >>>> how to deal with targets where natural alignment
> > > > > >> > >>>> is supposed to be lowered for optimization purposes?
> > > > > >> > >>>> (this case is for i?86 to avoid dynamic stack re-alignment
> > > > > >> > >>>> to align long long to 8 bytes with -mpreferred-stack-boundary=2)
> > > > > >> > >>>>
> > > > > >> > >>>> I note that for -mincoming-stack-boundary=2 we do perform
> > > > > >> > >>>> dynamic stack re-alignment already.
> > > > > >> > >>>>
> > > > > >> > >>>> I can't find a suitable existing target macro/hook for this,
> > > > > >> > >>>> but my gut feeling is that the default alignment should
> > > > > >> > >>>> instead be the lower one and instead the alignment for
> > > > > >> > >>>> globals should be raised as optimization?
> > > > > >> > >>>>
> > > > > >> > >>>
> > > > > >> > >>> Here is the updated patch from Sunil.
> > > > > >> > >>
> > > > > >> > >> It does not address the fundamental issue that during
> > > > > >> > >> do_type_align the is_global_var predicate is not
> > > > > >> > >> reliable.  This means that for
> > > > > >> > >>
> > > > > >> > >> int main()
> > > > > >> > >> {
> > > > > >> > >>    extern long z;
> > > > > >> > >> }
> > > > > >> > >>
> > > > > >> > >> the new hook (with -m32 -mpreferred-stack-boundary=2)
> > > > > >> > >> will lower the alignment of 'z' which looks wrong.  During
> > > > > >> > >> layout_decl we can unfortunately not distinguish between
> > > > > >> > >> locals and globals.  We need to find another spot to adjust
> > > > > >> > >> alignment of locals.  For C that might be in finish_decl,
> > > > > >> > >> for C++ there's probably another suitable place.
> > > > > >> > >
> > > > > >> > >cp_finish_decl could work, but layout_decl seems like the right spot;
> > > > > >> > >if
> > > > > >> > >the problem is that the appropriate flags currently aren't being set in
> > > > > >> > >
> > > > > >> > >time, can't we fix that?
> > > > > >> >
> > > > > >> > The first and usually only call to layout_decl is from build_decl which gets nothing more than the type... But yes, I also initially thought that's the correct spot but it turns out it isn't.
> > > > > >>
> > > > > >> I added a new function lower_decl_alignment and invoked from
> > > > > >> cp_decl_finish/decl_finish. Attached is revised patch.
> > > > > >> >
> > > > > >> > >> Note it needs to be a place before the frontends possibly
> > > > > >> > >> inspect the alignment of the decl
> > > > > >> > >> In C++ constexpr evalualtion might also expose alignment
> > > > > >> > >> "early" so we really need a frontend solution here.
> > > > > >> > >
> > > > > >> > >Yes, we need to know the alignment right after the declaration.
> > > > > >> > >
> > > > > >> > >Jason
> > > > > >> >

[-- Attachment #2: pr95237_v3.patch.txt --]
[-- Type: text/plain, Size: 13589 bytes --]

From c4f601c0f6ebfa2a417a76aedcfa5fcf112f318d Mon Sep 17 00:00:00 2001
From: Sunil K Pandey <skpgkp2@gmail.com>
Date: Fri, 17 Jul 2020 19:42:09 -0700
Subject: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]

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 prevents lowering of alignment from following macros.
	LOCAL_ALIGNMENT
	STACK_SLOT_ALIGNMENT
	LOCAL_DECL_ALIGNMENT
  - 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.

Tested on x86-64.

gcc/c/ChangeLog:

	PR target/95237
	* c-decl.c (finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/ChangeLog:

	PR target/95237
	* config/i386/i386-protos.h (ix86_local_alignment): Add
	another function parameter may_lower alignment. Default is
	false.
	* config/i386/i386.c (ix86_lower_local_decl_alignment): New
	function.
	(ix86_local_alignment): Amend ix86_local_alignment to accept
	another parameter may_lower. If may_lower is true, new align
	may be lower than incoming alignment. If may_lower is false,
	new align will be greater or equal to incoming alignment.
	(TARGET_LOWER_LOCAL_DECL_ALIGNMENT): Define.
	* doc/tm.texi: Regenerate.
	* doc/tm.texi.in (TARGET_LOWER_LOCAL_DECL_ALIGNMENT): New
	hook.
	* target.def (lower_local_decl_alignment): New hook.

gcc/cp/ChangeLog:

	PR target/95237
	* decl.c (cp_finish_decl): Call target hook
	lower_local_decl_alignment to lower local decl alignment.

gcc/testsuite/ChangeLog:

	PR target/95237
	* c-c++-common/pr95237-1.c: New test.
	* c-c++-common/pr95237-2.c: New test.
	* c-c++-common/pr95237-3.c: New test.
	* c-c++-common/pr95237-4.c: New test.
	* c-c++-common/pr95237-5.c: New test.
	* c-c++-common/pr95237-6.c: New test.
	* c-c++-common/pr95237-7.c: New test.
	* c-c++-common/pr95237-8.c: New test.
	* c-c++-common/pr95237-9.c: New test.
---
 gcc/c/c-decl.c                         |  7 +++++++
 gcc/config/i386/i386-protos.h          |  2 +-
 gcc/config/i386/i386.c                 | 18 ++++++++++++++++--
 gcc/cp/decl.c                          |  7 +++++++
 gcc/doc/tm.texi                        |  5 +++++
 gcc/doc/tm.texi.in                     |  2 ++
 gcc/target.def                         |  7 +++++++
 gcc/testsuite/c-c++-common/pr95237-1.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-2.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-3.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-4.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-5.c | 16 ++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-6.c | 24 ++++++++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-7.c | 19 +++++++++++++++++++
 gcc/testsuite/c-c++-common/pr95237-8.c | 10 ++++++++++
 gcc/testsuite/c-c++-common/pr95237-9.c | 10 ++++++++++
 16 files changed, 170 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-1.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-2.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-3.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-4.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-5.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-6.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-7.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-8.c
 create mode 100644 gcc/testsuite/c-c++-common/pr95237-9.c

diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 81bd2ee94f0..5d6b504fe78 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 7c2ce618f3f..0b95c57b1a0 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 5c373c091ce..45e85dd13de 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -16768,6 +16768,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
@@ -16776,7 +16786,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;
 
@@ -16793,7 +16803,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))
@@ -23521,6 +23532,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 6e4d546d55e..d72abc1a111 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 6e7d9dc54a9..1058221842d 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 3be984bbd5c..d76c85d5800 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 07059a87caf..e122d3c32c2 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
+(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\
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 00000000000..8947a9fed26
--- /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 00000000000..87949a9e122
--- /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 00000000000..6941b6f154b
--- /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 00000000000..deace53cc26
--- /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 00000000000..9dc5cfcd739
--- /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 00000000000..ce1568fa282
--- /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 00000000000..8410009d00e
--- /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 00000000000..8ba98abafc9
--- /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 00000000000..687517cbc0a
--- /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;
+}
-- 
2.25.4


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-21 23:04                             ` Sunil Pandey
@ 2020-07-22 14:24                               ` Dimitar Dimitrov
  2020-07-22 14:37                                 ` H.J. Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Dimitar Dimitrov @ 2020-07-22 14:24 UTC (permalink / raw)
  To: gcc-patches, Sunil Pandey; +Cc: Richard Biener, Jakub Jelinek

On сряда, 22 юли 2020 г. 2:04:35 EEST Sunil Pandey via Gcc-patches wrote:
> On Tue, Jul 21, 2020 at 12:50 AM Richard Biener
> 
> <richard.guenther@gmail.com> wrote:
> > On Tue, Jul 21, 2020 at 7:16 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > On Mon, Jul 20, 2020 at 5:06 AM Richard Biener
> > > 
> > > <richard.guenther@gmail.com> wrote:
> > > > On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com> 
wrote:
> > > > > On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> > > > > 
> > > > > <richard.guenther@gmail.com> wrote:
> > > > > > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com> 
wrote:
> > > > > > > Any comment on revised patch? At least,  in finish_decl, decl
> > > > > > > global attributes are populated.> > > > > 
> > > > > > +static void
> > > > > > +ix86_lower_local_decl_alignment (tree decl)
> > > > > > +{
> > > > > > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> > > > > > 
> > > > > > please use the macro-expanded call here since we want to amend
> > > > > > ix86_local_alignment to _not_ return a lower alignment when
> > > > > > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > > > > > to ix86_local_alignment).  Can you also amend the patch in this
> > > > > > way?
> > > > > > 
> > > > > > +  if (new_align < DECL_ALIGN (decl))
> > > > > > +    SET_DECL_ALIGN (decl, new_align);
> > > > > > 
> > > > > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > > > > > index 81bd2ee94f0..1ae99e30ed1 100644
> > > > > > --- a/gcc/c/c-decl.c
> > > > > > +++ b/gcc/c/c-decl.c
> > > > > > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc,
> > > > > > tree init,> > > > > 
> > > > > >      }
> > > > > >    
> > > > > >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > > > > > 
> > > > > > +  /* Lower local decl alignment.  */
> > > > > > +  lower_decl_alignment (decl);
> > > > > > 
> > > > > >  }
> > > > > > 
> > > > > > should come before plugin hook invocation, likewise for the
> > > > > > cp_finish_decl case.
> > > > > > 
> > > > > > +/* Lower DECL alignment.  */
> > > > > > +
> > > > > > +void
> > > > > > +lower_decl_alignment (tree decl)
> > > > > > +{
> > > > > > +  if (VAR_P (decl)
> > > > > > +      && !is_global_var (decl)
> > > > > > +      && !DECL_HARD_REGISTER (decl))
> > > > > > +    targetm.lower_local_decl_alignment (decl);
> > > > > > +}
> > > > > > 
> > > > > > please avoid this function, it's name sounds too generic and it's
> > > > > > not worth
> > > > > > adding a public API for two calls.
> > > > > > 
> > > > > > Alltogether this should avoid the x86 issue leaving left-overs
> > > > > > (your identified inliner case) as missed optimization [for the
> > > > > > linux kernel which appearantly decided that
> > > > > > -mpreferred-stack-boundary=2 is a good ABI to use].
> > > > > > 
> > > > > > Richard.
> > > > > 
> > > > > Revised patch attached.
> > > > 
> > > > @@ -16776,7 +16783,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 setalign)
> > > > 
> > > >  {
> > > >  
> > > >    tree type, decl;
> > > > 
> > > > @@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode
> > > > mode,
> > > > 
> > > >        && (!decl || !DECL_USER_ALIGN (decl)))
> > > >      
> > > >      align = 32;
> > > > 
> > > > +  /* Lower decl alignment.  */
> > > > +  if (setalign && align < DECL_ALIGN (decl))
> > > > +    SET_DECL_ALIGN (decl, 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.  */
> > > > 
> > > > sorry for not being clear - the parameter should indicate whether an
> > > > alignment lower
> > > > than natural alignment is OK to return thus sth like
> > > > 
> > > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > > > index 31757b044c8..19703cbceb9 100644
> > > > --- a/gcc/config/i386/i386.c
> > > > +++ b/gcc/config/i386/i386.c
> > > > @@ -16641,7 +16641,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 +16658,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))
> > > > 
> > > > I also believe that spill_slot_alignment () should be able to get the
> > > > lower alignment
> > > > for long long but not get_stack_local_alignment () (both use
> > > > STACK_SLOT_ALIGNMENT).
> > > > Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem
> > > > attributes and alignment.
> > > > 
> > > > Otherwise the patch looks reasonable to salvage a misguided
> > > > optimization for a non-standard ABI.  If it is sufficient to make the
> > > > people using that ABI happy is of course another question.  I'd
> > > > rather see them stop using it ...
> > > > 
> > > > That said, I'm hesitant to be the only one OKing this ugliness but I'd
> > > > immediately
> > > > OK a patch removing the questionable hunk from ix86_local_alignment ;)
> > > > 
> > > > Jakub, Jeff - any opinion?
> > > > 
> > > > Richard.
> > > 
> > > Revised patch attached.
> > 
> > You are now passing 'true' to ix86_local_alignment for all callers,
> > that's not correct.
> > I said at most STACK_SLOT_ALIGNMENT _might_ be able to take the lower
> > alignment but some callers look suspicious so I wasn't sure.
> > 
> > Which means - please pass false for LOCAL_ALIGNMENT, STACK_SLOT_ALIGNMENT
> > and LOCAL_DECL_ALIGNMENT.
> > 
> > +  /* Lower local decl alignment.  */
> > +
> > +  if (VAR_P (decl)
> > +      && !is_global_var (decl)
> > +      && !DECL_HARD_REGISTER (decl))
> > +    targetm.lower_local_decl_alignment (decl);
> > 
> > the comment is quite useless, just repeating what the code does.
> > Please rephrase it
> > as
> > 
> >   /* This is the last point we can lower alignment so give the target the
> >   
> >      chance to do so.  */
> > 
> > and remove the vertical space after the comment.
> > 
> > OK with those changes.
> > Richard.
> 
> Updated patch attached. I will ask H.J. to check it in for me.
> --Sunil

Hi Sunil,

I get regressions for PRU and AVR:
  NA->UNRESOLVED: c-c++-common/pr95237-6.c  -std=gnu++14 execution test

Is pr95237-6.c missing an ia32 target filter?

  /* { dg-require-effective-target ia32 } */

If all pr95237-*.c cases require target ia32, then shouldn't they be moved to 
gcc.target/i386/ ?


Regards,
Dimitar




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237]
  2020-07-22 14:24                               ` Dimitar Dimitrov
@ 2020-07-22 14:37                                 ` H.J. Lu
  0 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-07-22 14:37 UTC (permalink / raw)
  To: Dimitar Dimitrov; +Cc: GCC Patches, Sunil Pandey, Jakub Jelinek

[-- Attachment #1: Type: text/plain, Size: 8004 bytes --]

On Wed, Jul 22, 2020 at 7:25 AM Dimitar Dimitrov <dimitar@dinux.eu> wrote:
>
> On сряда, 22 юли 2020 г. 2:04:35 EEST Sunil Pandey via Gcc-patches wrote:
> > On Tue, Jul 21, 2020 at 12:50 AM Richard Biener
> >
> > <richard.guenther@gmail.com> wrote:
> > > On Tue, Jul 21, 2020 at 7:16 AM Sunil Pandey <skpgkp1@gmail.com> wrote:
> > > > On Mon, Jul 20, 2020 at 5:06 AM Richard Biener
> > > >
> > > > <richard.guenther@gmail.com> wrote:
> > > > > On Sat, Jul 18, 2020 at 7:57 AM Sunil Pandey <skpgkp1@gmail.com>
> wrote:
> > > > > > On Fri, Jul 17, 2020 at 1:22 AM Richard Biener
> > > > > >
> > > > > > <richard.guenther@gmail.com> wrote:
> > > > > > > On Fri, Jul 17, 2020 at 7:15 AM Sunil Pandey <skpgkp1@gmail.com>
> wrote:
> > > > > > > > Any comment on revised patch? At least,  in finish_decl, decl
> > > > > > > > global attributes are populated.> > > > >
> > > > > > > +static void
> > > > > > > +ix86_lower_local_decl_alignment (tree decl)
> > > > > > > +{
> > > > > > > +  unsigned new_align = LOCAL_DECL_ALIGNMENT (decl);
> > > > > > >
> > > > > > > please use the macro-expanded call here since we want to amend
> > > > > > > ix86_local_alignment to _not_ return a lower alignment when
> > > > > > > called as LOCAL_DECL_ALIGNMENT (by adding a new parameter
> > > > > > > to ix86_local_alignment).  Can you also amend the patch in this
> > > > > > > way?
> > > > > > >
> > > > > > > +  if (new_align < DECL_ALIGN (decl))
> > > > > > > +    SET_DECL_ALIGN (decl, new_align);
> > > > > > >
> > > > > > > diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> > > > > > > index 81bd2ee94f0..1ae99e30ed1 100644
> > > > > > > --- a/gcc/c/c-decl.c
> > > > > > > +++ b/gcc/c/c-decl.c
> > > > > > > @@ -5601,6 +5601,8 @@ finish_decl (tree decl, location_t init_loc,
> > > > > > > tree init,> > > > >
> > > > > > >      }
> > > > > > >
> > > > > > >    invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
> > > > > > >
> > > > > > > +  /* Lower local decl alignment.  */
> > > > > > > +  lower_decl_alignment (decl);
> > > > > > >
> > > > > > >  }
> > > > > > >
> > > > > > > should come before plugin hook invocation, likewise for the
> > > > > > > cp_finish_decl case.
> > > > > > >
> > > > > > > +/* Lower DECL alignment.  */
> > > > > > > +
> > > > > > > +void
> > > > > > > +lower_decl_alignment (tree decl)
> > > > > > > +{
> > > > > > > +  if (VAR_P (decl)
> > > > > > > +      && !is_global_var (decl)
> > > > > > > +      && !DECL_HARD_REGISTER (decl))
> > > > > > > +    targetm.lower_local_decl_alignment (decl);
> > > > > > > +}
> > > > > > >
> > > > > > > please avoid this function, it's name sounds too generic and it's
> > > > > > > not worth
> > > > > > > adding a public API for two calls.
> > > > > > >
> > > > > > > Alltogether this should avoid the x86 issue leaving left-overs
> > > > > > > (your identified inliner case) as missed optimization [for the
> > > > > > > linux kernel which appearantly decided that
> > > > > > > -mpreferred-stack-boundary=2 is a good ABI to use].
> > > > > > >
> > > > > > > Richard.
> > > > > >
> > > > > > Revised patch attached.
> > > > >
> > > > > @@ -16776,7 +16783,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 setalign)
> > > > >
> > > > >  {
> > > > >
> > > > >    tree type, decl;
> > > > >
> > > > > @@ -16801,6 +16808,10 @@ ix86_local_alignment (tree exp, machine_mode
> > > > > mode,
> > > > >
> > > > >        && (!decl || !DECL_USER_ALIGN (decl)))
> > > > >
> > > > >      align = 32;
> > > > >
> > > > > +  /* Lower decl alignment.  */
> > > > > +  if (setalign && align < DECL_ALIGN (decl))
> > > > > +    SET_DECL_ALIGN (decl, 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.  */
> > > > >
> > > > > sorry for not being clear - the parameter should indicate whether an
> > > > > alignment lower
> > > > > than natural alignment is OK to return thus sth like
> > > > >
> > > > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
> > > > > index 31757b044c8..19703cbceb9 100644
> > > > > --- a/gcc/config/i386/i386.c
> > > > > +++ b/gcc/config/i386/i386.c
> > > > > @@ -16641,7 +16641,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 +16658,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))
> > > > >
> > > > > I also believe that spill_slot_alignment () should be able to get the
> > > > > lower alignment
> > > > > for long long but not get_stack_local_alignment () (both use
> > > > > STACK_SLOT_ALIGNMENT).
> > > > > Some uses of STACK_SLOT_ALIGNMENT also look fishy with respect to mem
> > > > > attributes and alignment.
> > > > >
> > > > > Otherwise the patch looks reasonable to salvage a misguided
> > > > > optimization for a non-standard ABI.  If it is sufficient to make the
> > > > > people using that ABI happy is of course another question.  I'd
> > > > > rather see them stop using it ...
> > > > >
> > > > > That said, I'm hesitant to be the only one OKing this ugliness but I'd
> > > > > immediately
> > > > > OK a patch removing the questionable hunk from ix86_local_alignment ;)
> > > > >
> > > > > Jakub, Jeff - any opinion?
> > > > >
> > > > > Richard.
> > > >
> > > > Revised patch attached.
> > >
> > > You are now passing 'true' to ix86_local_alignment for all callers,
> > > that's not correct.
> > > I said at most STACK_SLOT_ALIGNMENT _might_ be able to take the lower
> > > alignment but some callers look suspicious so I wasn't sure.
> > >
> > > Which means - please pass false for LOCAL_ALIGNMENT, STACK_SLOT_ALIGNMENT
> > > and LOCAL_DECL_ALIGNMENT.
> > >
> > > +  /* Lower local decl alignment.  */
> > > +
> > > +  if (VAR_P (decl)
> > > +      && !is_global_var (decl)
> > > +      && !DECL_HARD_REGISTER (decl))
> > > +    targetm.lower_local_decl_alignment (decl);
> > >
> > > the comment is quite useless, just repeating what the code does.
> > > Please rephrase it
> > > as
> > >
> > >   /* This is the last point we can lower alignment so give the target the
> > >
> > >      chance to do so.  */
> > >
> > > and remove the vertical space after the comment.
> > >
> > > OK with those changes.
> > > Richard.
> >
> > Updated patch attached. I will ask H.J. to check it in for me.
> > --Sunil
>
> Hi Sunil,
>
> I get regressions for PRU and AVR:
>   NA->UNRESOLVED: c-c++-common/pr95237-6.c  -std=gnu++14 execution test
>
> Is pr95237-6.c missing an ia32 target filter?

I am checking in this to limit it to x86 targets as an obvious fix.

>   /* { dg-require-effective-target ia32 } */
>
> If all pr95237-*.c cases require target ia32, then shouldn't they be moved to
> gcc.target/i386/ ?
>

They are both C and C++ tests.  gcc.target/i386/  is C only.

-- 
H.J.

[-- Attachment #2: 0001-Limit-pr95237-6.c-to-x86-targets.patch --]
[-- Type: text/x-patch, Size: 927 bytes --]

From 265c6a41b78599309a8649d61879f69b4aae091d Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 22 Jul 2020 07:33:54 -0700
Subject: [PATCH] Limit pr95237-6.c to x86 targets

Since c-c++-common/pr95237-6.c is x86 specific, limit it to x86 targets.

	PR target/95237
	* c-c++-common/pr95237-6.c: Only run for x86 targets.
---
 gcc/testsuite/c-c++-common/pr95237-6.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/c-c++-common/pr95237-6.c b/gcc/testsuite/c-c++-common/pr95237-6.c
index ce1568fa282..5e7396d7f4e 100644
--- a/gcc/testsuite/c-c++-common/pr95237-6.c
+++ b/gcc/testsuite/c-c++-common/pr95237-6.c
@@ -1,5 +1,5 @@
-/* { dg-do run } */
-/* { dg-options "-O2" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-do run { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2" } */
 #include <stddef.h>
 #ifdef  __x86_64__
 # define EXP_ALIGN 8
-- 
2.26.2


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2020-07-22 14:38 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23 15:29 [PATCH] Add TARGET_UPDATE_DECL_ALIGNMENT [PR95237] Sunil K Pandey
2020-06-24  7:30 ` Richard Biener
2020-06-25  0:52   ` Sunil Pandey
2020-06-25  8:10     ` Richard Biener
2020-06-26 20:11       ` [PATCH] Add TARGET_LOWER_LOCAL_DECL_ALIGNMENT [PR95237] H.J. Lu
2020-06-29  9:00         ` Richard Biener
2020-07-03 21:16           ` Jason Merrill
2020-07-04 16:11             ` Richard Biener
2020-07-14 15:37               ` Sunil Pandey
2020-07-17  5:15                 ` Sunil Pandey
2020-07-17  8:22                   ` Richard Biener
2020-07-18  5:57                     ` Sunil Pandey
2020-07-20 12:06                       ` Richard Biener
2020-07-21  5:16                         ` Sunil Pandey
2020-07-21  7:50                           ` Richard Biener
2020-07-21 23:04                             ` Sunil Pandey
2020-07-22 14:24                               ` Dimitar Dimitrov
2020-07-22 14:37                                 ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).