Summary: | [SPARC/Solaris] __int128 aligned(8) as function argument is passed in wrong register | ||
---|---|---|---|
Product: | gcc | Reporter: | Марина Полякова <polyakova.marina69> |
Component: | target | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | NEW --- | ||
Severity: | normal | CC: | ebotcazou, jakub, ro |
Priority: | P3 | Keywords: | ABI |
Version: | 5.5.0 | ||
Target Milestone: | --- | ||
Host: | Target: | sparc-solaris | |
Build: | Known to work: | ||
Known to fail: | Last reconfirmed: | 2018-01-18 00:00:00 | |
Attachments: |
preprocessed file for PG_ALIGN_128=8
unpreprocessed input |
Note GCC 5 is no longer maintained - can you test a newer version? No, I can't because pkgutil has only gcc 4 or 5 :-( (In reply to Richard Biener from comment #1) > Note GCC 5 is no longer maintained - can you test a newer version? No, I can't because pkgutil has only gcc 4 or 5 :-( Rainer, can you please test current trunk? Thanks. Created attachment 43175 [details]
unpreprocessed input
The failure still happens indeed, but only at -O0, -O and -O2 are fine. 128-bit types requite 128-bit alignment on SPARC64 so we cannot support that. (In reply to Eric Botcazou from comment #7) > 128-bit types requite 128-bit alignment on SPARC64 so we cannot support that. Fair enough, but wouldn't it be a good idea to throw an error for the alignment atttribute, rather than silently generating incorrect code? Given the issues we had on ARM, AArch64 (see exempli gratia PR65956 and associated discussions), et cetera with overaligned/underaligned scalars, I think the right thing is not to consider alignment for the argument passing and return value passing decisions at least for scalars. One can always call a function with a scalar argument expecting some alignment and callee expecting different etc. So, any reason why e.g. in this case the __int128_t arguments shouldn't be passed always the same, e.g. like normally aligned __int128_t? |
Created attachment 43170 [details] preprocessed file for PG_ALIGN_128=8 If we define a new type int128a as __int128 __attribute__((aligned(8))), and you pass it as not the first function argument, its value in the function may be incorrect. See the output of the test program: $ gcc -D PG_ALIGN_128=8 -m64 -o int128test2 int128test2.c $ ./int128test2 basic aritmetic OK pass int 16 FAILED pass uint 16 FAILED pass int 32 FAILED pass int 64 FAILED pass int 128 OK (see its preprocessed file int128test2_8.i as an attachment) When the alignment is 16, everything is fine: $ gcc -D PG_ALIGN_128=16 -m64 -o int128test2 int128test2.c $ ./int128test2 basic aritmetic OK pass int 16 OK pass uint 16 OK pass int 32 OK pass int 64 OK pass int 128 OK As it turns out, Sparc GCC passes function arguments via register ring which is referenced as %on in the calling code and as %in in function. And somehow it happens that alignment attribute of typedef affects access to arguments in the function, but doesn't affect how regiser ring is filled before call. the system type: sparc-sun-solaris2.10 the options given when GCC was configured/built: /home/dam/mgar/pkg/gcc5/trunk/work/solaris10-sparc/build-isa-sparcv8plus/gcc-5.5.0/configure --prefix=/opt/csw --exec_prefix=/opt/csw --bindir=/opt/csw/bin --sbindir=/opt/csw/sbin --libexecdir=/opt/csw/libexec --datadir=/opt/csw/share --sysconfdir=/etc/opt/csw --sharedstatedir=/opt/csw/share --localstatedir=/var/opt/csw --libdir=/opt/csw/lib --infodir=/opt/csw/share/info --includedir=/opt/csw/include --mandir=/opt/csw/share/man --enable-cloog-backend=isl --enable-java-awt=xlib --enable-languages=ada,c,c++,fortran,go,java,objc --enable-libada --enable-libssp --enable-nls --enable-objc-gc --enable-threads=posix --program-suffix=-5.5 --with-cloog=/opt/csw --with-gmp=/opt/csw --with-included-gettext --with-ld=/usr/ccs/bin/ld --without-gnu-ld --with-libiconv-prefix=/opt/csw --with-mpfr=/opt/csw --with-ppl=/opt/csw --with-system-zlib=/opt/csw --with-as=/usr/ccs/bin/as --without-gnu-as