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

David Grayson <davidegrayson at gmail dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |davidegrayson at gmail dot com

--- Comment #14 from David Grayson <davidegrayson at gmail dot com> ---
To recap: there is an internal compiler error in ix86_compute_frame_layout when
using rdrnd, C++, noexcept, and i686-w64-mingw32.  And it probably affects
x86_64-w64-mingw32 too, but I am most interested in the i686 case so I will
focus on that.

Here is a minimal test case the reproduces the issue:

    __attribute__((__target__("rdrnd")))
        void f(unsigned int * b) noexcept {
      __builtin_ia32_rdrand32_step(b);
    }

Here are some workarounds I found:

1) Remove the "noexcept" specifier from the function.
2) Don't use the rdrand built-ins.
3) Compile the function as C code.
4) I'm not sure if this is safe, but you can use the compiler option
-mpreferred-stack-boundary=2, which tells GCC to prefer 4-aligning the stack.

I am running GCC as a cross-compiler on Linux, targeting i686-w64-mingw32.  I
have seen this bug in GCC 7.3.0, 8.2.0, and the 8-20181019 snapshot.  For the
remainder of this bug report, I will just focus on the behavior of the
8-20181019 snapshot.

Here is the command I use to compile the program above, and the full output of
the compiler:

----

$ ../prefix/bin/i686-w64-mingw32-g++ -c ../david.cpp 
during RTL pass: ira
../david.cpp: In function 'void f(unsigned int*)':
../david.cpp:3:1: internal compiler error: in ix86_compute_frame_layout, at
config/i386/i386.c:11734
 }
 ^
0xe0b414 ix86_compute_frame_layout
        ../../gcc-8-20181019/gcc/config/i386/i386.c:11734
0xaf65ed set_initial_elim_offsets
        ../../gcc-8-20181019/gcc/reload1.c:3858
0xb0131f calculate_elim_costs_all_insns()
        ../../gcc-8-20181019/gcc/reload1.c:1562
0x9e536f ira_costs()
        ../../gcc-8-20181019/gcc/ira-costs.c:2249
0x9decc6 ira_build()
        ../../gcc-8-20181019/gcc/ira-build.c:3427
0x9d64e3 ira
        ../../gcc-8-20181019/gcc/ira.c:5295
0x9d64e3 execute
        ../../gcc-8-20181019/gcc/ira.c:5606
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

----

The assertion that is failing in ix86_compute_frame_layout (i386.c, line 11734)
is this one:

    gcc_assert (preferred_alignment <= stack_alignment_needed);

By adding my own fprintf statement, I determined that in the problematic case
we have:

- preferred_alignment is 16
- stack_alignment_needed is 4

I did some experiments and I found that the problematic case (using an rdrand
intrinsic in a noexcept C++ function) seems to be the only case where the
preferred_alignment variable is affected by the -mpreferred-stack-boundary
command-line option.  In every other case, preferred_alignment is always just
4.

Isn't that weird?  Just looking at variable names, I would expect
-mpreferred-stack-boundary to always affect crtl->preferred_stack_boundary and
crtl->stack_alignment_needed (which are where the values in the assertion above
come from).  My guess is that someone decided to force the
preferred_stack_boundary and stack_alignment_needed to 4 on Windows for some
reason, and they succeeded in doing that for most cases, but they failed to do
it for the rdrand/C++/noexcept case.

Does anyone have an idea of how to fix this bug for real?  What values should
crtl->preferred_stack_boundary crtl->stack_alignment_needed really have  on
Windows, and should they be controllable from the command-line?  Where do they
get set?

--David

Reply via email to