project_options
project_options copied to clipboard
Test '-march=native' support for all architectures and platforms
This flag fails on some ARM platforms including the Apple M1 (1, 2). We may be able to check whether it is supported by using clang -march=native -cx /dev/null
(1, 2) before adding to the compile options.
Upvote & Fund
-
I am using Polar.sh so you can upvote and help fund this issue. The funding is received once the issue is completed & confirmed by you.
-
Thank you in advance for helping prioritize & fund our backlog.
Is this supported on other compilers like GCC and MSVC?
I don't see the same problem with GCC. And I don't have an environment to test with MSVC.
I tested inside Godbolt, and it seems that GCC doesn't support it either!
gcc arm https://godbolt.org/z/G93d8qPed
clang arm https://godbolt.org/z/zfTcTbhG9
It also seems that /arch:native
doesn't actually work on MSVC.
https://godbolt.org/z/G3W1EqeMo
It seems it only accepts the exact instruction set like AVX https://docs.microsoft.com/en-us/cpp/build/reference/arch-x64
I found another issue while testing this.
I tested inside Godbolt, and it seems that GCC doesn't support it either!
gcc arm https://godbolt.org/z/G93d8qPed
clang arm https://godbolt.org/z/zfTcTbhG9
It also seems that
/arch:native
doesn't actually work on MSVC. https://godbolt.org/z/G3W1EqeMoIt seems it only accepts the exact instruction set like AVX https://docs.microsoft.com/en-us/cpp/build/reference/arch-x64
I'm glad you found that. Maybe my ARM machine is supported by GCC but not clang. The key is that not all ARM machines are supported by these two compilers with that flag.
I suspect that the reason why your GCC test on Godbolt doesn't work is that Godbolt uses cross-compiling on an x86_64 machine and the "native" flag means using the processor's features of the host machine for compiling code, which doesn't work if the toolchain is for Arm and you ask it to optimize for a different type of CPU (e.g., x86_64). Therefore, for cross-compiling, the flag should be explicit for a relevant type of CPU.
This article suggests that the optimization flag for x86 and Arm cannot be the same and we should use -mcpu for Arm and -march for x86: https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/compiler-flags-across-architectures-march-mtune-and-mcpu
If there is a deterministic and cross-platform way to do this, I will be open to doing that.
For GCC and clang, we can use [gcc/clang] -Werror [the test flag] -E -xc /dev/null
and check the return code.
For example, [gcc/clang] -Werror -march=native -E -xc /dev/null
or [gcc/clang] -Werror -mcpu=native -E -xc /dev/null
.
I guess MSVC will have a similar way to test, but I don't have the environment for testing.
Originally posted by @ljishen in https://github.com/cpp-best-practices/project_options/issues/98#issuecomment-1060233047
I found a project that does this! We can use that https://github.com/scivision/cmake-cpu-detect