-1

I am using a third party x86_64 assembler that do not recognise kmov instructions (it only supports a subset of the x86_64 instruction set).

The assembler is fed assembly files generated by GCC 5.1 (I can't change the version), then it parses and assembles the code to generate ELF object files. It can compile fairly large code bases.

I am trying to compile a very simple plain C code base, but GCC keeps generating kmov instructions. I searched a little bit and it looks like they are AVX512 extensions but I am not sure about it!

I am looking for a way to tell GCC not to generate those instructions. I used those GCC options:

-mno-avx -mno-sse -mno-sse2 -mno-mmx -mno-fma

But it is still generating them! So what are those kmov instructions? And how can I tell GCC 5.1 to not generate them?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Karim Manaouil
  • 1,177
  • 10
  • 24
  • 1
    Can you determine the complete command line that is being passed to gcc? Can you compile with `-v -Q` to get the complete list of all options that are in effect? – Nate Eldredge Nov 11 '21 at 05:41
  • @NateEldredge the complete GCC command used is `gcc -S -Wall -Wundef -Wstrict-prototypes -fno-strict-aliasing -Werror-implicit-function-declaration -Wno-format-security -fno-delete-null-pointer-checks -O2 -funit-at-a-time -mno-mmx -mno-sse -mno-sse2 -mno-3dnow -mno-avx -mno-fma` – Karim Manaouil Nov 11 '21 at 05:53
  • 4
    Can you show a [mcve] with source and the resulting asm, reproducing this on https://godbolt.org/? GCC definitely won't use `kmov` if you haven't used `-march=skylake-avx512` or `-mavx512f` or something. (But `-mno-avx` and `-mno-sse` both imply `-mno-avx512f`). The only way for `kmov` to be present in the asm output with those options would be from an inline `asm()` statement. – Peter Cordes Nov 11 '21 at 06:09
  • @PeterCordes I tried but I could not reproduce it in a small self-contained function on godbolt. I have to compile the whole ~2000L source file with the include headers. I tried `-march=core2` to force the compiler to not consider anything related to AVX but I get `cmov`instructions, which are again not supported. Is there a way to turn off conditional moves on GCC? – Karim Manaouil Nov 11 '21 at 16:41
  • 2
    `cmov` is an entirely different situation from `kmov` - every x86-64 CPU is supposed to support it. If your assembler can't do it then it is severely broken. https://stackoverflow.com/questions/60019582/conditional-move-cmov-in-gcc-compiler suggests that `-fno-if-conversion -fno-if-conversion2` might disable them, but I doubt that you can reliably count on it. – Nate Eldredge Nov 11 '21 at 16:45
  • @KarimManaouil: To try to get down to a smaller example, you can start by preprocessing your source file with `gcc -E`, so that everything from the headers is included. Identify one function whose output has the offending `kmov`, then remove all the other functions, then start removing unrelated stuff from that function. It may help if you can first reproduce the problem without `-funit-at-a-time`, as this will make functions less interdependent on each other's compilation. – Nate Eldredge Nov 11 '21 at 16:48
  • 1
    Inter `cmov` conditional move??? Like `cmovge eax, edx`? That's a completely different question from `kmov`, so you should edit this accordingly. `cmov` is baseline for x86-64 (and thus required for any x86-64 assembler, and no way to tell GCC that it's not available other than editing the machine-description files and rebuilding GCC from source). It was new for 32-bit mode in PPro. If you're building 32-bit code, you can use `-march=pentium -mtune=haswell`. – Peter Cordes Nov 11 '21 at 17:16
  • @NateEldredge: Disabling if-conversion will remove some sources of conditional move, but it might still be present in some canned sequences for things. A simple ternary still compiles to `cmov` with both those no-if-conversion options: https://godbolt.org/z/hhn9hsWEa – Peter Cordes Nov 11 '21 at 17:21
  • Probably less work to just stop using that crappy assembler than to build a version of GCC5.1 which won't emit `cmov` for 64-bit code. Or fix that toy assembler to support at least cmov, and any other common missing instructions. – Peter Cordes Nov 11 '21 at 17:23
  • @PeterCordes Sorry for the confusion! The original issue is with `kmov`. As a way to get ride of them, I compiled with `-march=core2`, which effectively did the job and didn't generate `kmov`, but it, instead, generated `cmov` in other places, and `cmov` is also not supported by the assembler. – Karim Manaouil Nov 11 '21 at 17:53
  • @NateEldredge `-fno-if-conversion -fno-if-conversion2` did the job, and the compilation succeeded. No `kmov` and no `cmov` were generated. You may want to post that as an answer. – Karim Manaouil Nov 11 '21 at 17:56
  • 2
    I guess your gcc was configured for a really weird default target somehow, which is the only explanation I can imagine for how it would emit `kmov` without any options to specifically request it. It's especially strange because when GCC 5.1 was released, there were not yet any actual devices on the market that supported AVX-512. As for `cmov`, I don't really think the `-fno-if-conversion` options are a good solution because as Peter says they won't prevent `cmov` in every instance, and minor tweaks to your code might result in having `cmov` anyway. – Nate Eldredge Nov 11 '21 at 18:03
  • 1
    Really, it sounds like your toolchain is ancient, bizarrely configured, and broken in several different ways. The right fix is not these fragile workarounds, but to migrate to a toolchain that is actually fully functional. – Nate Eldredge Nov 11 '21 at 18:04
  • @NateEldredge I omitted technical details to make the post generic and focus on the question. But if you want to know, the code base is an embedded OS I wrote at my University and the targeted architecture is the somehow x86-64-compatible Knights Corner architecture (a.k.a KNC or Xeon Phi 5100). The toolchain is a modified GNU toolchain from Intel to prevent generating unsupported KNC instructions and with support for 512b vector extension of KNC. – Karim Manaouil Nov 11 '21 at 18:30
  • If you doubt that `kmovs` are related to the 512b vector extensions of KNC, then I have already compiled with `-mno-knc` and I still got them!! Super weird annoying toolchain!! – Karim Manaouil Nov 11 '21 at 18:32
  • 1
    I see. It's really important information that this is not stock GCC 5.1, but Intel's patched version. I wish you had stated that in the original question, it would have saved a lot of time. Stock GCC with your options would not have emitted the `kmov` instructions in the first place. – Nate Eldredge Nov 11 '21 at 18:35
  • @NateEldredge This is one of the reasons why I wanted to omit the details, because it makes the question very specific, and it discourages contributions. But, instead, it can be framed generically, as I did, and then could be adapted to any personal situation. Thanks for your time, very much appreciated! – Karim Manaouil Nov 11 '21 at 19:29
  • @KarimManaouil Without details, the question cannot be answered. Always specify the exact toolchain you are programming for. – fuz Nov 14 '21 at 20:42

1 Answers1

2

As @Peter Cordes pointed out, specifying -mno-avx -mno-sse should be sufficient to tell GCC not to generate kmov instructions. The only way for kmov to be present in the asm output with those options would be from an inline asm().

Karim Manaouil
  • 1,177
  • 10
  • 24