https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94878
Bug ID: 94878 Summary: Failure to optimize div with bls/or pattern Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: gabravier at gmail dot com Target Milestone: --- unsigned y(unsigned x) { unsigned s = x & -x; return s | (x % s); } With -O3, LLVM outputs : y(unsigned int): blsi ecx, edi lea eax, [rcx - 1] and eax, edi or eax, ecx ret GCC outputs : y(unsigned int): mov eax, edi xor edx, edx blsi ecx, edi div ecx mov eax, edx or eax, ecx ret If a single change to this function is applied, changing it to this : unsigned y(unsigned x) { unsigned s = x & -x; return x | (x % s); } It's equivalent to `return x`, and LLVM recognises this : y(unsigned int): mov eax, edi ret While GCC does not : y(unsigned int): mov eax, edi xor edx, edx blsi ecx, edi div ecx mov eax, edx or eax, edi ret