From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22508 invoked by alias); 4 Jan 2010 18:24:29 -0000 Received: (qmail 22484 invoked by uid 48); 4 Jan 2010 18:24:18 -0000 Date: Mon, 04 Jan 2010 18:24:00 -0000 Subject: [Bug tree-optimization/42614] New: FRE optimizes away valid code after IPA inlining X-Bugzilla-Reason: CC Message-ID: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "rahul at icerasemi dot com" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2010-01/txt/msg00431.txt.bz2 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; : 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 ; : 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; : # index_6 = PHI <0(2), index_7(3)> if (index_6 == 0) goto ; else goto ; : __asm__ __volatile__("before"); D.1315_8 = 0; expect_func (0, &index); 61455B->num ={v} 0; goto ; : D.1320_10 ={v} 61455B->num; D.1321_11 = D.1320_10 + 1; 61455B->num ={v} D.1321_11; index_13 = index_12 + 1; : # index_12 = PHI <0(5), index_13(6)> if (index_12 == 0) goto ; else goto ; : __asm__ __volatile__("before"); D.1320_14 ={v} 61455B->num; if (D.1320_14 != 0) goto ; else goto ; : fake_assert (0); __asm__ __volatile__("#here"); : 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) : 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