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

Reply via email to