Bug 62281

Summary: gcc doesn't conform to Solaris 32-bit ABI by expecting 16-byte stack alignment
Product: gcc Reporter: Justin Carveley <justin.carveley>
Component: targetAssignee: Rainer Orth <ro>
Status: RESOLVED FIXED    
Severity: normal CC: ro
Priority: P3 Keywords: ABI, ssemmx
Version: 4.9.1   
Target Milestone: 4.9.4   
URL: https://gcc.gnu.org/ml/gcc-patches/2016-03/msg00461.html
Host: i386-pc-solaris2.10 Target: i386-pc-solaris2.10
Build: Known to work:
Known to fail: 4.8.0, 4.9.0 Last reconfirmed: 2016-03-07 00:00:00
Attachments: Example 2: SSE vector load causes SEGV on callback from Xt timer
Example 2: Preprocessed source
Example 1: gcc compiled module performing sse vector load
Example 1: Solaris studio compiled module: main()
Example 1: preprocessed source
Example 1: build script

Description Justin Carveley 2014-08-27 10:55:46 UTC
Created attachment 33400 [details]
Example 2: SSE vector load causes SEGV on callback from Xt timer

This is essentially a resubmission of bug 47842 "gcc forces 16-byte stack alignment on Solaris i386, when SYSV requires word alignment".

As described in the above bug, changes to gcc for Linux x86 cause generated code to assume a 16-byte preferred and incoming stack alignment. However, this behaviour does not conform to the Solaris x86 (32-bit) ABI, which is still based on http://www.sco.com/developers/devspecs/abi386-4.pdf and only specifies that the stack be 32-bit word aligned.

PR 47842 was closed due to a lack of test cases. Here, therefore, are two test cases that demonstrate the problem:


Example 1: Mixing 32-bit modules compiled with the Solaris Studio 12.3 and gcc:

Using:
- Solaris Studio compiler from http://www.oracle.com/technetwork/server-storage/solarisstudio/downloads/index-jsp-141149.html
- gcc 4.8.0 (stable) or gcc 4.9.0 (unstable) package from http://www.opencsw.org/
  or gcc 4.9.1 built from tarball

Files: x.c, y.c, build

Result:

GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-pc-solaris2.10".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /export/home/justin/tmp/xy...done.
(gdb) r    
Starting program: /export/home/justin/tmp/xy 

Program received signal SIGSEGV, Segmentation fault.
0x080509db in _mm_set_epi8 (__q00=1 '\001', __q01=1 '\001', __q02=1 '\001', 
    __q03=1 '\001', __q04=1 '\001', __q05=1 '\001', __q06=1 '\001', 
    __q07=1 '\001', __q08=1 '\001', __q09=1 '\001', __q10=1 '\001', 
    __q11=1 '\001', __q12=1 '\001', __q13=1 '\001', __q14=1 '\001', 
    __q15=1 '\001')
    at /opt/tarantella/lib/gcc/i386-pc-solaris2.10/4.8.0/include/emmintrin.h:602
602       return __extension__ (__m128i)(__v16qi){
(gdb) where
#0  0x080509db in _mm_set_epi8 (__q00=1 '\001', __q01=1 '\001', 
    __q02=1 '\001', __q03=1 '\001', __q04=1 '\001', __q05=1 '\001', 
    __q06=1 '\001', __q07=1 '\001', __q08=1 '\001', __q09=1 '\001', 
    __q10=1 '\001', __q11=1 '\001', __q12=1 '\001', __q13=1 '\001', 
    __q14=1 '\001', __q15=1 '\001')
    at /opt/tarantella/lib/gcc/i386-pc-solaris2.10/4.8.0/include/emmintrin.h:602
#1  _mm_set1_epi8 (__A=1 '\001')
    at /opt/tarantella/lib/gcc/i386-pc-solaris2.10/4.8.0/include/emmintrin.h:637
#2  test_sse () at x.c:5
#3  0x08050a1b in main (argc=1, argv=0x8047d74) at y.c:5
(gdb) 


Example 2: libXt timer callback

Using:
- gcc 4.8.0 (stable) or gcc 4.9.0 (unstable) packages from http://www.opencsw.org/
- or gcc 4.9.1 from tarball

File: xt.c

Result:
The stack becomes only 4-byte aligned on callback from Xt.

GNU gdb (GDB) 7.6
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i386-pc-solaris2.10".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /export/home/justin/tmp/xt...done.
(gdb) r
Starting program: /export/home/justin/tmp/xt 

Program received signal SIGSEGV, Segmentation fault.
0x08050e97 in _mm_set_epi8 (__q00=1 '\001', __q01=1 '\001', __q02=1 '\001', 
    __q03=1 '\001', __q04=1 '\001', __q05=1 '\001', __q06=1 '\001', 
    __q07=1 '\001', __q08=1 '\001', __q09=1 '\001', __q10=1 '\001', 
    __q11=1 '\001', __q12=1 '\001', __q13=1 '\001', __q14=1 '\001', 
    __q15=1 '\001')
    at /opt/csw/lib/gcc/i386-pc-solaris2.10/4.8.0/include/emmintrin.h:602
