This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/42620] New: FRE optimizes away valid code after IPA inlining
- From: "rahul at icerasemi dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 5 Jan 2010 11:27:47 -0000
- Subject: [Bug tree-optimization/42620] New: FRE optimizes away valid code after IPA inlining
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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=42620