https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109931
--- Comment #3 from Antony Polukhin <antoshkka at gmail dot com> --- > But that's because nothing in the function asserts this? Without fully > specializing and unrolling on the constant "hello" argument at least. Yes, I was hoping for that unrolling to happen Probably a more simplified case: constexpr bool EqualICase(const char* lowercase, const char* y) noexcept { for (;;) { const auto lowercase_c = *lowercase; if (!lowercase_c) return true; if (lowercase_c != *y) { return false; } ++lowercase; ++y; } } bool test2(const char* y) { return EqualICase("he", y); } With range info for loads from read-only constants I'd expect this to become just a test2(char const*): cmp BYTE PTR [rdi], 104 jne .L3 cmp BYTE PTR [rdi+1], 101 sete al ret .L3: xor eax, eax ret rather than a fair loop with checks for \0 Godbolt: https://godbolt.org/z/z6rTYEzWx