<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 15 (filtered medium)"><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:"Book Antiqua";
        panose-1:2 4 6 2 5 3 5 3 3 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Book Antiqua",serif;
        color:windowtext;
        font-weight:normal;
        font-style:normal;
        text-decoration:none none;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
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-IE link="#0563C1" vlink="#954F72"><div class=WordSection1><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>When I updated our out of tree compiler to v3.9 RC3 from v3.8, I noticed a number of large performance regressions, some tests using 5 times as many instructions.  However, when I examined the test, I realised that something quite different was going on concerning the ISO C math functions, and it is not a true performance regression at all.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>I will use the following example for this message, and this is compiled with ‘-S -O3’.  The option ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>-ffast-math</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ is not used, and I have verified that ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>-fmath-errno</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ is present in the ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>-cc1</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ options:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>extern double exp(double);<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>extern double foo(double);<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>int useMathName() {<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>  if ((exp(1.0) < 2.71) || (exp(1.0) > 2.72))<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>    return -1;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>  return 0;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>}<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'><o:p> </o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>int useOtherName() {<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>  if ((foo(1.0) < 2.71) || (foo(1.0) > 2.72))<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>    return -1;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>  return 0;<o:p></o:p></span></p><p class=MsoNormal style='margin-left:36.0pt'><span style='font-size:12.0pt;font-family:"Courier New"'>}<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>With v3.8, the implementation of the function ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>useMathName</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ was reduced to simply ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>return 0</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’.  The compiler elided the calls to ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>exp</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’, assumed the value that would have been returned if it was called, decided that the two tests would be ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>false</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ and reduced the code-generation to ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>return 0</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’.  This does not happen for the other function ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>useOtherName</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’, and the code generated is as expected.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>After updating to v3.9 RC3, the compiler is no longer eliding the calls to ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>exp</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ - probably because a bug was fixed since ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>errno</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ could be changed - but it is still presuming the returned value and eliding the tests, so the function is now 2 consecutive calls to ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>exp</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ and a ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>return 0</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>I have verified that this is the case for the unaltered X86 v3.8 distribution version too.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>I would expect this behaviour if ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>-ffast-math -fno-math-errno</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ was selected, but it isn’t, and I think that this is an invalid optimisation.  It also means that some of my math functional tests are not reporting honestly (this only happens when the argument(s) are constants).  Also, on our architecture, ‘</span><span style='font-size:12.0pt;font-family:"Courier New"'>double</span><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>’ is FP32, and it is probable that the compiler is using the host platform’s implementation which is FP64 for evaluating the test expressions, and this will introduce precision differences that the test will not detect - in my real tests, the test expression ranges are more fine-grained to allow for legitimate FP32 ranges.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>Thanks,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'>            MartinO<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:12.0pt;font-family:"Book Antiqua",serif'><o:p> </o:p></span></p></div></body></html>