https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118316
Bug ID: 118316 Summary: Missed optimization: while (len > 1) len -= 2; Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: blubban at gmail dot com Target Milestone: --- unsigned foo(char* buf, unsigned len) { while (len > 1) len -= 2; if (len) *buf = 42; return len; } unsigned bar(char* buf, unsigned len) { len %= 2; if (len) *buf = 42; return len; } -O2 Result: foo(char*, unsigned int): mov eax, esi and eax, 1 cmp esi, 1 cmovbe eax, esi test eax, eax je .L1 mov BYTE PTR [rdi], 42 .L1: ret bar(char*, unsigned int): mov eax, esi and eax, 1 je .L9 mov BYTE PTR [rdi], 42 .L9: ret Expected: Same for both Reduced from an implementation of to_chars(int) using a two-chars-at-the-time char[200] lookup table. All three major compilers get confused by that code. https://godbolt.org/z/1W1hroc67