https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66872
Bug ID: 66872 Summary: fold a & ((1 << b) - 1) to a & ~(-1 << b) Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: bonzini at gnu dot org Target Milestone: --- This can save one or two instructions on some architectures. For example, when compiling int f(int x, int t) { return x & ((1 << t) - 1); } vs. int f(int x, int t) { return x & ~(-1 << t); } with -march=haswell you get before: movl $1, %edx shlx %esi, %edx, %esi subl $1, %esi # not sure why no lea here? movl %esi, %eax andl %edi, %eax ret and after: movl $-1, %edx shlx %esi, %edx, %esi andn %edi, %esi, %eax ret Even if you account for the strange register allocation in the first assembly listing, using andn can save one instruction. Also, with -mtune=generic the size is the same. Before: movl %esi, %ecx movl $1, %edx sall %cl, %edx subl $1, %edx movl %edx, %eax andl %edi, %eax ret After: movl %esi, %ecx movl $-1, %edx sall %cl, %edx notl %edx movl %edx, %eax andl %edi, %eax ret