[Bug tree-optimization/81396] [7/8 Regression] Optimization of reading Little-Endian 64-bit number with portable code has a regression

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Thu Jul 13 17:38:00 GMT 2017


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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |jakub at gcc dot gnu.org

--- Comment #4 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 41749
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41749&action=edit
gcc8-pr81396.patch

While the bswap pass finds out this is a nop reshuffling, it hits:
  /* Useless bit manipulation performed by code.  */
  if (!n->base_addr && n->n == cmpnop)
    return NULL;
and doesn't do anything (while in GCC6 it was less optimized and thus
n->base_addr was non-NULL and the bswap pass did something with it).
Either we can do something in the bswap pass with it as done in this untested
patch, or we could consider match.pd optimization for:
  _3 = BIT_FIELD_REF <_7, 8, 16>;
  _32 = (typeof(_7)) _3;
  _4 = _32 << 16;
into:
  _4 = _7 & (((1ULL << 8) - 1) << 16);
if the shift matches the bitpos and then rest of match.pd would be able to
figure it out, like it optimizes now at forwprop1 time e.g.:
typedef unsigned long long uint64_t;
uint64_t ReadLittleEndian64(uint64_t word) {
  uint64_t ret = 0;
  ret |= (word & 0xff);
  ret |= (((word & 0xff00) >> 8) << 8);
  ret |= (((word & 0xff0000) >> 16) << 16);
  ret |= (((word & 0xff000000U) >> 24) << 24);
  ret |= (((word & 0xff00000000ULL) >> 32) << 32);
  ret |= (((word & 0xff0000000000ULL) >> 40) << 40);
  ret |= (((word & 0xff000000000000ULL) >> 48) << 48);
  ret |= (((word & 0xff00000000000000ULL) >> 56) << 56);
  return ret;
}


More information about the Gcc-bugs mailing list