I stumped across this change from
https://github.com/riscv-non-isa/riscv-toolchain-conventions/issues/88
and I want to express my strong disagreement with this change.
Perhaps I'm accustomed to Arm's behavior, but I believe using -march= to
target a specific CPU isn't ideal.
* -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 -march= and -mtune= but can be overridden by the two
options. The supported values are generally the same as -mtune=. The
architecture name is inferred from X
For execution domain settings, -march=X overrides -mcpu=X regardless of their
positions.
In cases like `-march=LOWER -mcpu=HIGHER` or `-mcpu=HIGHER -march=LOWER`, the
-march= option can disable certain target features.
I strongly disagree with Clang adopting this behavior.
I'm not convinced by the GCC patch explanation.
Suppose we have a Makefile that specifies -march=rv64gc by default.
In the project specifies a lower feature set, then the compiler should
respect it or the user should fix the project build system.
There are two reasons for the change:
- Adhere to the usual "last option wins" convention and at the same time
- Make it easy to specify an overriding -march string representing a CPU
without spelling out the >200 char expanded arch string, a very error-prone
procedure.
I agree that fixing the "project build system" might be another way of having
only a single -march in a compiler command line but it doesn't match my
experience. Over the years I have seen a significant number of projects where
multiple -marchs where present. With the "last option wins" convention this
works and a user always has a "last ditch" way of setting their preferred
architecture.
A typical use case is a default march that is overridden by CFLAGS. There's
nothing to be fixed here because it's standard procedure. In that situation we
would always need the full -march string and that can't be what we want?
What's your main concern? The less clear separation between arch and CPU?
I don't think the change takes anything away from -march but just adds a
shortcut "set the arch level to what this CPU supports". That's fully in line
with what other targets are doing, also on the clang side.
Ideally (IMHO) we'd also imply an -mtune when specifying -march by default
rather than using -mtune=rocket or so.
If we had an -mcpu=... that overrode -march and -mtune we'd already have a good
way of achieving what I intended. In that case -march wouldn't need to be
changed but to my understanding this has been unwanted so far. For me a "last
option wins" -mcpu that overrides march and mtune would also work and would
keep the clear separation between -march and -mtune.
--
Regards
Robin