<html><head><style type='text/css'>p { margin: 0; }</style></head><body><div style='font-family: arial,helvetica,sans-serif; font-size: 10pt; color: #000000'><br><hr id="zwchr"><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><b>From: </b>"Martin J. O'Riordan via cfe-dev" <cfe-dev@lists.llvm.org><br><b>To: </b>"Clang Dev" <cfe-dev@lists.llvm.org><br><b>Sent: </b>Wednesday, August 31, 2016 5:10:28 AM<br><b>Subject: </b>[cfe-dev] CLang and ISO C math functions<br><br>
<style><!--

@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;}

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><div class="WordSection1"><p class="MsoNormal"><span style="font-size: 12pt; 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.</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; 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: 12pt; font-family: "Courier New";">-ffast-math</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ is not used, and I have verified that ‘</span><span style="font-size: 12pt; font-family: "Courier New";">-fmath-errno</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ is present in the ‘</span><span style="font-size: 12pt; font-family: "Courier New";">-cc1</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ options:</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">extern double exp(double);</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">extern double foo(double);</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";"> </span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">int useMathName() {</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">  if ((exp(1.0) < 2.71) || (exp(1.0) > 2.72))</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">    return -1;</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">  return 0;</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">}</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";"> </span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">int useOtherName() {</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">  if ((foo(1.0) < 2.71) || (foo(1.0) > 2.72))</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">    return -1;</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">  return 0;</span></p><p class="MsoNormal" style="margin-left: 36pt;"><span style="font-size: 12pt; font-family: "Courier New";">}</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">With v3.8, the implementation of the function ‘</span><span style="font-size: 12pt; font-family: "Courier New";">useMathName</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ was reduced to simply ‘</span><span style="font-size: 12pt; font-family: "Courier New";">return 0</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’.  The compiler elided the calls to ‘</span><span style="font-size: 12pt; font-family: "Courier New";">exp</span><span style="font-size: 12pt; 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: 12pt; font-family: "Courier New";">false</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ and reduced the code-generation to ‘</span><span style="font-size: 12pt; font-family: "Courier New";">return 0</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’.  This does not happen for the other function ‘</span><span style="font-size: 12pt; font-family: "Courier New";">useOtherName</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’, and the code generated is as expected.</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; 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: 12pt; font-family: "Courier New";">exp</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ - probably because a bug was fixed since ‘</span><span style="font-size: 12pt; font-family: "Courier New";">errno</span><span style="font-size: 12pt; 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: 12pt; font-family: "Courier New";">exp</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ and a ‘</span><span style="font-size: 12pt; font-family: "Courier New";">return 0</span><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">’.</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">I have verified that this is the case for the unaltered X86 v3.8 distribution version too.</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">I would expect this behaviour if ‘</span><span style="font-size: 12pt; font-family: "Courier New";">-ffast-math -fno-math-errno</span><span style="font-size: 12pt; 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: 12pt; font-family: "Courier New";">double</span><span id="DWT12230" style="font-size: 12pt; font-family: "Book Antiqua",serif;">’ is FP32,</span></p></div></blockquote>Does Clang for your target emit C-language "double" types as "double" at the IR level? If so, that's wrong. "double" at the IR level is assumed to be an IEEE double-precision number. All of the constant folding will do the wrong thing on your target if this is what is happening.<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div class="WordSection1"><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> and it is probable that the compiler is using the host platform’s implementation which is FP64 for evaluating the test expressions,</span></p></div></blockquote>Yes, that's right. See ConstantFoldScalarCall in LLVM's lib/Analysis/ConstantFolding.cpp. We're obviously aware this can cause issues when cross compiling. If you'd like to discuss this behavior, you should do so on llvm-dev. We might want to make this more configurable than it currently is.<br><br> -Hal<br><blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; padding-left: 5px; color: rgb(0, 0, 0); font-weight: normal; font-style: normal; text-decoration: none; font-family: Helvetica,Arial,sans-serif; font-size: 12pt;"><div class="WordSection1"><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> 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.</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">Thanks,</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;">            MartinO</span></p><p class="MsoNormal"><span style="font-size: 12pt; font-family: "Book Antiqua",serif;"> </span></p></div><br>_______________________________________________<br>cfe-dev mailing list<br>cfe-dev@lists.llvm.org<br>http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev<br></blockquote><br><br><br>-- <br><div><span name="x"></span>Hal Finkel<br>Assistant Computational Scientist<br>Leadership Computing Facility<br>Argonne National Laboratory<span name="x"></span><br></div></div></body></html>