https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63278

            Bug ID: 63278
           Summary: Fails to compute loop bound from constant string
           Product: gcc
           Version: 4.9.1
            Status: UNCONFIRMED
          Keywords: missed-optimization
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rguenth at gcc dot gnu.org

For

inline constexpr size_t hashString(const char* str, size_t hash = 5381)
{
return (*str) ? hashString(str + 1, hash + (hash << 5) + *str) : hash;
}

inline size_t hashString2(const char* str) __attribute__ ((pure));
size_t hashString2(const char* str)
{
size_t hash = 5381;
while (*str) {
hash += (hash << 5) + *str;
str++;
}
return hash;
}

size_t foo()
{
  return hashString("foo") + hashString2("foo");
}

that is, the loop created by tail-recursion and the manual loop we fail
to compute the number of iterations and thus fail to unroll them.
Both look like

  <bb 2>:

  <bb 3>:
  # str_28 = PHI <"foo"(2), str_10(4)>
  # _29 = PHI <102(2), _4(4)>
  # hash_30 = PHI <5381(2), hash_9(4)>
  _6 = hash_30 << 5;
  _8 = (long unsigned int) _29;
  _23 = _6 + _8;
  hash_9 = _23 + hash_30;
  str_10 = str_28 + 1;
  _4 = *str_10;
  if (_4 != 0)
    goto <bb 4>;
  else
    goto <bb 8>;

  <bb 4>:
  goto <bb 3>;

Similar cases may occur when iterating over a constant initializer
guarded by a NULL pointer.

SCEV cannot handle the above (obviously), but eventually hacking up
some special-case code may be worth the trouble.

Reply via email to