https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101806
--- Comment #3 from Andrew Pinski <pinskia at gcc dot gnu.org> --- Even a simple: unsigned char g(unsigned char a, unsigned char b) { return ((~a) & b)&1; } Produces the extra zero extend. But it is ok with: unsigned char g(unsigned char *a, unsigned char *b) { return ((~*a) & *b)&1; } It looks like it is hard register related too ...