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

--- Comment #2 from Richard Biener <rguenth at gcc dot gnu.org> ---
I think we should be able to VN them the same so that PRE discovers the full
redundancy.  Oh we do:

Value numbering stmt = _4 = VIEW_CONVERT_EXPR<unsigned char>(a.0_1);
Setting value number of _4 to _4 (changed)
...
Value numbering stmt = iftmp.1_6 = BIT_FIELD_REF <a, 8, 0>;
Setting value number of iftmp.1_6 to _4 (changed)
...
Value numbering stmt = iftmp.1_2 = PHI <iftmp.1_6(3), _4(4)>
Setting value number of iftmp.1_2 to _4 (changed)

I think what's missing for PRE to work is BIT_INSERT_EXPR <@0, V_C_E <@0>, ...>
simplification to @0 - IIRC we only have BIT_INSERT <..., BIT_FIELD_REF ..>
simplification here.

That said, we fail to apply code hoisting because a.0_1 = a is AVAIL_OUT
in BB 2.

We can't eliminate iftmp.1_2 as theres no value available for replacement
and we don't consider inserting the conversion from a.0_1 here.

It works for

typedef unsigned char v1 __attribute__((__vector_size__(1)));
unsigned char vext_p64(v1 a, unsigned n)
{
  unsigned char r = (n == 0) ? a[n] : a[0];
  return r;
}

because we have two BIT_FIELD_REF from memory in this case.  It also works for

typedef unsigned char v1 __attribute__((__vector_size__(1)));
unsigned char vext_p64(v1 a, unsigned n)
{
  v1 x = a;
  unsigned char r = (n == 0) ? x[n] : x[0];
  return r;
}

because we have two V_C_E from register in this case.

Reply via email to