c++/3299: __attribute__((aligned(16))) seems to be ignored on x86
ryants@home.com
ryants@home.com
Wed Jun 20 10:56:00 GMT 2001
>Number: 3299
>Category: c++
>Synopsis: __attribute__((aligned(16))) seems to be ignored on x86
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jun 20 10:56:03 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Ryan T. Sammartino
>Release: gcc version 2.95.3 19991030 (prerelease)
>Organization:
>Environment:
Linux 2.4.5-6mdksmp #1 SMP Mon Jun 18 10:19:22 PDT 2001 i686 unknown
>Description:
The following code (which doesn't include anything, so it's the same as the .ii that is generated) seg faults because none of v1, v2, or ret are aligned to a 16 byte boundary, as required for the movaps instruction:
---cut here---
class vector
{
public:
float x;
float y;
float z;
float w;
vector(float _x, float _y, float _z, float _w)
: x(_x), y(_y), z(_z), w(_w)
{}
vector()
{}
vector operator+(const vector &v1)
{
vector ret __attribute__((aligned(16)));
asm("movl %1, %%esi \n"
"movl %2, %%edi \n"
"movaps (%%esi), %%xmm0 \n"
"addps (%%edi), %%xmm0 \n"
"movaps %%xmm0, %0 \n"
: "=g" (ret) : "r" (this), "r" (&v1));
return ret;
}
} __attribute__((aligned(16)));
int main(int argc, char *argv[])
{
vector v1(3.0f, 4.0f, 5.0f, 1.0f);
vector v2(7.0f, 1.0f, 9.0f, 1.0f);
vector ans = v1 + v2;
}
---cut here---
Here is the output I get:
$ g++ -v -save-temps -Wall -g sse.cpp -o sse
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/specs
gcc version 2.95.3 19991030 (prerelease)
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/cpp -lang-c++ -v -D__GNUC__=2 -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -D__EXCEPTIONS -g -Wall -Acpu(i386) -Amachine(i386) -Di386 -D__i386 -D__i386__ -Di586 -Dpentium -D__i586 -D__i586__ -D__pentium -D__pentium__ sse.cpp sse.ii
GNU CPP version 2.95.3 19991030 (prerelease) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/../../../../include/g++-3
/usr/local/include
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/../../../../i586-mandrake-linux/include
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/include
/usr/include
End of search list.
The following default directories have been omitted from the search path:
End of omitted list.
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/cc1plus sse.ii -quiet -dumpbase sse.cc -g -Wall -version -o sse.s
GNU C++ version 2.95.3 19991030 (prerelease) (i586-mandrake-linux) compiled by GNU C version 2.95.3 19991030 (prerelease).
sse.cpp: In function `int main(int, char **)':
sse.cpp:36: warning: unused variable `class vector ans'
as -V -Qy -o sse.o sse.s
GNU assembler version 2.10.91 (i686-mandrake-linux) using BFD version 2.10.91.0.2
/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/collect2 -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o sse /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/crtbegin.o -L/usr/lib/gcc-lib/i586-mandrake-linux/2.95.3 -L/usr/i586-mandrake-linux/lib sse.o -lstdc++ -lm -lgcc -lc -lgcc /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/crtend.o /usr/lib/crtn.o
I also tried the "equivalent" C code and compiling with gcc but I got the same problem.
This problem also exists for these other versions of gcc:
---
Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/2.95.3-5/specs
gcc version 2.95.3-5 (cygwin special)
---
Using builtin specs.
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --enable-shared --enable-threads=posix --disable-checking --enable
-long-long --enable-cstdio=stdio --enable-clocale=generic --enable-languages=c,c++,f77,objc,java --program-suffix=-3.0 --enable-objc-gc --host=i686-mandrake-linux
Thread model: posix
gcc version 3.0
---
(But my 3.0 installation may not be correct, so you may want to ignore that)
>How-To-Repeat:
- compile the sample code on a PIII
- run it.
>Fix:
By adding three ints before my vectors:
...
int i,j,k;
vector ret __attribute((aligned(16)));
...
int i,j,k;
vector v1(...);
vector v2(...);
I get the proper alignment and the code runs successfully.
Of course, this is a less than good solution, since as soon as I use any sort of optimisation, the alignment is not good again.
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the Gcc-bugs
mailing list