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

--- Comment #60 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
(In reply to Segher Boessenkool from comment #59)
> You either do a define_split (splitting the above ior thing into the two
> insns you want, during combine itself), or you do a define_insn_and_split,
> allowing this whole thing as a single rtl insn (perhaps only before split1,
> or whatever works best).

That won't work for the above folding as you need to know the non-zero bits of
r93 match up with the constant to the "and" (-256).
Also this really should be a generic as I originally saw this issue on MIPS :).

Here is a testcase which you will see the same issue as insv_1.c on
powerpc64-linux-gnu (for little-endian just swap around the fields of the
struct):
typedef struct bitfield
{
  unsigned short eight1: 8;
  unsigned short eight: 8;
} bitfield;

bitfield
bfi1 (bitfield a, unsigned *b)
{
  a.eight = *b;
  return a;
}

bitfield
bfi1_1 (bitfield a, unsigned b)
{
  a.eight = b;
  return a;
}

NOTICE how bfi1_1 uses one rlwimi while bfi1 has rlwinm followed by or but
could just used rlwimi .  This is a generic problem of combine wanting to use
nonzerobits but that sometimes can remove "important" information.

Reply via email to