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

            Bug ID: 90020
           Summary: [8 regression] -O2 -Os x86-64 wrong code generated for
                    GNU Emacs
           Product: gcc
           Version: 8.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 46106
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=46106&action=edit
source code illustrating the bug

In:

https://lists.gnu.org/r/emacs-devel/2019-04/msg00209.html

Madhu reports several crashes when compiling applications with 'gcc -O2 -Os' on
x86-64. Madhu isolated the example to a crash with GNU Emacs, and I narrowed
this down to 'gcc -O2 -Os' generating incorrect code for Emacs. I further
narrowed it down to the attached file x.i. I used gcc 8.3.1 20190223 (Red Hat
8.3.1-2) on x86-64 to compile it like this:

gcc -O2 -Os -S x.i

and am attaching a copy of the input x.i and the output x.s. GCC miscompiled
the subroutine 'select_window'. The source code looks like this:

Lisp_Object
select_window (Lisp_Object window)
{
  CHECK_TYPE (WINDOWP (window) && BUFFERP (XWINDOW (window)->contents),
              builtin_lisp_symbol (1214), window);
  struct window *w = XWINDOW (window);
  return w->contents;
}

but the assembly language looks like this:

select_window:
        pushq   %rbp
        pushq   %rbx
        movq    %rdi, %rbx
        pushq   %rcx
        call    WINDOWP
        movq    3(%rbx), %rbp
        ...

and that last movq is incorrect, because it dereferences %rbx ('window' in the
source code) even though it is not known whether WINDOWP returned true. In the
source code, if WINDOWP(window) returns false then 'window' is never used
except as an undereferenced pointer value, and it is possible for
WINDOWP(window) to return false without dereferencing 'window' so it is not
safe for the caller to assume that 'window' is dereferenceable. The incorrect
code causes GCC to dump core.

This problem does not occur with GCC 7.3.0 (Ubuntu 7.3.0-27ubuntu1~18.04).
Madhu observed the problem with GCC 8.2 so I suspect the problem was introduced
in GCC 8.

I don't know which GCC component is causing the problem and am guessing
tree-optimization.

Reply via email to