On Fri, Jul 4, 2025 at 9:46 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> On Fri, Jul 4, 2025 at 3:42 PM Richard Biener
> <richard.guent...@gmail.com> wrote:
> >
> > On Fri, Jul 4, 2025 at 9:33 AM H.J. Lu <hjl.to...@gmail.com> wrote:
> > >
> > > On Fri, Jul 4, 2025 at 2:37 PM Richard Sandiford
> > > <richard.sandif...@arm.com> wrote:
> > > >
> > > > "H.J. Lu" <hjl.to...@gmail.com> writes:
> > > > > On Thu, Jul 3, 2025 at 11:02 PM Richard Sandiford
> > > > > <richard.sandif...@arm.com> wrote:
> > > > >>
> > > > >> "H.J. Lu" <hjl.to...@gmail.com> writes:
> > > > >> > Since a backend may ignore user type alignment for arguments 
> > > > >> > passed on
> > > > >> > stack, update alignment for arguments passed on stack when copying 
> > > > >> > MEM's
> > > > >> > memory attributes.
> > > > >> >
> > > > >> > gcc/
> > > > >> >
> > > > >> > PR target/120839
> > > > >> > * emit-rtl.cc (set_mem_attrs): Update alignment for argument on
> > > > >> > stack.
> > > > >> >
> > > > >> > gcc/testsuite/
> > > > >> >
> > > > >> > PR target/120839
> > > > >> > * gcc.target/i386/pr120839-1.c: New test.
> > > > >> > * gcc.target/i386/pr120839-2.c: Likewise.
> > > > >> >
> > > > >> >
> > > > >> > --
> > > > >> > H.J.
> > > > >> >
> > > > >> > From 3f8a9bfb4beae47bfc0da20b517a5b3b06a1cbcc Mon Sep 17 00:00:00 
> > > > >> > 2001
> > > > >> > From: "H.J. Lu" <hjl.to...@gmail.com>
> > > > >> > Date: Sat, 28 Jun 2025 06:27:25 +0800
> > > > >> > Subject: [PATCH] Update alignment for argument on stack
> > > > >> >
> > > > >> > Since a backend may ignore user type alignment for arguments 
> > > > >> > passed on
> > > > >> > stack, update alignment for arguments passed on stack when copying 
> > > > >> > MEM's
> > > > >> > memory attributes.
> > > > >> >
> > > > >> > gcc/
> > > > >> >
> > > > >> >       PR target/120839
> > > > >> >       * emit-rtl.cc (set_mem_attrs): Update alignment for argument 
> > > > >> > on
> > > > >> >       stack.
> > > > >> >
> > > > >> > gcc/testsuite/
> > > > >> >
> > > > >> >       PR target/120839
> > > > >> >       * gcc.target/i386/pr120839-1.c: New test.
> > > > >> >       * gcc.target/i386/pr120839-2.c: Likewise.
> > > > >> >
> > > > >> > Signed-off-by: H.J. Lu <hjl.to...@gmail.com>
> > > > >> > ---
> > > > >> >  gcc/emit-rtl.cc                            | 14 ++++++++++++++
> > > > >> >  gcc/testsuite/gcc.target/i386/pr120839-1.c | 14 ++++++++++++++
> > > > >> >  gcc/testsuite/gcc.target/i386/pr120839-2.c | 19 
> > > > >> > +++++++++++++++++++
> > > > >> >  3 files changed, 47 insertions(+)
> > > > >> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr120839-1.c
> > > > >> >  create mode 100644 gcc/testsuite/gcc.target/i386/pr120839-2.c
> > > > >> >
> > > > >> > diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
> > > > >> > index f4fc92bb37a..0d1616361ca 100644
> > > > >> > --- a/gcc/emit-rtl.cc
> > > > >> > +++ b/gcc/emit-rtl.cc
> > > > >> > @@ -389,6 +389,20 @@ set_mem_attrs (rtx mem, mem_attrs *attrs)
> > > > >> >      {
> > > > >> >        MEM_ATTRS (mem) = ggc_alloc<mem_attrs> ();
> > > > >> >        memcpy (MEM_ATTRS (mem), attrs, sizeof (mem_attrs));
> > > > >> > +      if (MEM_EXPR (mem))
> > > > >> > +     {
> > > > >> > +       tree base_address = get_base_address (MEM_EXPR (mem));
> > > > >> > +       if (base_address && TREE_CODE (base_address) == PARM_DECL)
> > > > >> > +         {
> > > > >> > +           /* User alignment on type may be ignored for parameter
> > > > >> > +              passed on stack.  */
> > > > >> > +           tree type = TREE_TYPE (base_address);
> > > > >> > +           unsigned int alignment
> > > > >> > +             = targetm.calls.function_arg_boundary (TYPE_MODE 
> > > > >> > (type),
> > > > >> > +                                                    type);
> > > > >> > +           set_mem_align (mem, alignment);
> > > > >> > +         }
> > > > >> > +     }
> > > > >> >      }
> > > > >> >  }
> > > > >>
> > > > >> This doesn't feel like the right place to address this.  
> > > > >> set_mem_attrs
> > > > >> is just supposed to install the attributes that it has been given,
> > > > >> without second-guessing the contents.
> > > > >>
> > > > >> Where does the incorrect alignment ultimately come from?  (As in,
> > > > >> which piece of code creates the MEM and fails to give it the correct
> > > > >> alignment?)
> > > > >
> > > > > x86 has
> > > > >
> > > > > static unsigned int
> > > > > ix86_function_arg_boundary (machine_mode mode, const_tree type)
> > > > > {
> > > > >   unsigned int align;
> > > > >   if (type)
> > > > >     {
> > > > >       /* Since the main variant type is used for call, we convert it 
> > > > > to
> > > > >          the main variant type.  */
> > > > >       type = TYPE_MAIN_VARIANT (type);
> > > > >       align = TYPE_ALIGN (type);
> > > > >       if (TYPE_EMPTY_P (type))
> > > > >         return PARM_BOUNDARY;
> > > > >     }
> > > > >
> > > > > Because of
> > > > >
> > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120900
> > > > >
> > > > > for C,
> > > > >
> > > > > typedef struct {
> > > > >   long double a, b
> > > > > } c __attribute__((aligned(32)));
> > > > >
> > > > > when such a variable is passed on stack, its alignment
> > > > > on stack is 16, not 32.  However, when set_mem_attrs
> > > >                                     ^^^^^^^^^^^^^^^^^^
> > > > > is called to set MEM_ALIGN for such a variable on stack,
> > > >   ^^^^^^^^^^^^^^^^^^^^^^^^^^
> > > > > it sets MEM_ALIGN to 32, instead of 16.
> > > >
> > > > But what I meant was: which piece of code calls set_mem_attrs
> > > > to set MEM_ALIGN in this case?  The bug seems further up the
> > > > call stack to me.
> > > >
> > >
> > > Breakpoint 1, set_mem_attrs (mem=0x7fffe9605510, attrs=0x7fffffffccd0)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:381
> > > 381   if (mem_attrs_eq_p (attrs, mode_mem_attrs[(int) GET_MODE (mem)]))
> > > (gdb) bt
> > > #0  set_mem_attrs (mem=0x7fffe9605510, attrs=0x7fffffffccd0)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:381
> > > #1  0x00000000008096d3 in set_mem_attributes_minus_bitpos 
> > > (ref=0x7fffe9605510,
> > >     t=0x7fffe9810bb0, objectp=1, bitpos=...)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:2191
> > > #2  0x0000000000809729 in set_mem_attributes (ref=0x7fffe9605510,
> > >     t=0x7fffe9810bb0, objectp=1)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:2197
> > > #3  0x000000000090d1a6 in assign_parm_find_stack_rtl (parm=0x7fffe9810bb0,
> > >     data=0x7fffffffcee0)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/function.cc:2681
> > > #4  0x0000000000911278 in assign_parms (fndecl=0x7fffe99d2900)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/function.cc:3691
> > > #5  0x0000000000915be8 in expand_function_start (subr=0x7fffe99d2900)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/function.cc:5201
> > > #6  0x00000000006c5b6b in (anonymous namespace)::pass_expand::execute (
> > >     this=0x486c0e0, fun=0x7ffff7fbc190)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/cfgexpand.cc:7168
> > > #7  0x0000000000d02703 in execute_one_pass (pass=0x486c0e0)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/passes.cc:2648
> > > #8  0x0000000000d02afb in execute_pass_list_1 (pass=0x486c0e0)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/passes.cc:2757
> > > ...
> > > (gdb) call debug (mem)
> > > (mem/c:BLK (reg/f:DI 92 virtual-incoming-args) [0  A8])
> > > (gdb) f 1
> > > #1  0x00000000008096d3 in set_mem_attributes_minus_bitpos 
> > > (ref=0x7fffe9605510,
> > >     t=0x7fffe9810bb0, objectp=1, bitpos=...)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:2191
> > > 2191   set_mem_attrs (ref, &attrs);
> > > (gdb) p attrs
> > > $2 = {expr = 0x7fffe9810bb0, offset = {coeffs = {0}}, size = {coeffs = 
> > > {32}},
> > >   alias = 2, align = 256, addrspace = 0 '\000', offset_known_p = true,
> > >   size_known_p = true}
> > > (gdb)
> > > Breakpoint 2, set_mem_attributes_minus_bitpos (ref=0x7fffe9605510,
> > >     t=0x7fffe9810bb0, objectp=1, bitpos=...)
> > >     at /export/gnu/import/git/gitlab/x86-gcc-test/gcc/emit-rtl.cc:2163
> > > 2163       get_object_alignment_1 (t, &obj_align, &obj_bitpos);
> > > (gdb) next
> > > 2164       unsigned int diff_align = known_alignment (obj_bitpos - 
> > > bitpos);
> > > (gdb)
> > > 2165       if (diff_align != 0)
> > > (gdb) p obj_align
> > > $3 = 256
> > > (gdb)
> > > (gdb) next
> > > 2167       attrs.align = MAX (attrs.align, obj_align);
> > > (gdb) p attrs.align
> > > $4 = 256
> > > (gdb)
> > >
> > > 256 is wrong only because
> > >
> > > typedef struct {
> > >   long double a;
> > >   long double b;
> > > } c __attribute__((aligned(32)));
> > >
> > > is passed on stack.
> > >
> > > The problems are in get_object_alignment_2 and 
> > > set_mem_attributes_minus_bitpos.
> >
> > I think the problem is that the IL doesn't reflect reality.  When the 
> > PARM_DECL
> > (or its type) has the specified alignment that has to reflect reality.  
> > Consider
> >
> > void foo (c x)
> > {
> >    __typeof (x) *tem = &x;
> >    x->a;
> > }
> >
> > when the target doesn't honor the alignment of 'x' then the accesses
> > based off 'tem'
> > will be wrong.
> >
> > The middle-end has, in similar cases, the "fix" for such bad backends
> > to generate a
> > callee copy for the incoming argument (with insufficient alignment) to
> > a local stack
> > variable with (sufficient alignment).  Why is that not triggering here?
>
> Where should I look for such codes in the middle-end?

It must be in the maze of assign_parms, assign_parm_adjust_stack_rtl
looks like what I remember:

  /* If we can't trust the parm stack slot to be aligned enough for its
     ultimate type, don't use that slot after entry.  We'll make another
     stack slot, if we need one.  */
  if (stack_parm


>
> > > Here is the v2 patch:
> > >
> > > Since a backend may ignore user type alignment for arguments passed on
> > > stack, call targetm.calls.function_arg_boundary to get alignment of
> > > parameter on stack and don't increase it.
> > >
> > > gcc/
> > >
> > > PR target/120839
> > > * builtins.cc (get_object_alignment_2): Call
> > > targetm.calls.function_arg_boundary to get alignment of
> > > parameter on stack.
> > > * emit-rtl.cc (set_mem_attributes_minus_bitpos): Don't
> > > increase alignment of parameter passed on stack.
> > >
> > > gcc/testsuite/
> > >
> > > PR target/120839
> > > * gcc.target/i386/pr120839-1.c: New test.
> > > * gcc.target/i386/pr120839-2.c: Likewise.
> > >
> > > --
> > > H.J.
>
>
>
> --
> H.J.

Reply via email to