Reputation: 1244
If we query what -march=native
expands to, the result seems as it should be
$ gcc -Q -march=native --help=target | grep -E '^\s+-.*(sse|march)'
-march= corei7-avx
-mno-sse4 [disabled]
-msse [enabled]
-msse2 [enabled]
-msse2avx [disabled]
-msse3 [enabled]
-msse4 [enabled]
-msse4.1 [enabled]
-msse4.2 [enabled]
-msse4a [disabled]
-msse5
-msseregparm [disabled]
-mssse3 [enabled]
But if the architecture is specified directly, gcc drops the SSE flags it would enable for native
, why?
$ gcc -Q -march=corei7-avx --help=target | grep -E '^\s+-.*sse'
-mno-sse4 [enabled]
-msse [disabled]
-msse2 [disabled]
-msse2avx [disabled]
-msse3 [disabled]
-msse4 [disabled]
-msse4.1 [disabled]
-msse4.2 [disabled]
-msse4a [disabled]
-msse5
-msseregparm [disabled]
-mssse3 [disabled]
Compilation with -march=corei7-avx
, however, shows, that they’ll be enabled.
$ echo | gcc -march=corei7-avx -dM -E - | grep -i sse
#define __SSE4_1__ 1
#define __SSE4_2__ 1
#define __SSE2_MATH__ 1
#define __SSE_MATH__ 1
#define __SSE2__ 1
#define __SSSE3__ 1
#define __SSE__ 1
#define __SSE3__ 1
Upvotes: 6
Views: 1521
Reputation: 1719
This is a known bug in GCC (39851); it has been open since GCC 4.5 in 2009.
Upvotes: 3
Reputation: 98446
I'm guessing a bit but anyway, this is too long for a commentary...
Take a look at the output of this command:
$ echo | gcc -march=native -v -x c -c -
And this other:
$ echo | gcc -march=corei7-avx -v -x c -c -
The interesting part is the call to the cc1
binary. In the -march=native
case it is replaced by all the target options, not just the equivalent -march
one. I have a sandybridge
, so in my machine it gives:
.../cc1 -march=sandybridge -mmmx -mno-3dnow -msse -msse2 -msse3 -mssse3 \
-mno-sse4a -mcx16 -msahf -mno-movbe -mno-aes -mno-sha -mpclmul \
-mpopcnt -mno-abm -mno-lwp -mno-fma -mno-fma4 -mno-xop ...
Whereas when you add the -march=corei7-avx
or (-march=sandybridge
in my case) there is none of those specific architecture options.
Now my conclusion:
The output of -Q --help=target
tell whether the given compiler options are set, not if feature is actually enabled or not. As is happens, some of these features can be enabled or disabled in different ways.
For example, SSE can be enabled with -msse
, and also with -march=corei7-avx
or -march=sandybridge
. But although specifying -march=corei7-avx
enables SSE, it does not set the -msse
options per se.
On the other hand -march=native
sets a lot of options, not only the actual -march
but also any other relevant option that can be fetched from the runtime system, such as cache sizes.
The proper way to check if a specific feature is on or off is, as you already noticed, checking the predefined defines
.
Upvotes: 3