<html>
<head>
<base href="https://bugs.llvm.org/">
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW - GCC Optimizes Constexpr atof Function (LLVM does not)"
href="https://bugs.llvm.org/show_bug.cgi?id=47213">47213</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>GCC Optimizes Constexpr atof Function (LLVM does not)
</td>
</tr>
<tr>
<th>Product</th>
<td>clang
</td>
</tr>
<tr>
<th>Version</th>
<td>trunk
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>enhancement
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>C++2a
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedclangbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>a.huebl@hzdr.de
</td>
</tr>
<tr>
<th>CC</th>
<td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
</td>
</tr></table>
<p>
<div>
<pre>Hi,
while working around a bug in a downstream project (intel/llvm for DPC++,
<a href="https://github.com/intel/llvm/issues/2187">https://github.com/intel/llvm/issues/2187</a>) we found a constexpr atof function
that we use in a work-around.
Although we do some loops in the body, GCC was able to optimize the atof
function at compile-time, while clang was not. Could this be a good RFE?
Credits go to my colleague Weiqun Zhang for finding this.
<a href="https://godbolt.org/z/EM4TfM">https://godbolt.org/z/EM4TfM</a>
Code:
constexpr double my_atof (const char* p)
{
while (*p == ' ' || *p == '\t') ++p;
double sign = (*p == '-') ? -1.0 : 1.0;
if (*p == '-' || *p == '+') ++p;
double r = 0.;
while (*p >= '0' && *p <= '9') {
r = r*10. + double(*(p++) - '0');
}
if (*p == '.') {
++p;
double r2 = 0.;
double d = 1.;
while (*p >= '0' && *p <= '9') {
r2 = r2*10. + double(*(p++) - '0');
d *= 10;
}
r += r2/d;
}
if (*p == 'e') {
++p;
int sexp = (*p == '-') ? -1 : 1;
if (*p == '-' || *p == '+') ++p;
int iexp = 0;
while (*p >= '0' && *p <= '9') {
iexp = iexp*10 + (*(p++) - '0');
}
// need to compute 10**iexp = 10**(\sum 2**n) = \prod 10**(2**n)
int nmax = 0;
unsigned short int tmp = iexp;
while (tmp >>= 1) ++nmax;
double d = 1.0;
constexpr double powers[] =
{10.,100.,1.e4,1.e8,1.e16,1.e32,1.e64,1.e128,1.e256};
for (int n = 0; n <= nmax; ++n) {
if (iexp & 0x1) {
d *= powers[n];
}
iexp >>= 1;
}
if (sexp == -1) {
r /= d;
} else {
r *= d;
}
}
return sign*r;
}
constexpr double
operator"" _rt( const char* x )
{
return double( my_atof(x) );
}
constexpr double
operator"" _rt( unsigned long long int x )
{
return double( x );
}
bool f1 ()
{
return (-1.234e-13_rt == -1.234e-13);
}
bool f2 ()
{
return (3._rt == 3.0);
}
bool f3 ()
{
return (.5e2_rt == 0.5e2);
}</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>