https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109931
Bug ID: 109931
Summary: Knowledge on literal not used in optimization
Product: gcc
Version: 14.0
Status: UNCONFIRMED
Keywords: missed-optimization
Severity: normal
Priority: P3
Component: tree-optimization
Assignee: unassigned at gcc dot gnu.org
Reporter: antoshkka at gmail dot com
Target Milestone: ---
Function for comparing a lower-cased string with runtime string of known size:
constexpr bool ICaseEqualLowercase(const char* lowercase, const char* y,
unsigned size) noexcept {
constexpr char kLowerToUpperMask = static_cast<char>(~unsigned{32});
for (unsigned i = 0; i < size; ++i) {
const auto lowercase_c = lowercase[i];
if (lowercase_c != y[i]) {
if (!('a' <= lowercase_c && lowercase_c <= 'z') ||
(lowercase_c & kLowerToUpperMask) != y[i]) {
return false;
}
}
}
return true;
}
bool test2(const char* y) {
return ICaseEqualLowercase("hello", y, 5);
}
With GCC trunk and -O2 flags the GCC fails to understand that all the
characters of `lowercase` are lowercase ASCII and the expression `!('a' <=
lowercase_c && lowercase_c <= 'z')` is always `false`.
Because of that, additional instructions in loop are emitted:
lea esi, [rdx-97]
cmp sil, 25
ja .L6
Godbolt playground: https://godbolt.org/z/xrc1T4oeW