[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