https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82940

Peter Cordes <peter at cordes dot ca> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |peter at cordes dot ca

--- Comment #6 from Peter Cordes <peter at cordes dot ca> ---
For a simpler test case, GCC 4.8.5 did redundantly mask before using
bitfield-insert, but GCC 9.2.1 doesn't.


unsigned merge2(unsigned a, unsigned b){
    return (a&0xFFFFFF00u) | (b&0xFFu);
}

https://godbolt.org/z/froExaPxe
# PowerPC (32-bit) GCC 4.8.5
        rlwinm 4,4,0,0xff     # b &= 0xFF is totally redundant
        rlwimi 3,4,0,24,31
        blr

# power64 GCC 9.2.1 (ATI13.0)
        rlwimi 3,4,0,255    # bit-blend according to mask, rotate count=0
        rldicl 3,3,0,32     # Is this zero-extension to 64-bit redundant?
        blr

But ppc64 GCC does zero-extension of the result from 32 to 64-bit, which is
probably not needed unless the calling convention has different requirements
for return values than for incoming args.  (I don't know PPC well enough.)

So for at least some cases, modern GCC does ok.

Also, when the blend isn't split at a byte boundary, even GCC4.8.5 manages to
avoid redundant masking before the bitfield-insert.

unsigned merge2(unsigned a, unsigned b){
    return (a & 0xFFFFFF80u) | (b & 0x7Fu);
}

        rlwimi 3,4,0,25,31   # GCC4.8.5, 32-bit so no zero-extension
        blr

Reply via email to