This fixes PR55687 - there is a latent issue in SCEV analysis. For (int) (short) {(unsigned short) i_2, +, 1 }_4 no_evolution_in_loop_p returns false when asked whether that CHREC has an evolution in loop 4 (which is obviously wrong). The reason is that the machinery is not good at filtering NOPs.
The following patch conservatively fixes it (appropriate for stage3) to use tree_contains_chrecs instead of just checking whether the outermost tree is a chrec. In fact hide_evolution_in_other_loops_than_loop isn't conservative (but luckily unused apart from from no_evolution_in_loop_p). Instead of trying to implement that no_evolution_in_loop_p could be simplified much, piggy-backing on tree_contains_chrecs (and thus also made more precise). I'll leave that for 4.9 though (PR 55689 to track that). Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Thanks, Richard. 2012-12-14 Richard Biener <rguent...@suse.de> PR tree-optimization/55687 * tree-chrec.h (no_evolution_in_loop_p): Properly use tree_contains_chrecs. * gcc.dg/torture/pr55687.c: New testcase. Index: gcc/tree-chrec.h =================================================================== *** gcc/tree-chrec.h (revision 194496) --- gcc/tree-chrec.h (working copy) *************** no_evolution_in_loop_p (tree chrec, unsi *** 117,123 **** STRIP_NOPS (chrec); scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num); ! *res = !tree_is_chrec (scev); return true; } --- 117,123 ---- STRIP_NOPS (chrec); scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num); ! *res = !tree_contains_chrecs (scev, NULL); return true; } Index: gcc/testsuite/gcc.dg/torture/pr55687.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr55687.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr55687.c (working copy) *************** *** 0 **** --- 1,29 ---- + /* { dg-do compile } */ + + typedef struct _IO_FILE FILE; + typedef short gshort; + typedef struct _GString GString; + + extern char *fgets(char *, int, FILE *); + + void verbose_text_loop (void *data) + { + FILE *dev_vcs; + char buf[81]; + GString *buf_str; + gshort i, j; + while (1) + { + for (i = 1; i <= 7; i++) + { + while (fgets (buf, 81, dev_vcs)) + { + for (j = 0; j < __builtin_strlen (buf); j++) + if (buf[j] != ' ') + break; + for (; j < __builtin_strlen (buf); j++) + g_string_append_c_inline (buf_str, buf[j]); + } + } + } + }