Linking fails for the program below, with the error: undefined reference to `___sync_val_compare_and_swap_4' // gcc -Wall atomic.c int main() { int *a, b, c; return __sync_val_compare_and_swap(a, b, c); } According to the atomic builtins docs (), "Not all operations are supported by all target processors. If a particular operation cannot be implemented on the target processor, a warning will be generated and a call an external function will be generated. The external function will carry the same name as the builtin, with an additional suffix `_n' where n is the size of the data type." If CAS is not supported, how come I don't get a warning? Why would i686 *not* support compare and swap? The cmpxchg instruction has been around since 80486, according to the intel IA-32 processor manual. Also, does an unsupported builtin mean the user is responsible to write that function, or simply that the compiler must make a function call to synthesize its behavior? FWIW, my x86_64 cross-compile gcc 4.2.0 handles it fine, emitting a "lock"+"cmpxchg" pair.
Because the default arch for i686-linux-gnu is i386.
I think this is essentially invalid. Note that now we also have the various __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* macros: http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html
Subject: Re: atomic builtins not supported on i686? On Thu, 15 Nov 2007, pinskia at gcc dot gnu dot org wrote: > Because the default arch for i686-linux-gnu is i386. Which is a stupid inconsistency and arguably a bug. sparcv9-linux-gnu defaults to -mcpu=v9 (where -mcpu means -march for SPARC), likewise various other architectures; i686-linux-gnu should be consistent with those other targets and default to -march=i686. libstdc++ will use i486-specific code if you configure GCC for i[456]86, even when GCC itself restricts itself to i386 code, making this default to i386 even less useful; likewise glibc will use i486/i586/i686 code when configured for those processors (and no longer supports i386).
Yeah, the wind is changing!
Subject: Re: atomic builtins not supported on i686? On 15 Nov 2007 23:53:06 -0000, joseph at codesourcery dot com <gcc-bugzilla@gcc.gnu.org> wrote: > > Because the default arch for i686-linux-gnu is i386. > Which is a stupid inconsistency and arguably a bug. ++ BTW, -march=i686 works beautifully. Close the bug? or rename it as a RFE to have i686-* default to -march=i686?
(In reply to comment #5) > Subject: Re: atomic builtins not supported on i686? > > On 15 Nov 2007 23:53:06 -0000, joseph at codesourcery dot com > <gcc-bugzilla@gcc.gnu.org> wrote: > > > Because the default arch for i686-linux-gnu is i386. > > Which is a stupid inconsistency and arguably a bug. > > ++ > > BTW, -march=i686 works beautifully. Close the bug? or rename it as a > RFE to have i686-* default to -march=i686? > Oh, and is there supposed to be a warning about unsupported atomic ops or not? If not the docs should say to expect a linker error instead (and also mention/link those macros Paolo pointed out).
(In reply to comment #2) > I think this is essentially invalid. Note that now we also have the various > __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* macros: > > http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html > Too bad they aren't defined for any machine I've tried so far... ia64-linux-gnu (4.1.2 Debian) x86_64-unknown-linux-gnu (4.2.0) sparc-sun-solaris2.10 (4.1.1) powerpc64-unknown-linux-gnu (4.1.2 Gentoo) i686-pc-cygwin (4.2.2) All these actually *do* support CAS, and emit perfectly respectable .asm... as long as you don't wrap them in any #ifdef's.
(In reply to comment #7) > Too bad they aren't defined for any machine I've tried so far... The explanation is very simple: the new macros are implemented only in mainline (would be 4.3.0).
(In reply to comment #8) > (In reply to comment #7) > > Too bad they aren't defined for any machine I've tried so far... > > The explanation is very simple: the new macros are implemented only in mainline > (would be 4.3.0). > Any chance of backporting? (I know, probably not) The only question left is whether the compiler is supposed to emit a warning when it doesn't support the intrinsics (like the docs say) or whether the user should just be ready for linker errors.
After encountering this issue and some testing, I think this is definitely a bug. The problem ONLY occurs when directly returning a call to an atomic builtin! Assuming no march flags: Links: int main() { unsigned long test; return __sync_add_and_fetch(&test, 1); return (int)test; } Does not link: int main() { unsigned long test; return __sync_add_and_fetch(&test, 1); } If you do specify -march=i686, then they both link! If this somehow isn't a bug, the design is poor, because it's very hard to debug behavior. $ gcc -v Reading specs from /opt/app/g++lib6/gcc-4.2/lib/gcc/i386-pc-solaris2.10/4.2.2/specs Target: i386-pc-solaris2.10 Configured with: ../configure --prefix=/opt/app/g++lib6/gcc-4.2 --enable-languages=c,c++,fortran,objc --disable-nls --with-included-gettext --with-gnu-as --with-as=/usr/sfw/bin/gas --with-target-tools=/usr/sfw/bin/ --with-gmp=/opt/app/nonc++/gmp-4.2 --with-mpfr=/opt/app/nonc++/mpfr-2.3 Thread model: posix gcc version 4.2.2
is this still a problem now that GCC defaults to setting the default march based on the configure target?
The defualt arch changed with r0-98640 such that i686 defaults to i686 which fixes this issue all together.