https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83272
--- Comment #2 from Mason <slash.tmp at free dot fr> --- (In reply to Jakub Jelinek from comment #1) > I don't believe the andl is not needed after shrb, as that is an 8-bit > operand size, it should leave the upper 56 bits of the register unmodified. > And unsigned char argument is in the ABI passed as int, so I think the upper > 32 bits are undefined, which the andl instruction clears. I checked the amd64 SysV ABI, and didn't see a requirement for a function returning an INTEGER type smaller than 64 bits to clear the upper bits? (The caller knows what bits are valid.) Anyway, I may have oversimplified the testcase. Consider this one: char foo(unsigned char *p) { static const char map[16] = "wxyz"; return map[*p / 16]; } foo: movzbl (%rdi), %eax shrb $4, %al andl $15, %eax movzbl map.2295(%rax), %eax ret movzbl does all bits of RAX. shrb discards 4 of the 8 bits, leaving only 4. Thus, andl is a no-op in that case.