<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>