https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96625
Bug ID: 96625 Summary: Unnecessarily large assembly generated when a bit-offsetted higher-end end of a uint64_t-backed bitfield is shifted toward the high end (left) by its bit-offset Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: pskocik at gmail dot com Target Milestone: --- (Bitfields backed by 32-bit unsigneds are handled well.) My example (https://gcc.godbolt.org/z/Yac38T): #include <stdint.h> #define FRONTSZ 3 #define UTYPE uint64_t struct s{ union { UTYPE whole; struct { UTYPE front:FRONTSZ, tail:8*sizeof(UTYPE)-FRONTSZ; }; };}; UTYPE hiShifted_tail(struct s X) { return X.tail<<FRONTSZ; } //better codegen: UTYPE hiShifted_tail2(struct s X) { return X.whole>>FRONTSZ<<FRONTSZ; } UTYPE hiShifted_tail3(struct s X) { return X.whole & (0xffffffffffffffff<<FRONTSZ); } x86-64 assembly generated for hiShifted_tail{,2,3}: 0000000000000000 <hiShifted_tail> (14 bytes): 0: 48 b8 f8 ff ff ff ff ff ff 1f movabs rax,0x1ffffffffffffff8 a: 48 21 f8 and rax,rdi d: c3 ret 0000000000000000 <hiShifted_tail{2,3}> (8 bytes): 0: 48 89 f8 mov rax,rdi 3: 48 83 e0 f8 and rax,0xfffffffffffffff8 7: c3 ret The codegen follows the same pattern for other front-sizes. hiShifted_tail() on clang (regardless of whether uint64_t or uint32_t is used as the backing type) and on gcc with uint32_t rather than uin64_t used as the bitfield-backing-type follows the smaller codegen patter of hiShifted_tail{2,3}.