"-march=native" possibly being misled on Debian i386?

Xi Ruoyao ryxi@stu.xidian.edu.cn
Sun Jun 11 11:33:00 GMT 2017

On 2017-06-11 09:29 +0200, Toby Douglass wrote:

> However, when I look in /usr/lib, I find this...
> /usr/lib/i386-linux-gnu

This is just Debian multiarch hierarchy specification.
Irrelevant with your issue.

> And now we come to the crux of the matter;
> If I run; "gcc -dM -E - < /dev/null | grep 86"
> I get this (re-ordered for clarity);
> #define __i586 1
> #define __i586__ 1
> #define __i386 1
> #define __i386__ 1
> #define i386 1
> The compiler thinks it's on a 586, rather than a 686, but that's okay.
> But when I use "-march=native", like so; "gcc -march=native -dM -E - <
> /dev/null | grep 86"
> I only get this!
> #define __i386 1
> #define __i386__ 1
> #define i386 1

In the first case, the architecture is decided by "--with-arch=" when
GCC was configured.

In the second case, the architecture is guessed by GCC driver.

Use "gcc [-march=native] -E -x c /dev/null -v".  And see the flag
"-march=xxx" passed to `cc1` by `gcc` to figure out the real
architecture GCC used.

> This is a problem for me.  I use these compiler defined macros to
> control a porting abstraction layer, which in turn uses atomic
> intrinsics.  The i386 has no atomic operations, the i486 has
> everything except double-word CAS, and i586 and higher has the lot.
> When I use "-march=native", building fails because the porting
> abstraction layer throws a #error (due to it being on an unsupportable
> target).
> Now, I may be completely wrong, but it looks to me where the OS is
> pretending to be i386, it's actually misleading the mechanism behind
> "-march=native".  There *is* no actual i686 Debian build, so I can't
> just use that instead of the i386 Debian.

No. I don't think so.  GCC is guessing the architecture for
"-march=native" using "cpuid" instruction on x86.  GCC doesn't
look at OS.

See the source code of
gcc_source/gcc/config/i386/driver-i386.c: host_detect_local_cpu.

> I want to use "-march=native" because it means the makefile selects
> the correct target for whomever is building.

I doubt it.  '__i386__' is defined for all 32-bit x86 architectures,
but '__i686__' is only for "-march=i686", not its 'subsets'.

For example, on my laptop (x86-64, multilib), I can use
"gcc -m32 -march=native". But then GCC guessed out
march=ivybridge" and the macro "__corei7_avx__" was defined,
instead of "__i686__".

> Any advice, insight, corrections, words of wisdom, etc?

I think it's better to use configuration script (maybe generated
by GNU autoconf) to get the architecture from several tests.
Xi Ruoyao <ryxi@stu.xidian.edu.cn>
School of Aerospace Science and Technology, Xidian University

More information about the Gcc-help mailing list