<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal" style="margin-left:.5in">I can't find any documentation *at all* for lzcntintrin.h, so I can find no suggestion that its __lzcnt* functions would have defined behavior on an input of 0.<span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><a name="_MailEndCompose"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></a></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">I think it's not the exact header so much as the functions themselves that we should care about.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Intel documents _lzcnt_u32/64 as returning operand size for 0 input. Ditto tzcnt.  Here's the lzcnt reference:<o:p></o:p></span></p>
<p class="MsoNormal"><a href="https://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-67C6440B-D49E-4D7C-98A2-667E47ED63CC.htm"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif"">https://software.intel.com/sites/products/documentation/doclib/iss/2013/compiler/cpp-lin/GUID-67C6440B-D49E-4D7C-98A2-667E47ED63CC.htm</span></a><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">Microsoft documentation claims that __lzcnt* returns the operand size for 0 input, while noting "If you run code that uses this intrinsic on hardware that does
 not support the lzcnt instruction, the results are unpredictable."<o:p></o:p></span></p>
<p class="MsoNormal"><a href="http://msdn.microsoft.com/en-us/library/vstudio/bb384809(v=vs.100).aspx"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif"">http://msdn.microsoft.com/en-us/library/vstudio/bb384809(v=vs.100).aspx</span></a><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D">--paulr<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt">
<div>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in">
<p class="MsoNormal"><b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif"">From:</span></b><span style="font-size:10.0pt;font-family:"Tahoma","sans-serif""> cfe-commits-bounces@cs.uiuc.edu [mailto:cfe-commits-bounces@cs.uiuc.edu]
<b>On Behalf Of </b>Richard Smith<br>
<b>Sent:</b> Monday, October 27, 2014 7:49 PM<br>
<b>To:</b> Sean Silva<br>
<b>Cc:</b> cfe-commits@cs.uiuc.edu<br>
<b>Subject:</b> Re: [PATCH][X86] __builtin_ctz/clz sometimed defined for zero input<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<div>
<div>
<p class="MsoNormal">On Mon, Oct 27, 2014 at 7:07 PM, Sean Silva <<a href="mailto:chisophugis@gmail.com" target="_blank">chisophugis@gmail.com</a>> wrote:<o:p></o:p></p>
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal">On Mon, Oct 27, 2014 at 5:20 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<o:p></o:p></p>
<div>
<div>
<div>
<div>
<div>
<p class="MsoNormal">On Sun, Oct 26, 2014 at 10:24 PM, Chandler Carruth <<a href="mailto:chandlerc@google.com" target="_blank">chandlerc@google.com</a>> wrote:<o:p></o:p></p>
<div>
<div>
<p class="MsoNormal">Sorry for the late replies, but as the last person to work on the CLZ / CTZ stuff, I have some small opinions here. =]<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<div>
<p class="MsoNormal">On Sun, Oct 26, 2014 at 9:52 PM, David Majnemer <<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>> wrote:<o:p></o:p></p>
<div>
<p class="MsoNormal">I think Paul's patch is fine.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I firmly disagree.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
<blockquote style="border:none;border-left:solid #CCCCCC 1.0pt;padding:0in 0in 0in 6.0pt;margin-left:4.8pt;margin-right:0in">
<div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Having `__builtin_ctz` asking the target if `isCLZForZeroUndef` seems busted and this patch seems to fix that just fine.<o:p></o:p></p>
</div>
</div>
</blockquote>
</div>
<p class="MsoNormal"><br>
Yes, that is busted and we should fix that aspect regardless. But changing the behavior on x86 seems actively harmful to portability.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">So, let's look at the history.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I went and taught LLVM to produce optimal code in cases where undef-at-zero was acceptable and only instructions with undef-at-zero were available. In order to generate reasonable code for these scenarios, Clang and LLVM had to respect
 the contract specified for the GCC __builtin_clz and __builtin_ctz. That spec[1] *very* clearly states that if the input is zero the result is undefined.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">1: <a href="https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">However, after this Bob changed ARM to not follow this spec citing a radar only in r149086. I objected at the time, and continue to feel this is the *wrong* approach for ARM. We should not be deviating from the clear, documented, and widely
 followed spec here. However, I had no real basis for arguing about the behavior of ARM at the time, and I doubt that I have much say in the behavior there even now. =] That said, on x86, I am firmly opposed to deviating from the clear and unambiguous spec.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If folks want a builtin to access unambiguously defined-at-zero CLZ or CTZ behavior, we should define *new* builtins which have a clear spec here. However, I'm unpersuaded that this is better or more portable. The alternative code seems
 quite palatable: (x == 0 ? 32 : __builtin_clz(x))<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">If LLVM fails to turn this into the maximally efficient code on some architecture, then much as others have suggested, we should enhance LLVM.<o:p></o:p></p>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal">I agree with Chandler on all points here.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">__builtin_clz and __builtin_ctz is clearly and unambiguously defined by GCC's specification for them, and we should not be providing additional definedness  guarantees. If we want a defined-for-zero-input form of these intrinsics, they
 should have a different name (or an additional argument, or be written as "x == 0 ? 32 : __builtin_clz(x)" or similar).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">It is a major feature of Clang that we try not to lock people in by providing incompatible extensions.<o:p></o:p></p>
</div>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
</div>
</div>
<div>
<p class="MsoNormal">Curiously, it looks like GCC is depending on definedness for 0 in its own headers: <a href="https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/lzcntintrin.h" target="_blank">https://github.com/gcc-mirror/gcc/blob/master/gcc/config/i386/lzcntintrin.h</a><o:p></o:p></p>
</div>
</div>
</div>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I can't find any documentation *at all* for lzcntintrin.h, so I can find no suggestion that its __lzcnt* functions would have defined behavior on an input of 0. And apparently MSVC doesn't actually guarantee to give the width on a zero
 input for these (if you have BSR but not LZCNT it'll use BSR instead and give you an unspecified result), so we cannot deduce that either lzcntintrin.h nor Intrin.h should give a defined result on zero input to these functions, unless someone has other evidence
 hidden away somewhere.<o:p></o:p></p>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>