https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81161
Bug ID: 81161 Summary: poor code concatenating bitfields Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: middle-end Assignee: unassigned at gcc dot gnu.org Reporter: nathan at gcc dot gnu.org Target Milestone: --- Created attachment 41604 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41604&action=edit example The example code is trying to use a set of adjacent single bit fields as a wider value. (Think TREE_LANG_FLAG_{N,N+2} to explain why I can't just make a 3-bit bitfield). We don't spot this is just extrating a wider bitfield[*] here's the x86_64 code I get: movzbl (%rdi), %edx movl %edx, %eax movl %edx, %ecx shrb $2, %dl shrb $4, %al shrb $3, %cl andl $1, %edx andl $1, %eax andl $1, %ecx sall $2, %eax addl %ecx, %ecx orl %ecx, %eax orl %edx, %eax ret which is roughly doing: t1 = (val >> 2) & 1 t2 = (val >> 3) & 1 t3 = (val >> 4) & 1 r = (t3 << 2) | (t2 + t1) | t1 optimal code would be something like: movzbl (%rdi), %eax shrb $2,%al andl $7,%eax this is similar to 68360, but looks sufficiently different to warrant a new report. [*] where bitfield packing was from the other end of the object, one might want to swap the bitfields around to get a nice ordering. Let's just assume little-endian packing for the sake of argument.