> Date: Thu, 10 Jan 2019 00:06:01 +0100
> From: Jakub Jelinek <ja...@redhat.com>

> 2019-01-09  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR middle-end/84877
>       PR bootstrap/88450
>       * function.c (assign_stack_local_1): Revert the 2018-11-21 changes.
>       (assign_parm_setup_block): Do the argument slot realignment here
>       instead.

When this was committed as r267812, results for cris-elf went
from regress-8 to regress-160 (now at r268749, regress-154).

<TL;DR>
I analyzed one of the simpler cases,
gcc.c-torture/execute/930126-1.c at -O0.

It looks like the code added in r267812 doesn't handle targets
where MAX_SUPPORTED_STACK_ALIGNMENT is less than BITS_PER_WORD
(by necessity, non-STRICT_ALIGNMENT targets); the bug is in not
adding necessary alignment to the allocated space.

cris-elf is a non-STRICT_ALIGNMENT target and
MAX_SUPPORTED_STACK_ALIGNMENT is defaulted from STACK_BOUNDARY,
16 (bits).

The only difference with r267812 is that before, 10 bytes
(excluding 4 for the saved frame-pointer-address) was allocated
for the stack-frame of the function f and at r267812, 8 bytes;
the literally only differences are two instructions, one when
allocating stack and one when forming the pointer to the
stack-parameter.  The sizeof the actual object is 5 bytes, but
padded to 8 bytes due to copying from incoming registers (which
is IMO a valid reason, maybe not worthwhile to improve).  Please
remember that size-padding is different from alignment-padding.

The setting of DECL_ALIGN (parm) to BITS_PER_WORD (originating
at r94104) is wrong too, but not fatal.  I'll fix that in a
follow-up change and let's pretend for the moment that there's a
valid reason for aligning "parm" in this case (for example, a
user-provided overalignment).

At function entry, after saving the frame-pointer-register, the
stack-pointer is 0x3dfffece (both versions).  The parameter-
pointer-align instructions align this to a multiple of 4 for
both versions, and this of course fails as there's no padding
with r267812.  The actual failure is due to overwriting the
saved frame-pointer-register, with the wrong value then used in
main to verify the result.
</TL;DR>

To fix the r267812 incorrectness we need to use the *stored*
size, i.e. that which will be stored into using register-sized
writes.  It's seems like the bug is just a typo, so the fix is
as simple as follows.  Note the usage of "diff -U 10" to show
that size_stored is used in the "then"-arm.

Regtested on cris-elf, where it "introduces" gcc.dg/pr84877.c
but on inspection that's a known bug with a bit of hairy churn,
reverts and all.  See the PR.  This patch has no bearing on that
PR; this is for incoming parameters, and PR84877 is for (not
doing) alignment of pass-by-reference parameters for outgoing
parameters.  Still, maybe the solution to that PR should have
code like in that the context below...which I see you already
noted, in the patch-message to which this is a reply.

Also regtested on x86_64-pc-linux-gnu (without regressions)
together with the followup-change.

Ok to commit?

gcc/ChangeLog:
        * function.c (assign_parm_setup_block): Use the stored
        size, not the passed size, when allocating stack-space,
        also for a parameter with alignment larger than
        MAX_SUPPORTED_STACK_ALIGNMENT.

both arms of the containing "if".)
--- gcc/function.c.orig Sun Jan 20 19:20:16 2019
+++ gcc/function.c      Sat Feb  9 00:53:17 2019
@@ -2907,23 +2907,23 @@ assign_parm_setup_block (struct assign_p
        }
       data->stack_parm = NULL;
     }
 
   size = int_size_in_bytes (data->passed_type);
   size_stored = CEIL_ROUND (size, UNITS_PER_WORD);
   if (stack_parm == 0)
     {
       SET_DECL_ALIGN (parm, MAX (DECL_ALIGN (parm), BITS_PER_WORD));
       if (DECL_ALIGN (parm) > MAX_SUPPORTED_STACK_ALIGNMENT)
        {
-         rtx allocsize = gen_int_mode (size, Pmode);
+         rtx allocsize = gen_int_mode (size_stored, Pmode);
          get_dynamic_stack_size (&allocsize, 0, DECL_ALIGN (parm), NULL);
          stack_parm = assign_stack_local (BLKmode, UINTVAL (allocsize),
                                           MAX_SUPPORTED_STACK_ALIGNMENT);
          rtx addr = align_dynamic_address (XEXP (stack_parm, 0),
                                            DECL_ALIGN (parm));
          mark_reg_pointer (addr, DECL_ALIGN (parm));
          stack_parm = gen_rtx_MEM (GET_MODE (stack_parm), addr);
          MEM_NOTRAP_P (stack_parm) = 1;
        }
       else
        stack_parm = assign_stack_local (BLKmode, size_stored,

brgds, H-P

Reply via email to