https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78444

            Bug ID: 78444
           Summary: Wrong prologue stack alignment for implicit dtor on
                    x86_64-darwin*
           Product: gcc
           Version: 7.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: iains at gcc dot gnu.org
  Target Milestone: ---

Created attachment 40095
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40095&action=edit
stand-alone reproducer (c++11)

-std=c++11 -fno-exceptions -fno-rtti

In this code, there's an implict dtor which calls a base class dtor.  The stack
is incorrectly aligned at the call to the second dtor (leading to dyld
complaining and aborting the code).

        .globl __ZN4llvm2cl6parserIjED1Ev
        .weak_definition __ZN4llvm2cl6parserIjED1Ev
__ZN4llvm2cl6parserIjED1Ev:
LFB15:
        pushq   %rbp
LCFI21:
        movq    %rsp, %rbp
LCFI22:
        subq    $8, %rsp
        movq    %rdi, -8(%rbp)
        movq    -8(%rbp), %rax
        movq    %rax, %rdi
        call    __ZN4llvm2cl12basic_parserIjED2Ev
        leave
LCFI23:
        ret
LFE15:

=====

AFAICT has been present since c++11 introduction in 4.7 (so seems to be an
infrequently triggered issue).

I can't see any particular reason why this is Darwin-specific (the x86_64 code
in the back end has very little Darwin conditional code).  However, it looks
like Linux clones the dtor (_ZN4llvm2cl6parserIjED2Ev) and generates correct
prologue code for that.  So it's not clear if this is Darwin-specific, or just
that the fail conditions are only triggered for Darwin.

Looking at the tree dumps, the dtors look like regular weak hidden functions.

====

Looking at the incoming state to ix86_expand_prologue, it seems that the
function is expecting the stack_alignment_needed to be already set to a valid
amount.

with some debug code at the entry of ix86_expand_prologue():
$ ./prev-gcc/xg++ -Bprev-gcc -fno-exceptions -fno-rtti
/Volumes/sc3_src/test-cxx/prologue-x86-64-bug.C -S
_ZN4llvm2cl6OptionD2Ev : is leaf Y incoming 128 set align_needed 64 realign N
_ZN4llvm2cl12basic_parserIjED2Ev : is leaf Y incoming 128 set align_needed 64
realign N
_ZN4llvm2cl12basic_parserIjED1Ev : is leaf Y incoming 128 set align_needed 64
realign N
_ZN4llvm2cl3optIjLb0ENS0_6parserIjEEE16handleOccurrenceEjNS_9StringRefES5_ : is
leaf Y incoming 128 set align_needed 64 realign N
_ZNK4llvm2cl3optIjLb0ENS0_6parserIjEEE16printOptionValueEjb : is leaf Y
incoming 128 set align_needed 64 realign N
_ZN4llvm2cl6parserIjED1Ev : is leaf N incoming 128 set align_needed 64 realign
N
_ZN4llvm2cl3optIjLb0ENS0_6parserIjEEED1Ev : is leaf N incoming 128 set
align_needed 128 realign N
_ZN4llvm2cl3optIjLb0ENS0_6parserIjEEED0Ev : is leaf N incoming 128 set
align_needed 128 realign N

Notice that _ZN4llvm2cl6parserIjED1Ev is not a leaf function, but only claims
to need 64b alignment.

If I hack the following into ix86_finalize_stack_realign_flags()

  if (TARGET_MACHO && TARGET_64BIT && !crtl->is_leaf)
    {
        /* Darwin needs at least 128b alignment at function calls.  */
        crtl->stack_alignment_needed = crtl->stack_alignment_needed < 128
                                     ? 128
                                     : crtl->stack_alignment_needed;
        crtl->preferred_stack_boundary = crtl->preferred_stack_boundary < 128
                                       ? 128
                                       : crtl->preferred_stack_boundary;
    }

it works around the issue.

So the questions are;
1. are preceding phases (e.g. cfgexpand) supposed to make target callbacks that
get this right?
2. is something missing in the pro/epilogue that's supposed to detect this case
and fix it up?

Reply via email to