<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><span class="vcard"><a class="email" href="mailto:craig.topper@gmail.com" title="Craig Topper <craig.topper@gmail.com>"> <span class="fn">Craig Topper</span></a>
</span> changed
          <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - <intrin.h> does not declare _tzcnt_u32"
   href="https://bugs.llvm.org/show_bug.cgi?id=30506">bug 30506</a>
          <br>
             <table border="1" cellspacing="0" cellpadding="8">
          <tr>
            <th>What</th>
            <th>Removed</th>
            <th>Added</th>
          </tr>

         <tr>
           <td style="text-align:right;">Status</td>
           <td>NEW
           </td>
           <td>RESOLVED
           </td>
         </tr>

         <tr>
           <td style="text-align:right;">Resolution</td>
           <td>---
           </td>
           <td>FIXED
           </td>
         </tr></table>
      <p>
        <div>
            <b><a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - <intrin.h> does not declare _tzcnt_u32"
   href="https://bugs.llvm.org/show_bug.cgi?id=30506#c6">Comment # 6</a>
              on <a class="bz_bug_link 
          bz_status_RESOLVED  bz_closed"
   title="RESOLVED FIXED - <intrin.h> does not declare _tzcnt_u32"
   href="https://bugs.llvm.org/show_bug.cgi?id=30506">bug 30506</a>
              from <span class="vcard"><a class="email" href="mailto:craig.topper@gmail.com" title="Craig Topper <craig.topper@gmail.com>"> <span class="fn">Craig Topper</span></a>
</span></b>
        <pre>I've removed the __BMI__ check on these intrinsics in r374516. But I don't
think it really accomplishes what ffmpeg wanted.

On real MSVC, using _tzcnt_u32 blindly emits the F3 0F BC tzcnt encoding which
is equivalent to rep+bsf. MSVC doesn't have a concept of enabling features on
the command line. Using an intrinsic always generates the instruction. On
legacy prefixes, the f3 prefix is ignored and the behavior for an input of 0
won't match tzcnt. ffmpeg knows this, but doesn't send 0 so this fine.

clang on the other hand has CPU features. We turn the _tzcnt_u32 intrinsic into
llvm.cttz in IR with a defined behavior for 0. If tzcnt isn't enabled on the
command line, the backend has to emulate the 0 behavior and we won't emit the
tzcnt instruction. So we end up with bsf+cmov and a few other instructions.
Worse than the code we would have gotten if ffmpeg had just used __builtin_ctz
which is undefined for 0 and would just generate a bsf.

If I recall correctly gcc will emit __builtin_ctz as rep+bsf with certain
-march options possibly including the default. Specifically written that way to
support older versions of binutils that don't support tzcnt mnemonic since the
user never mentioned tzcnt anywhere. On CPUs that support tzcnt this will
decode as tzcnt on older CPUs it will be treated as bsf. tzcnt has better
throughput on some AMD CPUs than bsf. Which is probably the very reason ffmpeg
used the tzcnt intrinsic instead of the bsf intrinsic?</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>