difference between --target, -mcpu, -march

I’m confused about the clang --target, -mcpu, -march

Can someone give a clear explanation on what is the difference between them?

Originally I thought need to specify -mcpu (which I assume means CPU) and -march but then I can’t figure out how --target fits into the picture. Sometimes it tells me that -march or -mcpu options is not used. I would really appreciate any help on this.

I’m confused about the clang --target, -mcpu, -march

Can someone give a clear explanation on what is the difference between them?

I can try :slight_smile:

Originally I thought need to specify -mcpu (which I assume means CPU) and -march but then I can’t figure out how --target fits into the picture. Sometimes it tells me that -march or -mcpu options is not used. I would really appreciate any help on this.

Let’s say you’re on an x86_64-linux-gnu machine (basically any linux machine) and you want to compile some code for a haswell specific binary, you’d use:

clang -march=haswell foo.c

Which tells clang to use the current host as the “OS” for your compile and to tell the backend to generate haswell specific code.

Let’s say you instead want to compile for arm-linux-gnu (just your basic arm linux machine), you’d use:

clang -target arm-linux-gnu foo.c

I’m glossing over this a bit because it’s not relevant to what you asked, but the other options there are going to be things like a sysroot where you can get the headers and libraries for an arm-linux-gnu machine, because they’re likely not installed on your x86_64-linux-gnu machine.

Now, let’s say you want to target a specific arm processor as part of your cross compile, you’d do this:

clang -target arm-linux-gnu foo.c -mcpu=armv7

or you could do this:

clang -target armv7-linux-gnu foo.c

this is partially because of legacy reasons, and partially because arm is weird here. The -mcpu and -march options are very similar in clang. In general, they’re setting the processor you’re compiling your code to run on. (Arm is even weirder here so I’m glossing over a lot of details).

The reasons behind this are largely historical and option compatibility with gcc. If you’ve done cross compilation with gcc all that the --target option does in clang is select at runtime the same thing that you’d use --target for on the configure line.

Make sense?

-eric

It somewhat makes sense. Basically one has to know very well what options
to use for their specific target. It looks like at the moment there is no
consistency.

-Most- targets use -march.

-eric

-Most- targets use -march.

-eric

Do you meat that in most cases -target is used along with -march instead of
-target and -mcpu?

Yes and no. By target here I just mean the architecture being targeted and that most of them use the -march option rather than -mcpu. Which makes what you said a consequence of that. :slight_smile:

Would it be fair to say that an -march chooses an instruction set, while -mcpu will affect scheduling things such as how many instructions can be run in parallel and their latency etc?

I actually use -m32 or -mthumb more than anything else :slight_smile:

From what I remember, the meaning of march/mcpu differs between clang and LLVM's utilities (llc, etc.) In clang, mcpu and march have a lot of overlap in terms of usage, and it seems to differ from one target to the next. What you say would make sense, but, for example, we have legacy code that used -march=hexagonv5, where "hexagonv5" is actually a CPU version, something that intuitively should belong in "mcpu". Hexagon doesn't seem to be the only one where "march" and "mcpu" are treated almost identically, I saw what looked like CPU names in the march string in other toolchains as well.

The clang documentation states:

   Target Selection Options