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.

Reply via email to