<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=us-ascii">
<meta name=Generator content="Microsoft Word 12 (filtered medium)">
<title>Message</title>
<style>
<!--
 /* Font Definitions */
 @font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@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:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-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;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
span.EmailStyle18
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle19
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page Section1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.Section1
        {page:Section1;}
-->
</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=Section1>

<p class=MsoNormal><span style='color:#1F497D'>Hi Marc,<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>Thanks a lot for the detailed
explanation!<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>For the record and for my own
reference: If the ZF (zero flag) is 0 we know for certain the arguments are not
equal (!=). If the ZF is 1 they are either equal or unordered. The PF
determines whether any argument is NaN. So for equality (==) we need to check
two flags if we care about the unordered case.<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>I was also thrown off by LLVM’s
use of ucomiss instead of comiss, but it has nothing to do with the compares
themselves, only whether or not an exception is thrown for QNaNs. So for the
best optimization opportunity I should always use unordered compares in LLVM,
right?<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>Thanks again!<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>Nicolas<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'>

<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"'>
llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu] <b>On Behalf
Of </b>Marc B. Reynolds<br>
<b>Sent:</b> Tuesday, 27 May, 2008 18:49<br>
<b>To:</b> 'LLVM Developers Mailing List'<br>
<b>Subject:</b> Re: [LLVMdev] Float compare-for-equality andselect
optimizationopportunity<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif"'> <o:p></o:p></span></p>

</div>

<blockquote style='margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt'>

<p class=MsoNormal><span style='color:#1F497D'>Hi Marc,<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'>I’m a bit confused.
Isn’t the standard compare (i.e. the one for a language like C) an
ordered one? I tried converting some C code to LLVM C++ API code with the
online demo, and it uses FCMP_OEQ…<o:p></o:p></span></p>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>No, if you have:</span><span style='font-size:12.0pt;font-family:
"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>  x = NaN </span><span style='font-size:12.0pt;font-family:
"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>  y = NaN</span><span style='font-size:12.0pt;font-family:
"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>then the comparison:</span><span style='font-size:12.0pt;
font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>  (x == y) is false.</span><span style='font-size:12.0pt;
font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>Which is what your seeing from your first post and is the standard
IEEE expected behavior.</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>Why I expected your min/max question to be related, consider
the flags of  'comiss, ucomiss, etc.' :</span><span style='font-size:
12.0pt;font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>                           
ZPC</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'>    </span><span style='font-size:10.0pt;
font-family:"Arial","sans-serif";color:blue'>unordered         
111</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'>    </span><span style='font-size:10.0pt;
font-family:"Arial","sans-serif";color:blue'>greater
than       000</span><span style='font-size:
12.0pt;font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>    less
than           001</span><span
style='font-size:12.0pt;font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>   
equal               
100</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>Try the following C program with gcc, first with no options and
then with --ffinite-math-only (or --ffast-math)</span><span style='font-size:
12.0pt;font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>-----------</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><br>
</span><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>#define STR(X) #X<br>
#define CMP(X) if (X) { printf(STR(X) " true\n"); } else {
printf(STR(X) " false\n"); }</span><span style='font-size:12.0pt;
font-family:"Times New Roman","serif";color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>int main(int argc, char** argv)<br>
{<br>
  float a = 0.f/0.f;   // generate a NaN <br>
  float b = 1;         // any
finite </span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>  CMP(a!=a);<br>
  CMP(a==a);<br>
  CMP(a> b);<br>
  CMP(a>=b);<br>
  CMP(a< b);<br>
  CMP(a<=b);<br>
  CMP(a!=b);</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'> <o:p></o:p></span></p>

</div>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>  return 0;<br>
}<br>
------------------------</span><span style='font-size:12.0pt;font-family:"Times New Roman","serif";
color:#1F497D'><o:p></o:p></span></p>

</div>

<p class=MsoNormal><span style='color:#1F497D'><o:p> </o:p></span></p>

<div>

<div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'>

<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"'>
llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu] <b>On Behalf
Of </b>Marc B. Reynolds<br>
<b>Sent:</b> Tuesday, 27 May, 2008 14:07<br>
<b>To:</b> 'LLVM Developers Mailing List'<br>
<b>Subject:</b> Re: [LLVMdev] Float compare-for-equality and select
optimizationopportunity<o:p></o:p></span></p>

</div>

</div>

<p class=MsoNormal><o:p> </o:p></p>

<div>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:"Arial","sans-serif";
color:blue'>Both ZF and PF will be set if unordered, so the code below is IEEE
correct...you want to generate 'fcmp ueq' instead of 'fcmp oqe'</span><span
style='font-size:12.0pt;font-family:"Times New Roman","serif"'><o:p></o:p></span></p>

</div>

<blockquote style='margin-top:5.0pt;margin-right:0cm;margin-bottom:5.0pt'>

<p class=MsoNormal>This is the resulting x86 assembly code:<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>movss      
xmm0,dword ptr [ecx+4] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span lang=NL-BE
style='font-size:8.0pt;font-family:"Courier New";color:gray'>ucomiss    
xmm0,dword ptr [ecx+8] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span lang=NL-BE
style='font-size:8.0pt;font-family:"Courier New";color:gray'>sete       
al   <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>setnp      
dl   <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>test       
dl,al <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
edx,edi <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmovne     
edx,ecx <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmovne     
ecx,esi <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmovne     
esi,edi</span><o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>While I’m pleasantly surprised that my branch does get
turned into several select operations as intended (cmov - conditional move
– in x86), I’m confused why it uses the ucomiss instruction
(unordered compare and set flags). I only used IRBuilder::CreateFCmpOEQ. It
also appears to invert the conditional, for no clear reason. I think it could
be rewritten as follows:<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>movss      
xmm0,dword ptr [ecx+4] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>comiss    
 xmm0,dword ptr [ecx+8] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
edx,edi <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmove     
 edx,ecx <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmove     
 ecx,esi <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmove     
 esi,edi</span><o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Compared to the original C syntax code this looks pretty
straightforward. Curiously, when I replace the compare-for-equality with
something like a less-than, it does generate such compact code (using <span
style='font-size:8.0pt;font-family:"Courier New";color:gray'>comiss</span> and <span
style='font-size:8.0pt;font-family:"Courier New";color:gray'>cmova</span>). And
the not-equal case looks like this:<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>movss      
xmm0,dword ptr [ecx+4] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>ucomiss    
xmm0,dword ptr [ecx+8] <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>mov        
esi,ecx <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmove      
esi,edx <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmovne     
ecx,eax <o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:36.0pt'><span style='font-size:8.0pt;
font-family:"Courier New";color:gray'>cmove      
edx,eax</span><o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>So this generates compact code but with an unordered
compare.<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Anyway, it looks like the compare-for-equality case in
particular is missing an optimization opportunity. It’s no big deal to me
but I thought someone here might be interested…<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Cheers,<o:p></o:p></p>

<p class=MsoNormal><o:p> </o:p></p>

<p class=MsoNormal>Nicolas Capens<o:p></o:p></p>

</blockquote>

</blockquote>

</div>

</body>

</html>