https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105119
Bug ID: 105119 Summary: the division in x / (1 << y) is optimized away when x has unsigned type, but not when it's signed Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: rtl-optimization Assignee: unassigned at gcc dot gnu.org Reporter: ppalka at gcc dot gnu.org Target Milestone: --- For the following on x86_64 with -O2 int f(int x, int y) { return x / (1 << y); } GCC generates an idiv instruction: movl %esi, %ecx movl $1, %edx movl %edi, %eax sall %cl, %edx movl %edx, %ecx cltd idivl %ecx ret But I believe this is equivalent to the division-less int g(int x, int y) { return (x + (x < 0) * ((1 << y) - 1)) >> y; } (which basically generalizes the existing x / (1 << y) -> x >> y transformation that we perform for unsigned x). For this latter function, we generate movl %esi, %ecx movl $1, %eax xorl %edx, %edx sall %cl, %eax subl $1, %eax testl %edi, %edi cmovns %edx, %eax addl %edi, %eax sarl %cl, %eax ret which seems to be significantly faster according to some rough benchmarks.