[Bug tree-optimization/42587] bswap not recognized for memory

rguenth at gcc dot gnu dot org gcc-bugzilla@gcc.gnu.org
Sun Jan 3 16:26:00 GMT 2010



------- Comment #3 from rguenth at gcc dot gnu dot org  2010-01-03 16:26 -------
Similar example not handled by bswap recognition:

typedef unsigned char u8;
typedef unsigned int u32;
union __anonunion
{
  u32 value;
  u8 bytes[4];
};
u32
acpi_ut_dword_byte_swap (u32 value)
{
  union __anonunion in;
  in.value = value;
  return (((((in.bytes[0] << 8) | in.bytes[1]) << 8) | in.bytes[2]) << 8) |
in.bytes[3];
}

here we also hit the recursion depth of the bswap recognition.  Not so with

typedef unsigned char u8;
typedef unsigned int u32;
union __anonunion
{
  u32 value;
  u8 bytes[4];
};
u32
acpi_ut_dword_byte_swap (u32 value)
{
  union __anonunion in;
  in.value = value;
  return (((in.bytes[0] << 8) | in.bytes[1]) << 16) | ((in.bytes[2] << 8) |
in.bytes[3]);
}

but we do not handle

# VUSE <.MEM_18>
in$bytes$2_25 = in.bytes[2];

as bases (we probably could and it woudldn't be too hard - harder for
the case with pointer arithmetic though).  We end up trying with
in$bytes$2_25 as base.  Here:

        case BIT_IOR_EXPR:
          source_expr1 = find_bswap_1 (rhs1_stmt, &n1, limit - 1);
          if (!source_expr1)
            return NULL_TREE;

          source_expr2 = find_bswap_1 (rhs2_stmt, &n2, limit - 1);
          if (source_expr1 != source_expr2
              || n1.size != n2.size)
            return NULL_TREE;

we'd have to detect the source exprs common memory and adjust the
piecewise symbolic numbers and create a common source expr.  The
idea would be to combine in.bytes[2] and in.bytes[3] to
V_C_E <int> (in.bytes).  As said it's going to me more complicated
for accesses via pointers, *p, *(p+1), ...

Note that once we extend this for memory we can as well do piecewise
memory copy analysis and do store/load merging on the tree level.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42587



More information about the Gcc-bugs mailing list