<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<style type="text/css" style="display:none;"> P {margin-top:0;margin-bottom:0;} </style>
</head>
<body dir="ltr">
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
Hi, Andy,</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
This is somewhat tricky. 'afn' is for approximate functions, to "allow substitution of approximate calculations for functions", but in this case, the answers aren't any more approximate than the original function calls. Different, but likely no less accurate.
This has long caused these kinds of subtle differences when cross compiling, etc. but it's not clear what the best thing to do actually is. Users often want the constant folding, and I've certainly seen code where the performance depends critically on it,
and yet, the compiler will likely never be able to exactly replicate the behavior of whatever libm implementation is used at runtime. Maybe having a dedicated flag to disable just this behavior, aside from suggesting that users use -fno-builtin=..., would
be useful for users who depend on the compiler not folding these kinds of expressions in ways that might differ from their runtime libm behavior?</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
-Hal</div>
<div style="font-family: Calibri, Arial, Helvetica, sans-serif; font-size: 12pt; color: rgb(0, 0, 0);">
<br>
</div>
<div id="Signature">
<div class="BodyFragment"><font size="2"><span style="font-size:10pt;">
<div class="PlainText">Hal Finkel<br>
Lead, Compiler Technology and Programming Languages<br>
Leadership Computing Facility<br>
Argonne National Laboratory</div>
</span></font></div>
<div>
<div id="appendonsend"></div>
<div style="font-family:Calibri,Arial,Helvetica,sans-serif; font-size:12pt; color:rgb(0,0,0)">
<br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> llvm-dev <llvm-dev-bounces@lists.llvm.org> on behalf of Kaylor, Andrew via llvm-dev <llvm-dev@lists.llvm.org><br>
<b>Sent:</b> Tuesday, April 16, 2019 2:23 PM<br>
<b>To:</b> llvm-dev<br>
<b>Subject:</b> [llvm-dev] [FP] Constant folding math library functions</font>
<div> </div>
</div>
<div lang="EN-US">
<div class="x_WordSection1">
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
Hi everyone,</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
I noticed today that LLVM’s constant folding of math library functions can lead to minor differences in results. A colleague sent me the following test case which demonstrates the issue:</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
#include <stdio.h></p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
#include <math.h></p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
typedef union {</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
double d;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
unsigned long long i;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
} my_dbl;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
int main(void) {</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
my_dbl res, x;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
x.i = 0x3feeb39556255de2ull;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
res.d = tanh(x.d);</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
printf("tanh(%f) = %f = %016LX\n", x.d, res.d, res.i);</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
return 0;</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
}</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
Compiling with “clang -O2 -g0 -emit-llvm” I get this:</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
define dso_local i32 @main() local_unnamed_addr #0 {</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
%1 = tail call double @tanh(double 0x3FEEB39556255DE2) #2</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
%2 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str, i64 0, i64 0),</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
double 0x3FEEB39556255DE2, double 0x3FE7CF009CE7F169,</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
i64 4604876745549017449)</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
ret i32 0</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
}</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
We’re still calling ‘tanh’ but all the values passed to printf are constant folded. The constant folding is based on a call to tanh made by the compiler. The problem with this is that if I am linking my program against a different version of the math library
than was used by the compiler I may get a different result.</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
I can prevent this constant folding with either the ‘nobuiltin’ or ‘strictfp’ attribute. However, it seems to me like this optimization should really be checking the ‘afn’ fast math flag.</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
Opinions?</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
Thanks,</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
Andy</p>
<p class="x_MsoNormal" style="margin: 0in 0in 0.0001pt; font-size: 11pt; font-family: Calibri, sans-serif;">
</p>
</div>
</div>
</div>
</div>
</body>
</html>