title: gcc: Differences between -march=native and -march=<specific arch>
body: <p>In order to compare which flags various <code>-march</code> settings will enable, I am comparing the outputs of the following commands, as detailed in <a href="https://stackoverflow.com/a/5470379/955273">this SO answer</a>:</p>
  <pre><code>$ gcc -Q -march=native         --help=target
  $ gcc -Q -march=skylake-avx512 --help=target
  </code></pre>
  <p>Please note, for the avoidance of doubt, the <em>detected</em> arch output from using <code>-march=native</code> is <code>skylake-avx512</code>.</p>
  <pre><code>$ gcc -Q -march=native --help=target | grep march
    -march=                           skylake-avx512
  </code></pre>
  <p>Most of the flags the two <code>-march</code> variants output match exactly.</p>
  <p><strong>However</strong>, there are a few differences:</p>
  <pre><code>$ diff &lt;(gcc -Q -march=native --help=target) &lt;(gcc -Q -march=skylake-avx512 --help=target)
  12c12
  &lt;   -mabm                               [enabled]
  &gt;   -mabm                               [disabled]
  119c119
  &lt;   -mpku                               [disabled]
  &gt;   -mpku                               [enabled]
  136c136
  &lt;   -mrtm                               [enabled]
  &gt;   -mrtm                               [disabled]
  138c138
  &lt;   -msgx                               [disabled]
  &gt;   -msgx                               [enabled]
  </code></pre>
  <p>It is these differences which have prompted me to ask this question.</p>
  <p>How does <code>-march=native</code> choose which instruction sets to enable and which to disable?</p>
  <p>I have the following conjecture:</p>
  <ul>
  <li><code>-march=native</code> will be using CPUID instructions to calculate supported instruction sets etc in order to detect the processor variant</li>
  <li><code>-march=foobar</code> will use a hardcoded list of instruction sets which processor <code>foobar</code> supports.</li>
  </ul>
  <p>If that is correct then I can see two possible ways this shakes out:</p>
  <p><strong>Option 1:</strong></p>
  <p>It is possible that <code>-march=native</code> may not get it 100% correct, whereas when a new processor is released, the table of supported instruction sets is updated, and is more likely to be correct.</p>
  <p>Therefore we would expect <code>-march=foobar</code> to be the &quot;more correct&quot; flag.</p>
  <p><strong>Option 2:</strong></p>
  <p><code>-march=native</code> will be using CPUID instructions to calculate supported instruction sets - and is therefore guaranteed to be correct, whereas <code>-march=foobar</code> will use a hardcoded list of instruction sets which may not be correct.</p>
  <p>Therefore we would expect <code>-march=native</code> to be the &quot;more correct&quot; flag.</p>
  <p>If <em>Option 2</em> is correct, one could surmise that using <code>-march=foobar</code> could end up with an unsupported instruction set enabled - and if the program were to emit these instructions result in a crash.</p>
  <p>I have thus far been unsuccessful in finding the answer as to whether either or any of the above is correct.</p>
  <p>If I want to target a specific arch, be sure all (and only) supported instruction sets are enabled, and am unable to use <code>-march=native</code>, what is the best way to do this?</p>