[Bug tree-optimization/42614] New: FRE optimizes away valid code after IPA inlining

rahul at icerasemi dot com gcc-bugzilla@gcc.gnu.org
Mon Jan 4 18:24:00 GMT 2010


On the following test case compiled with GCC 4.4.1 release version and the
following command line

gcc -S -O2 -finline-functions-called-once -fdump-tree-all-details
-fdump-ipa-all fail.c

typedef struct SEntry
{
  unsigned char num;
} TEntry;

typedef struct STable
{
  TEntry data[2];
} TTable;


TTable *init ();
int fake_expect (int, int);
void fake_assert (int);

void
expect_func (int a, unsigned char *b) __attribute__ ((noinline));

static inline void
inlined_wrong (TEntry *entry_p, int flag);

void
inlined_wrong (TEntry *entry_p, int flag)
{
  unsigned char index;
  entry_p->num = 0;

  if (!flag)
      fake_assert (0);

  for (index = 0; index < 1; index++)
    entry_p->num++;

  asm ("before");

  if (entry_p->num)
    {
      fake_assert(0);
      asm ("#here");
    }
}

void
expect_func (int a, unsigned char *b)
{
  if (fake_expect ((a == 0), 0))
    fake_assert (0);
  if (fake_expect ((b == 0), 0))
    fake_assert (0);
}

void
broken ()
{
  unsigned char index = 0;
  TTable *table_p = init();

  inlined_wrong (&(table_p->data[1]), 1);
  expect_func (0, &index);
  inlined_wrong ((TEntry *)0xf00f, 1);

  LocalFreeMemory (&table_p);
}


we get after FRE:

broken ()
{
  unsigned char index;
  unsigned char D.1321;
  unsigned char D.1320;
  unsigned char index;
  unsigned char D.1316;
  unsigned char D.1315;
  struct TTable * table_p;
  unsigned char index;
  struct TEntry * D.1281;
  struct TTable * table_p.1;
  struct TTable * table_p.0;

<bb 2>:
  index = 0;
  table_p.0_1 = init ();
  table_p = table_p.0_1;
  table_p.1_2 = table_p.0_1;
  D.1281_3 = &table_p.1_2->data[1];
  table_p.1_2->data[1].num = 0;
  goto <bb 4>;

<bb 3>:
  D.1315_4 = D.1281_3->num;
  D.1316_5 = D.1315_4 + 1;
  D.1281_3->num = D.1316_5;
  index_7 = index_6 + 1;

<bb 4>:
  # index_6 = PHI <0(2), index_7(3)>
  if (index_6 == 0)
    goto <bb 3>;
  else
    goto <bb 5>;

<bb 5>:
  __asm__ __volatile__("before");
  D.1315_8 = 0;
  expect_func (0, &index);
  61455B->num ={v} 0;
  goto <bb 7>;

<bb 6>:
  D.1320_10 ={v} 61455B->num;
  D.1321_11 = D.1320_10 + 1;
  61455B->num ={v} D.1321_11;
  index_13 = index_12 + 1;

<bb 7>:
  # index_12 = PHI <0(5), index_13(6)>
  if (index_12 == 0)
    goto <bb 6>;
  else
    goto <bb 8>;

<bb 8>:
  __asm__ __volatile__("before");
  D.1320_14 ={v} 61455B->num;
  if (D.1320_14 != 0)
    goto <bb 9>;
  else
    goto <bb 10>;

<bb 9>:
  fake_assert (0);
  __asm__ __volatile__("#here");

<bb 10>:
  LocalFreeMemory (&table_p);
  return;

}


Note the check "if (entry_p->num)" and associated block is completely
eliminated. The dumps indicate:

Replaced table_p with table_p.0_1 in table_p.1_2 = table_p;
Replaced table_p.1_2->data[1].num with 0 in D.1315_8 =
table_p.1_2->data[1].num;
Removing basic block 6
;; basic block 6, loop depth 0, count 0
;; prev block 5, next block 7
;; pred:       5 [39.0%]  (true,exec)
;; succ:       7 [100.0%]  (fallthru,exec)
<bb 6>:
fake_assert (0);
__asm__ __volatile__("#here");


If the same code is compiled with the function "inlined_wrong" declared as

static inline void
inlined_wrong (TEntry *entry_p, int flag) __attribute__ ((always_inline));

The generated code is correct with the check in place, suggesting ipa-inline is
troublesome while early inlining works okay?


-- 
           Summary: FRE optimizes away valid code after IPA inlining
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rahul at icerasemi dot com
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


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



More information about the Gcc-bugs mailing list