On July 3, 2020 11:16:46 PM GMT+02:00, Jason Merrill <ja...@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.to...@gmail.com> wrote: >>> >>> On Thu, Jun 25, 2020 at 1:10 AM Richard Biener >>> <richard.guent...@gmail.com> wrote: >>>> >>>> On Thu, Jun 25, 2020 at 2:53 AM Sunil Pandey <skpg...@gmail.com> >wrote: >>>>> >>>>> On Wed, Jun 24, 2020 at 12:30 AM Richard Biener >>>>> <richard.guent...@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 <skpg...@gmail.com> >>>>>>> >>>>>>> Default for this hook is NOP. For x86, in 32 bit mode, this hook >>>>>>> sets alignment of long long on stack to 32 bits if preferred >stack >>>>>>> boundary is 32 bits. >>>>>>> >>>>>>> - This patch fixes >>>>>>> gcc.target/i386/pr69454-2.c >>>>>>> gcc.target/i386/stackalign/longlong-1.c >>>>>>> - Regression test on x86-64, no new fail introduced. >>>>>> >>>>>> I think the name is badly chosen, >TARGET_LOWER_LOCAL_DECL_ALIGNMENT >>>>> >>>>> 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