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]); 
+           }
+       }
+     }
+ }

Reply via email to