Target-features, target-cpu, LLVM, Clang and general confusion

I am trying to understand “target-feature” and how it relates to LLVM LLVM-IR and other things.

Usually when you create a target machine you provide cpu and features. From the code it seems both CPU and features can be used to derive target-features. It is unclear whether “cpu” is used for anything beyond the features.

Looking at Clang’s output in Godbolt however, setting -march=sandybridge (as an example) one sees that target-feature will be set to “+avx,+crc32,+cx16,+cx8,+fxsr,+mmx,+pclmul,+popcnt,+sahf,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+ssse3,+x87,+xsave,+xsaveopt” as the function attribute.

It’s unclear to me why this is set on the function and isn’t a property of the target machine.

And if -march isn’t set and one just compiles for x86-64 the function has the attributes:
“+cx8,+fxsr,+mmx,+sse,+sse2,+x87”, presumably picking x86-64-v1 as the default.

Things get stranger though. If one sets -march=sandybridge -no-sse. We then get:

Again here it’s unclear why there are things like “-avx512ifma”. It seems superfluous.

In fact, I would only expect these arguments to show up relative to features in the target machine. I.e. if the target machine is set to avx512ifma, then only in this case do we get “-avx512ifma”

I have a suspicion that this is indeed superfluous and that Clang either just outputs these in asm mode so that the IR can be correctly run even if a different target machine is initialized (but it’s not needed if when the code is emitted in the normal case)

However, I’d like to have this confirmed.

“cpu” is also used for turning.

I think this is mainly used for making a binary runable on multi targets. It’s useful for multi-versioning fucntions as well.

This makes the binary runable on most recent X86 targets.

We support turning off a single feature by option -mno-xxxx. The feature itself as well as all features depend on it will be turn off.

If a feature is required like -mavx512ifma, all its based features will be set too.