https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120869
Bug ID: 120869
Summary: gcc does not eliminate short-circuiting tail calls
Product: gcc
Version: 15.1.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: kndevl at outlook dot com
Target Milestone: ---
https://godbolt.org/z/eGYfxK4PE
Reproducer (C++23)
```
#include <span>
using namespace std;
template <bool can_delete>
inline bool go(span<char> s) {
if (s.size() <= 1) return true;
if (s.front() == s.back()) return go<can_delete>(s.subspan(1, s.size() -
2));
if constexpr (can_delete) {
return go<false>(s.subspan(1, s.size() - 1))
|| go<false>(s.subspan(0, s.size() - 1));
} else {
return false;
}
}
bool validPalindrome(span<char> s) {
return go<true>(s);
}
```
clang 20.1.0 for x86-64 compiles `validPalindrome` to a tight loop with `-O2
-std=c++23` whereas gcc generates explicit calls to go<false>. clang also
results in ~5x fewer instructions.
With `-Os`, clang produces the same code as `-O2` whereas gcc eliminates all
but one tail calls to go<false>.