[Bug rtl-optimization/51933] [4.7 Regression] Wrong-code due to -free

jakub at gcc dot gnu.org gcc-bugzilla@gcc.gnu.org
Sat Jan 21 15:51:00 GMT 2012


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

--- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-01-21 15:24:26 UTC ---
Consider following 3 routines:

unsigned long
foo (unsigned short *s, int i)
{
  unsigned short x = s[i];
  if (x < 0x211)
    return (unsigned char) x;
  asm volatile ("");
  return 6;
}
unsigned long
bar (unsigned short *s, int i)
{
  unsigned short x = s[i];
  if (x < 0x211)
    return (unsigned char) x;
  asm volatile ("");
  return x;
}
unsigned long
baz (unsigned short *s, int i)
{
  unsigned short x = s[i];
  if (x < 0x211)
    return x;
  asm volatile ("");
  return (unsigned char) x;
}

In foo ree doesn't optimize away the QImode -> DImode zero extension, because
merge_def_and_ext checks:
  && GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
and in this case ext_src_mode is QImode, but SET_DEST has HImode.
In bar ree doesn't optimize it away either, first merge_def_and_ext_checks is
called with the QImode ext_src_mode (which doesn't match) and only afterwards
on the HImode -> DImode extension, which is optimized (that is correct).
In baz (which is the same as bar in #c0 testcase) unfortunately
merge_def_and_ext is first called on the HImode -> DImode extension, which is
optimized (that is fine) by turning the HImode load into a DImode zero_extend
load from HImode and removing the HImode -> DImode extension.
But then when make_defs_and_copies_lists is called on the QImode -> DImode
extension, we reach:
      /* Initialize the work list.  */
      if (!get_defs (extend_insn, src_reg, &work_list))
        {
          VEC_free (rtx, heap, work_list);
          /* The number of defs being equal to zero can only mean that all the
             definitions have been previously merged.  */
          return 2;
        }
and because the definition has been changed already.  But nothing performs the
ext_src_mode check that used to be performed otherwise.
So we either need to do the src mode checking earlier when we haven't started
modifying insns (in add_removable_extension?), or we'd need to look even at the
newly added defs and see what mode they extend from.



More information about the Gcc-bugs mailing list