https://gcc.gnu.org/bugzilla/show_bug.cgi?id=119006
Bug ID: 119006 Summary: IPA ICF and LTO cause strcmp condition to be omitted Product: gcc Version: 14.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: ipa Assignee: unassigned at gcc dot gnu.org Reporter: jeff-gcc at caffeinated dot me.uk Target Milestone: --- When compiled with -O2 -flto (or more minimally: -O -finline -fipa-icf-functions -foptimize-strlen -ftree-dse -ftree-vrp -flto), GCC miscompiles the following code: template<unsigned N> struct FixedString { FixedString(const char* str_) { *this = str_; } bool operator==(const char* rhs_) const { return rhs_ and not __builtin_strcmp(_str, rhs_); } bool operator!=(const char* rhs_) const { return !(*this == rhs_); } char _str[N + 1]; }; int fixedStringUser(const FixedString<10>& lhs, const char* rhs) { return lhs == rhs; } void checkString(FixedString<127> reason_) { if (reason_ != "StrOverTenChars") asm volatile("nop"); } int main(int argc, char** argv) { FixedString<127> fs = argv[1]; if (argc > 2) checkString(fs); } During LTO WPA, ICF replaces FixedString<127>::operator== with FixedString<10>::operator==, and then LTRANS reasons that strcmp of a buffer which can hold a string up to length 10 cannot be equal to a string longer than 10 characters, forgetting that the LHS is actually max length 127. This results in `checkString` being reduced to the body of the `if` condition, i.e. just the `asm volatile("nop")`. Testing on godbolt (https://gcc.godbolt.org/z/bv3YqzTG5) shows that this has been present since GCC11, and is still present in trunk.