<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Oct 26, 2014 at 5:56 PM, Robinson, Paul <span dir="ltr"><<a href="mailto:Paul_Robinson@playstation.sony.com" target="_blank">Paul_Robinson@playstation.sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">





<div lang="EN-US" link="blue" vlink="purple">
<div>
<p class="MsoNormal"><a name="1494f1af4ec367fc__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">I don't know about the "public" contract, but Clang's own lzcntintrin.h uses __builtin_clz without a runtime zero check, protected
 by the __LZCNT__ preprocessor define.  So Clang's own headers are assuming that __builtin_clz will be treated as defined for zero input on these machines.  That makes my patch a correctness fix, not 'just' an optimization.</span></a></p></div></div></blockquote><div><br></div><div>I think that the header is using __LZCNT__ more along the lines of "you can't use this header if you don't have __LZCNT__", rather than "these builtins won't work right without __LZCNT__". I would describe the situation as "__lzcnt* intrinsics incorrectly implemented". Now that I think about the situation in our internal bugzilla, our replies on the bugs regarding behavior of __builtin_clz(0) should have just been "if you want the LZCNT instruction, then use <lzcntintrin.h>" (and then the next bug would have been "__lzcnt* are incorrectly implemented", which is currently the case).</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div lang="EN-US" link="blue" vlink="purple"><div><p class="MsoNormal"><a name="1494f1af4ec367fc__MailEndCompose"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u><u></u></span></a></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">If you use Clang's intrinsics (either the ones from Intrin.h or the ones from lzcntintrin.h) you shouldn't need to add your own zero checks; but that's the
 public contract for the intrinsics, not the builtins.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">If we leave __builtin_clz defined as-is, you should always add your own zero check; on appropriate machines sometimes Clang will be able to tell and optimize
 it away.  But that's target-dependent and I don't know that it would be all that smart to codify that target-dependent behavior as part of the public contract.<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)">--paulr<u></u><u></u></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:Calibri,sans-serif;color:rgb(31,73,125)"><u></u> <u></u></span></p>
<div style="border-style:none none none solid;border-left-color:blue;border-left-width:1.5pt;padding:0in 0in 0in 4pt">
<div>
<div style="border-style:solid none none;border-top-color:rgb(181,196,223);border-top-width:1pt;padding:3pt 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10pt;font-family:Tahoma,sans-serif">From:</span></b><span style="font-size:10pt;font-family:Tahoma,sans-serif"> Sean Silva [mailto:<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>]
<br>
<b>Sent:</b> Friday, October 24, 2014 5:46 PM<br>
<b>To:</b> Arthur O'Dwyer<span class=""><br>
<b>Cc:</b> Robinson, Paul; <a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<b>Subject:</b> Re: [PATCH][X86] __builtin_ctz/clz sometimed defined for zero input<u></u><u></u></span></span></p>
</div>
</div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
<div>
<p class="MsoNormal">On Fri, Oct 24, 2014 at 4:53 PM, Arthur O'Dwyer <<a href="mailto:arthur.j.odwyer@gmail.com" target="_blank">arthur.j.odwyer@gmail.com</a>> wrote:<u></u><u></u></p><div><div class="h5">
<p class="MsoNormal">On Fri, Oct 24, 2014 at 3:55 PM, Sean Silva <<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>> wrote:<br>
><br>
> What is the harm of documenting it? By defining this behavior we are<br>
> pledging to forever support it.<br>
<br>
Exactly. That's harm enough, isn't it?<u></u><u></u></p>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">It looks like clang already has precedent for doing this, and a corresponding infrastructure for doing so, so it shouldn't be too problematic.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal"><br>
<br>
>> This allows us to optimize<br>
>>   unsigned foo(unsigned x) { return (x ? __builtin_clz(x) : 32) }<br>
>> into a single LZCNT instruction on a BMI-capable X86, if we choose.<br>
<br>
I'm no expert, but isn't this kind of peephole optimization supposed<br>
to be handled by the LLVM (backend) side of things, not the Clang<br>
side?<u></u><u></u></p>
</blockquote>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<p class="MsoNormal">It's not an optimization that is being talked about here. It's a change of semantic meaning to define a previously undefined situation. Presumably it's a win for the user that thinks that __builtin_clz means "the best clz-like instruction
 available for the target", rather than the independently defined meaning given in the docs.<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
<div>
<div>
<p class="MsoNormal">-- Sean Silva<u></u><u></u></p>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
</div>
<div>
<p class="MsoNormal"> <u></u><u></u></p>
</div>
<blockquote style="border-style:none none none solid;border-left-color:rgb(204,204,204);border-left-width:1pt;padding:0in 0in 0in 6pt;margin-left:4.8pt;margin-right:0in">
<p class="MsoNormal"><br>
The behavior of __builtin_clz(0) is undefined, so no portable program<br>
can use it. Sure, it might happen to work on your machine, but then<br>
you switch to a different architecture, or even a slightly older x86,<br>
or a year from now Intel introduces an *even faster* bit-count<br>
instruction that yields the wrong value for 0... and suddenly your<br>
program breaks, and you have to waste time tracking down the bug.<br>
<br>
Therefore, portable programs WILL use<br>
<br>
   unsigned foo(unsigned x) { return (x ? __builtin_clz(x) : 32) }<br>
<br>
Therefore, it would be awesome if the LLVM backend for these<br>
particular Intel x86 machines would generate the most-optimized LZCNT<br>
instruction sequence for "foo". This seems relatively easy and<br>
shouldn't involve any changes to the Clang front-end, and *certainly*<br>
not to the documentation.<br>
<br>
Then you get the best of both worlds — old portable code continues to<br>
work (but gets faster), and newly written code continues to be<br>
portable.<br>
<br>
Andrea wrote:<br>
>> > My concern is that your suggested approach would force people to<br>
>> > always guard calls to __builtin_ctz/__builtin_clz against zero.<br>
>> > From a customer point of view, the compiler knows exactly if ctz and<br>
>> > clz is defined on zero. It is basically pushing the problem on the<br>
>> > customer by forcing them to guard all the calls to ctz/clz against<br>
>> > zero. We've already had a number of customer queries/complaints about<br>
>> > this and I personally don't think it is unreasonable to have ctz/clz<br>
>> > defined on zero on our target (and other x86 targets where the<br>
>> > behavior on zero is clearly defined).<br>
<br>
Sounds like a good argument in favor of introducing a new builtin,<br>
spelled something like "__builtin_lzcnt", that does what the customer<br>
wants. It could be implemented internally as (x ? __builtin_clz(x) :<br>
32), and lowered to a single instruction if possible by the LLVM<br>
backend for your target.<br>
<br>
my $.02,<br>
–Arthur<u></u><u></u></p>
</blockquote>
</div></div></div>
<p class="MsoNormal"><u></u> <u></u></p>
</div>
</div>
</div>
</div>
</div>

</blockquote></div><br></div></div>