https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70903
--- Comment #4 from ktkachov at gcc dot gnu.org --- Basically at expand time we're expanding: vector(32) unsigned char _4; unsigned char _5; _3 = {65535, _2}; _4 = VIEW_CONVERT_EXPR<vector(32) unsigned char>(_3); _5 = BIT_FIELD_REF <_4, 8, 8>; and we're getting: (insn 17 16 18 (set (subreg:DI (reg:OI 91 [ D.2757 ]) 0) (const_int 65535 [0xffff])) bfi.c:7 -1 (nil)) (insn 18 17 19 (set (subreg:DI (reg:OI 91 [ D.2757 ]) 8) (subreg:DI (reg/v:OI 84 [ x ]) 0)) bfi.c:7 -1 (nil)) (insn 19 18 20 (set (subreg:DI (reg:QI 94) 0) (zero_extract:DI (subreg:DI (reg:OI 91 [ D.2757 ]) 0) (const_int 8 [0x8]) (const_int 8 [0x8]))) bfi.c:7 -1 (nil)) (insn 20 19 21 (set (reg:DI 95) (subreg:DI (reg:QI 94) 0)) bfi.c:7 -1 (nil)) the various RTL optimizers propagate the 65535 through the subregs and zero-extracts and it ends up as -1 (0xffffffffffffffff) in reg 95. I'm not sure what path during expand expands this operation, but the subreg on insn 20 is probably wrong, as we do care about the bits beyond QImode, we want a zero_extend.