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.