i386: Require just 32-bit alignment for SLOT_FLOATxFDI_387 -m32 -mpreferred-stack-boundary=2 DImode temporaries [PR109276]
Checks
Commit Message
Hi!
The following testcase ICEs since r11-2259 because assign_386_stack_local
-> assign_stack_local -> ix86_local_alignment now uses 64-bit alignment
for DImode temporaries rather than 32-bit as before.
Most of the spots in the backend which ask for DImode temporaries are during
expansion and those apparently are handled fine with -m32
-mpreferred-stack-boundary=2, we dynamically realign the stack in that case
(most of the spots actually don't need that alignment but at least one
does), then 2 spots are in STV which I assume also work correctly.
But during splitting we can create a DImode slot which doesn't need to be
64-bit alignment (it is nicer for performance though), when we apparently
aren't able to detect it for dynamic stack realignment purposes.
The following patch just makes the slot 32-bit aligned in that rare case.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2023-03-28 Jakub Jelinek <jakub@redhat.com>
PR target/109276
* config/i386/i386.cc (assign_386_stack_local): For DImode
with SLOT_FLOATxFDI_387 and -m32 -mpreferred-stack-boundary=2 pass
align 32 rather than 0 to assign_stack_local.
* gcc.target/i386/pr109276.c: New test.
Jakub
Comments
On Tue, Mar 28, 2023 at 10:11 AM Jakub Jelinek <jakub@redhat.com> wrote:
>
> Hi!
>
> The following testcase ICEs since r11-2259 because assign_386_stack_local
> -> assign_stack_local -> ix86_local_alignment now uses 64-bit alignment
> for DImode temporaries rather than 32-bit as before.
> Most of the spots in the backend which ask for DImode temporaries are during
> expansion and those apparently are handled fine with -m32
> -mpreferred-stack-boundary=2, we dynamically realign the stack in that case
> (most of the spots actually don't need that alignment but at least one
> does), then 2 spots are in STV which I assume also work correctly.
> But during splitting we can create a DImode slot which doesn't need to be
> 64-bit alignment (it is nicer for performance though), when we apparently
> aren't able to detect it for dynamic stack realignment purposes.
>
> The following patch just makes the slot 32-bit aligned in that rare case.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2023-03-28 Jakub Jelinek <jakub@redhat.com>
>
> PR target/109276
> * config/i386/i386.cc (assign_386_stack_local): For DImode
> with SLOT_FLOATxFDI_387 and -m32 -mpreferred-stack-boundary=2 pass
> align 32 rather than 0 to assign_stack_local.
>
> * gcc.target/i386/pr109276.c: New test.
OK.
Thanks,
Uros.
> --- gcc/config/i386/i386.cc.jj 2023-03-23 10:00:58.415099003 +0100
> +++ gcc/config/i386/i386.cc 2023-03-27 17:36:37.405390440 +0200
> @@ -16682,10 +16682,18 @@ assign_386_stack_local (machine_mode mod
> if (s->mode == mode && s->n == n)
> return validize_mem (copy_rtx (s->rtl));
>
> + int align = 0;
> + /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
> + alignment with -m32 -mpreferred-stack-boundary=2. */
> + if (mode == DImode
> + && !TARGET_64BIT
> + && n == SLOT_FLOATxFDI_387
> + && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
> + align = 32;
> s = ggc_alloc<stack_local_entry> ();
> s->n = n;
> s->mode = mode;
> - s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
> + s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
>
> s->next = ix86_stack_locals;
> ix86_stack_locals = s;
> --- gcc/testsuite/gcc.target/i386/pr109276.c.jj 2023-03-27 17:43:59.977007379 +0200
> +++ gcc/testsuite/gcc.target/i386/pr109276.c 2023-03-27 17:44:52.516249622 +0200
> @@ -0,0 +1,13 @@
> +/* PR target/109276 */
> +/* { dg-do compile } */
> +/* { dg-options "-march=x86-64" } */
> +/* { dg-additional-options "-mpreferred-stack-boundary=2" { target ia32 } } */
> +
> +long long a;
> +long double b;
> +
> +void
> +foo (void)
> +{
> + b += a;
> +}
>
> Jakub
>
@@ -16682,10 +16682,18 @@ assign_386_stack_local (machine_mode mod
if (s->mode == mode && s->n == n)
return validize_mem (copy_rtx (s->rtl));
+ int align = 0;
+ /* For DImode with SLOT_FLOATxFDI_387 use 32-bit
+ alignment with -m32 -mpreferred-stack-boundary=2. */
+ if (mode == DImode
+ && !TARGET_64BIT
+ && n == SLOT_FLOATxFDI_387
+ && ix86_preferred_stack_boundary < GET_MODE_ALIGNMENT (DImode))
+ align = 32;
s = ggc_alloc<stack_local_entry> ();
s->n = n;
s->mode = mode;
- s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), 0);
+ s->rtl = assign_stack_local (mode, GET_MODE_SIZE (mode), align);
s->next = ix86_stack_locals;
ix86_stack_locals = s;
@@ -0,0 +1,13 @@
+/* PR target/109276 */
+/* { dg-do compile } */
+/* { dg-options "-march=x86-64" } */
+/* { dg-additional-options "-mpreferred-stack-boundary=2" { target ia32 } } */
+
+long long a;
+long double b;
+
+void
+foo (void)
+{
+ b += a;
+}