This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/27537] New: XMM alignment fault when compiling for i386 with -Os. Needs ABI specification.
- From: "agner at agner dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 10 May 2006 19:54:38 -0000
- Subject: [Bug c++/27537] New: XMM alignment fault when compiling for i386 with -Os. Needs ABI specification.
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
The g++ compiler for i386 target assumes that the stack is aligned by 16 when
storing xmm registers to the stack. However, the stack is not aligned when
compiling with option -Os (or with the Intel compiler). A misaligned memory
operand to an XMM instruction causes a general protection exception. An example
to reproduce the error is included below.
Suggested remedies:
Either (1): Keep the stack pointer aligned by 16, even when compiling with
option -Os and make this alignment an official requirement in the ABI (the ABI
for IA32 Gnu is shamefully poorly documented!). This alignment is already a
requirement in the Mac OS X IA32 ABI
(http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/index.html#//apple_ref/doc/uid/TP40002521).
It is preferred to have the same ABI for IA32/i386 on MacOS and Linux, BSD,
etc. since they all use the Gnu compiler.
Or (2): Make no assumptions about alignment of the stack. Align the stack
pointer with an AND-instruction whenever an alignment higher than 4 is needed.
(This is in accordance with the Windows IA32 ABI).
Steps to reproduce:
---------- begin file e1.cpp -------------
#include <stdio.h>
#include <emmintrin.h>
// Example showing stack alignment error
// compile with g++ v. 4.1.0:
// g++ -m32 -Os -msse2 e1.cpp
// ./a.out
char * e1() { // This function assumes that the stack is aligned by 16
// This puts 0 in an XMM register and stores it on the stack:
volatile __m128 dummy = _mm_set_ps1(0.f);
return "OK";
}
int main() { // This function calls e1() without proper alignment
printf("%s %s \n", e1(), e1());
return 0;
}
---------- end file e1.cpp -------------
compile this file with:
g++ -m32 -Os -msse2 e1.cpp
./a.out
------------------------------
Expected output:
OK OK
Actual output:
Segmentation fault
-----------------------------
Cause of error:
The instruction that generates the error is:
movaps %xmm0,-16(%ebp)
This instruction requires that the memory operand is aligned by 16, but there
is only a 25% chance that %ebp is divisible by 16 when compiling with option
-Os. The program works correctly when compiled with any other optimization
option. Also works correctly when compiling for x64 platform.
--------------------------------------------
I have submitted a bug report about the same issue to the Intel compiler
developers. Issue # 369990 at premier.intel.com
Whether you choose remedy (1) or (2) above should preferably be coordinated
with the Intel compiler developers and with Apple, because this is an ABI issue
and the solution must be standardized.
--------------------------------------------
[root@localhost t]# g++ -v -save-temps -m32 -Os -msse2 e1.cpp
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--with-cpu=generic --host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.0 20060304 (Red Hat 4.1.0-3)
/usr/libexec/gcc/x86_64-redhat-linux/4.1.0/cc1plus -E -quiet -v -D_GNU_SOURCE
e1.cpp -m32 -msse2 -mtune=generic -Os -fpch-preprocess -o e1.ii
ignoring nonexistent directory
"/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../x86_64-redhat-linux/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../include/c++/4.1.0
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../include/c++/4.1.0/x86_64-redhat-linux
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../include/c++/4.1.0/backward
/usr/local/include
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/include
/usr/include
End of search list.
/usr/libexec/gcc/x86_64-redhat-linux/4.1.0/cc1plus -fpreprocessed e1.ii -quiet
-dumpbase e1.cpp -m32 -msse2 -mtune=generic -auxbase e1 -Os -version -o e1.s
GNU C++ version 4.1.0 20060304 (Red Hat 4.1.0-3) (x86_64-redhat-linux)
compiled by GNU C version 4.1.0 20060304 (Red Hat 4.1.0-3).
GGC heuristics: --param ggc-min-expand=64 --param ggc-min-heapsize=63766
Compiler executable checksum: 145c15e175e7b5491c5723c9bdb452f1
as -V -Qy --32 -o e1.o e1.s
GNU assembler version 2.16.91.0.6 (x86_64-redhat-linux) using BFD version
2.16.91.0.6 20060212
/usr/libexec/gcc/x86_64-redhat-linux/4.1.0/collect2 --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linux.so.2
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../lib/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/32/crtbegin.o
-L/usr/lib/gcc/x86_64-redhat-linux/4.1.0/32
-L/usr/lib/gcc/x86_64-redhat-linux/4.1.0/32
-L/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../lib -L/lib/../lib
-L/usr/lib/../lib e1.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/32/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.1.0/../../../../lib/crtn.o
[root@localhost t]# ./a.out
Segmentation fault
[root@localhost t]#
--
Summary: XMM alignment fault when compiling for i386 with -Os.
Needs ABI specification.
Product: gcc
Version: 4.1.0
Status: UNCONFIRMED
Severity: critical
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: agner at agner dot org
GCC host triplet: x64
GCC target triplet: ia32
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27537