[llvm-bugs] [Bug 47213] New: GCC Optimizes Constexpr atof Function (LLVM does not)
via llvm-bugs
llvm-bugs at lists.llvm.org
Mon Aug 17 16:33:43 PDT 2020
https://bugs.llvm.org/show_bug.cgi?id=47213
Bug ID: 47213
Summary: GCC Optimizes Constexpr atof Function (LLVM does not)
Product: clang
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: C++2a
Assignee: unassignedclangbugs at nondot.org
Reporter: a.huebl at hzdr.de
CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk
Hi,
while working around a bug in a downstream project (intel/llvm for DPC++,
https://github.com/intel/llvm/issues/2187) 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.
https://godbolt.org/z/EM4TfM
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);
}
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20200817/8684abfd/attachment.html>
More information about the llvm-bugs
mailing list