In GCC and Clang, there are three major options specifying the architecture and microarchitecture the generated code can run on. The general semantics are described below, but each target machine may assign different semantics.
-march=X: (execution domain) Generate code that can use instructions available in the architecture X
-mtune=X: (optimization domain) Optimize for the microarchitecture X, but does not change the ABI or make assumptions about available instructions
-mcpu=X: Specify both
-mtune=but can be overridden by the two options. The supported values are generally the same as
-mtune=. The architecture name is inferred from
Below are some notes about GCC's implementation.
AArch32 follows the general description.
-march=name[+extension...] may specify architecture extensions.
AArch64 follows the general description.
gcc/config/aarch64/aarch64.cc:aarch64_validate_march verifies that
-march= specifies a value defined in
gcc/config/aarch64/aarch64.cc:aarch64_validate_mtune verifies that
-mtune= specifies a value defined in
The selected architecture is stored in
TargetVariable). The selected tune microarchitecture is stored in
-march= supports generic ISA names and processor names.
-mcpu= is not implemented in GCC.
-march= is not implemented in GCC.
% powerpc64le-linux-gnu-gcc -fsyntax-only -march=power10 a.c
powerpc64le-linux-gnu-gcc: error: unrecognized command-line option ‘-march=power10’; did you mean ‘-mcpu=power10’?
RISC-V follows the general description.
-mtune= must specify an element in
gcc/config/riscv/riscv-cores.def. The default
-mcpu= value is
-mcpu= does not seem to infer
-march= in GCC.
-mcpu= has been deprecated since 2003-02. It is an alias for
-march= specifies a cpu-type. cpu-type is a microarchitecture name (e.g.
znver3), a microarchitecture level (
-march=native enables all instruction subsets supported by the local machine and recognized by the GCC version.
-mtune= is not specified, use the
-march= value (if a microarchitecture name) or
% gcc -Q --help=target -march=skylake a.c |& grep --color 'march\|mtune\|mcpu'
Known valid arguments for -march= option:
Known valid arguments for -mtune= option:
-mtune= must specify an element in
-mtune= must specify an element without the
-mtune= decides features in
% gcc -c -mdump-tune-features a.c
List of x86 specific tuning parameter names:
schedule : on
partial_reg_dependency : on
sse_partial_reg_dependency : on
sse_split_regs : off
-mtune= decides instruction costs
-mtune= defines some built-in macros
x86-64, x86-64-v2, x86-64-v3, x86-64-v4
The x86-64 psABI defines some microarchitecture levels. They are a very small set of choices suitable for a Linux distribution default with a neutral name (i.e. not tied to an AMD or Intel microarchitecture name). See New x86-64 micro-architecture levels for the original proposal on libc-alpha.
One major use case is glibc's hwcap support for x86-64.
x86-64-v4 for Clang.
For the simplest case where only one option is desired, use
-march= for x86 and
-mcpu= for other targets.
When optimizing for the local machine, just use
-march=native for x86 and
-mcpu=native for other targets.
When the architecture and microarchitecture are both specified, i.e. when both the execution domain and the optimization domain need to be specified, specify
-mtune=, and avoid
-mcpu=. On PowerPC, specify both
Clang driver parses
-mtune=, and pass
-target-feature to cc1.
-mtune= mostly affects
MCSubtargetInfo::CPUSchedModel and target features.
For each target,
-mcpu=native is implemented by
--target= to set the target triple (for cross compilation). The specified target should be built into Clang (see
LLVM_EXPERIMENTAL_TARGETS_TO_BUILD). See Compiler driver and cross compilation.
--target=aarch64-unknown-linux-gnu -mcpu=X can be used to cross compile for AArch64 and optimize for the microarchitecture X.
GCC 4.4 added the function attribute
target for x86.
__attribute__((target(arch=k8))) is supported to override
-march= for a function. GCC 4.8 extended the syntax with
"default" which is then named function multi-versioning.
-mtune= are optionally supported by various ports.
-march= is defined, the assembler will report an error when assembling an instruction not supported by the specified architecture.
-mtune= is implemented for mips, ia64, visium, and x86. In the x86 port
-mtune= just decides the desired NOP sequence. In the ia64 port
-mtune= does some complex scheduling.
Clang does not support
-Wa,-mtune=. I dropped a glibc use in i386: Remove -Wa,-mtune=i686.