602       return __extension__ (__m128i)(__v16qi){
(gdb) info reg ebp
ebp            0x8047c74        0x8047c74
(gdb) fr 1
#1  _mm_set1_epi8 (__A=1 '\001')
    at /opt/csw/lib/gcc/i386-pc-solaris2.10/4.8.0/include/emmintrin.h:637
637       return _mm_set_epi8 (__A, __A, __A, __A, __A, __A, __A, __A,
(gdb) info reg ebp
ebp            0x8047c74        0x8047c74
(gdb) fr 2
#2  timer_callback (client_data=0x0, id=0x8047d10) at xt.c:10
10          __m128i b = _mm_set1_epi8(1);
(gdb) info reg ebp
ebp            0x8047c74        0x8047c74
(gdb) fr 3
#3  0xfef46e29 in XtAppProcessEvent () from /usr/lib/libXt.so.4
(gdb) info reg ebp
ebp            0x8047d18        0x8047d18
(gdb) fr 4
#4  0x08050efc in main (argc=1, argv=0x8047d74) at xt.c:17
17          XtAppProcessEvent(app, XtIMTimer);
(gdb) info reg ebp
ebp            0x8047d4c        0x8047d4c
(gdb) 

I believe the problem was fixed for the limited case of Solaris 9 x86 in bug 60107. However, the analysis for this fix seems slightly off. It infers that, because Solaris 10 creates outgoing thread stacks aligned on 16 bytes, the 32-bit ABI has changed to 16-byte stack alignment on this platform, which isn't correct.

I suggest -mincoming-stack-boundary=2 should be the default for all 32-bit Solaris binaries.


Workarounds:
1. __attribute__((force_align_arg_pointer)) at all entry points to gcc generated code,
2. Compile all gcc code with -mincoming-stack-boundary=2.
Comment 1 Justin Carveley 2014-08-27 10:56:48 UTC
Created attachment 33401 [details]
Example 2: Preprocessed source
Comment 2 Justin Carveley 2014-08-27 10:57:55 UTC
Created attachment 33402 [details]
Example 1: gcc compiled module performing sse vector load
Comment 3 Justin Carveley 2014-08-27 10:58:41 UTC
Created attachment 33403 [details]
Example 1: Solaris studio compiled module: main()
Comment 4 Justin Carveley 2014-08-27 10:59:16 UTC
Created attachment 33404 [details]
Example 1: preprocessed source
Comment 5 Justin Carveley 2014-08-27 10:59:48 UTC
Created attachment 33405 [details]
Example 1: build script
Comment 6 Rainer Orth 2014-08-29 14:37:28 UTC
I've been seeing the same issue in PR middle-end/61949, but only on Solaris 10,
not S11, and the failures have been intermittent (i.e. happened during one bootstrap,
but were gone a week later).

Regarding

> I believe the problem was fixed for the limited case of Solaris 9 x86 in bug 
> 60107. However, the analysis for this fix seems slightly off. It infers that,
> because Solaris 10 creates outgoing thread stacks aligned on 16 bytes, the
> 32-bit ABI has changed to 16-byte stack alignment on this platform, which isn't
> correct.

I believe the i386 psABI is irrelevant here: while it requires word alignment, it
doesn't preclude that Solaris guarantees a stricter alignment, which from what
I've seen both S10 and S11 do.

> I suggest -mincoming-stack-boundary=2 should be the default for all 32-bit
> Solaris binaries.

Before making any changes in this area, I'd like word from the responsible libc
engineer (Roger Faulkner probably) what various Solaris versions do and don't
guarantee.

  Rainer
Comment 7 jsm-csl@polyomino.org.uk 2014-08-29 15:16:52 UTC
FWIW, I recommended to Sun in Mar 2006 that the kernel should ensure 
16-byte alignment for both signal handlers and process startup (apparently 
this resulted in Sun bug 6397812, "Problem with stack alignment for signal 
delivery on AMD64").  (This does not of course mean that the ABI ended up 
with such an alignment requirement at interface boundaries in general.)
Comment 8 Jakub Jelinek 2015-04-22 11:59:05 UTC
GCC 5.1 has been released.
Comment 9 Richard Biener 2015-07-16 09:11:35 UTC
GCC 5.2 is being released, adjusting target milestone to 5.3.
Comment 10 Richard Biener 2015-12-04 10:43:54 UTC
GCC 5.3 is being released, adjusting target milestone.
Comment 11 Rainer Orth 2016-03-07 09:41:23 UTC
*** Bug 61949 has been marked as a duplicate of this bug. ***
Comment 12 Rainer Orth 2016-03-07 09:43:08 UTC
Mine, received confirmation that only 4-byte stack alignment is guaranteed on
32-bit Solaris/x86 from the Solaris and Studio groups in Oracle.

  Rainer
Comment 13 Rainer Orth 2016-03-07 09:52:02 UTC
Author: ro
Date: Mon Mar  7 09:51:31 2016
New Revision: 234022

URL: https://gcc.gnu.org/viewcvs?rev=234022&root=gcc&view=rev
Log:
Only assume 4-byte stack alignment on 32-bit Solaris/x86 (PR target/62281)

	PR target/62281
	* config/i386/sol2.h (STACK_REALIGN_DEFAULT): Define.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/i386/sol2.h
Comment 14 Rainer Orth 2016-03-07 09:56:15 UTC
Fixed for 6.1.
Comment 15 Rainer Orth 2016-03-14 09:57:19 UTC
Author: ro
Date: Mon Mar 14 09:56:47 2016
New Revision: 234179

URL: https://gcc.gnu.org/viewcvs?rev=234179&root=gcc&view=rev
Log:
Only assume 4-byte stack alignment on Solaris/x86 (PR target/62281)

	Backport from mainline
	2016-03-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR target/62281
	* config/i386/sol2.h (STACK_REALIGN_DEFAULT): Define.

Modified:
    branches/gcc-5-branch/gcc/ChangeLog
    branches/gcc-5-branch/gcc/config/i386/sol2.h
Comment 16 Rainer Orth 2016-03-14 10:03:44 UTC
Author: ro
Date: Mon Mar 14 10:03:12 2016
New Revision: 234180

URL: https://gcc.gnu.org/viewcvs?rev=234180&root=gcc&view=rev
Log:
Only assume 4-byte stack alignment on Solaris/x86 (PR target/62281)

	Backport from mainline:
	2016-03-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR target/62281
	* config/i386/sol2.h (STACK_REALIGN_DEFAULT): Define.

	Revert:
	2014-02-11  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR libgomp/60107
	* config/i386/sol2-9.h: New file.
	* config.gcc (i[34567]86-*-solaris2* | x86_64-*-solaris2.1[0-9]*,
	*-*-solaris2.9*): Use it.

Removed:
    branches/gcc-4_9-branch/gcc/config/i386/sol2-9.h
Modified:
    branches/gcc-4_9-branch/gcc/ChangeLog
    branches/gcc-4_9-branch/gcc/config.gcc
    branches/gcc-4_9-branch/gcc/config/i386/sol2.h
Comment 17 Rainer Orth 2016-03-14 10:07:34 UTC
Fixed for GCC 4.9.4, 5.4, 6.1.
Comment 18 Michael Meissner 2016-03-14 18:19:17 UTC
Author: meissner
Date: Mon Mar 14 18:18:45 2016
New Revision: 234188

URL: https://gcc.gnu.org/viewcvs?rev=234188&root=gcc&view=rev
Log:
[gcc]
2016-03-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

	Backport from mainline
	2016-03-11  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/70131
	* config/rs6000/rs6000.md (round32<mode>2_fprs): Do not do the
	optimization if we have direct move.
	(roundu32<mode>2_fprs): Likewise.

2016-03-14  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	Backport from mainline
	2016-03-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR target/62281
	* config/i386/sol2.h (STACK_REALIGN_DEFAULT): Define.

2016-03-10  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>

	PR target/70168
	* config/rs6000/rs6000.c (rs6000_expand_atomic_compare_and_swap):
	Handle overlapping retval and newval.

[gcc/testsuite]
2016-03-14  Michael Meissner  <meissner@linux.vnet.ibm.com>

	Backport from mainline
	2016-03-11  Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/70131
	* gcc.target/powerpc/ppc-round2.c: New test.

2016-03-14  Dominique d'Humieres  <dominiq@lps.ens.fr>

	PR fortran/45076
	gfortran.dg/prof/prof.exp: New script.
	gfortran.dg/prof/dynamic_dispatch_6.f03: New test.


Added:
    branches/ibm/gcc-5-branch/gcc/testsuite/gcc.target/powerpc/ppc-round2.c
      - copied unchanged from r234186, branches/gcc-5-branch/gcc/testsuite/gcc.target/powerpc/ppc-round2.c
    branches/ibm/gcc-5-branch/gcc/testsuite/gfortran.dg/prof/
      - copied from r234186, branches/gcc-5-branch/gcc/testsuite/gfortran.dg/prof/
Modified:
    branches/ibm/gcc-5-branch/gcc/ChangeLog
    branches/ibm/gcc-5-branch/gcc/DATESTAMP
    branches/ibm/gcc-5-branch/gcc/config/i386/sol2.h
    branches/ibm/gcc-5-branch/gcc/config/rs6000/rs6000.c
    branches/ibm/gcc-5-branch/gcc/config/rs6000/rs6000.md
    branches/ibm/gcc-5-branch/gcc/testsuite/ChangeLog