Bug 34115 - atomic builtins not supported on i686?
Summary: atomic builtins not supported on i686?
Status: UNCONFIRMED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-11-15 22:15 UTC by Ryan Johnson
Modified: 2010-10-15 20:48 UTC (History)
2 users (show)

See Also:
Host: i686-pc-cygwin
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan Johnson 2007-11-15 22:15:27 UTC
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.
Comment 1 Andrew Pinski 2007-11-15 22:19:49 UTC
Because the default arch for i686-linux-gnu is i386.
Comment 2 Paolo Carlini 2007-11-15 22:30:05 UTC
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
Comment 3 joseph@codesourcery.com 2007-11-15 23:53:06 UTC
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).

Comment 4 Paolo Carlini 2007-11-16 00:07:43 UTC
Yeah, the wind is changing!
Comment 5 Ryan Johnson 2007-11-16 01:00:18 UTC
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?
Comment 6 Ryan Johnson 2007-11-16 01:04:29 UTC
(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).
Comment 7 Ryan Johnson 2007-11-28 01:56:01 UTC
(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.
Comment 8 Paolo Carlini 2007-11-28 02:05:27 UTC
(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).
Comment 9 Ryan Johnson 2007-11-28 14:20:42 UTC
(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.
Comment 10 Joseph Garvin 2009-06-08 21:18:40 UTC
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
Comment 11 Jonathan Wakely 2010-10-15 20:48:37 UTC
is this still a problem now that GCC defaults to setting the default march based on the configure target?