[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Bug tree-optimization/33826] [4.1/4.2/4.3 Regression] GCC generates wrong code for infinitely recursive functions




------- Comment #10 from zadeck at naturalbridge dot com  2007-11-07 18:44 -------
Subject: Re:  [4.1/4.2/4.3 Regression] GCC generates
 wrong code for infinitely recursive functions

This patch keeps recursive functions from being marked as pure or const.

Full testing in progress on x86-64.  But the code seems to work properly.

Ok to commit when the full testing is finished?

Kenny

2007-11-07  Kenneth Zadeck <zadeck@naturalbridge.com>

    PR middle-end/33826
    * ipa-pure-const (static_execute): Added code to keep recursive
    functions from being marked as pure or const.
    * ipa-utils (searchc): Fixed comment.

2007-11-07  Kenneth Zadeck <zadeck@naturalbridge.com>

    PR middle-end/33826
    * gcc.dg/pr33826.c: New.


Index: testsuite/gcc.dg/pr33826.c
===================================================================
--- testsuite/gcc.dg/pr33826.c  (revision 0)
+++ testsuite/gcc.dg/pr33826.c  (revision 0)
@@ -0,0 +1,40 @@
+/* Regression test for PR middle-end/33826 */
+/* Verify that recursive functions cannot be pure or const.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-ipa-pure-const" } */
+
+int recurese1 (int i)
+{
+  return recurse1 (i+1);
+}
+
+int recurse2a (int i)
+{
+  return recurse2b (i+1);
+}
+
+int recurse2b (int i)
+{
+  return recurse2a (i+1);
+}
+
+int norecurse1a (int i)
+{
+  return norecurse1b (i+1);
+}
+
+int norecurse1b (int i)
+{
+  return i+1;
+}
+
+/* { dg-final { scan-ipa-dump "found to be const: norecurse1a" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump "found to be const: norecurse1b" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse1" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2a" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2b" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse1" "pure-const" }
} */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse2a" "pure-const"
} } */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse2b" "pure-const"
} } */
+/* { dg-final { cleanup-ipa-dump "pure-const" } } */
Index: ipa-pure-const.c
===================================================================
--- ipa-pure-const.c    (revision 129944)
+++ ipa-pure-const.c    (working copy)
@@ -644,6 +644,7 @@ static_execute (void)
   for (i = 0; i < order_pos; i++ )
     {
       enum pure_const_state_e pure_const_state = IPA_CONST;
+      int count = 0;
       node = order[i];

       /* Find the worst state for any node in the cycle.  */
@@ -660,11 +661,40 @@ static_execute (void)
          if (!w_l->state_set_in_source)
            {
              struct cgraph_edge *e;
+             count++;
+
+             /* FIXME!!!  Because of pr33826, we cannot have either
+                immediate or transitive recursive functions marked as
+                pure or const because dce can delete a function that
+                is in reality an infinite loop.  A better solution
+                than just outlawing them is to add another bit the
+                functions to distinguish recursive from non recursive
+                pure and const function.  This would allow the
+                recursive ones to be cse'd but not dce'd.  In this
+                same vein, we could allow functions with loops to
+                also be cse'd but not dce'd.
+
+                Unfortunately we are late in stage 3, and the fix
+                described above is is not appropriate.  */
+             if (count > 1)
+               {
+                 pure_const_state = IPA_NEITHER;
+                 break;
+               }
+                   
              for (e = w->callees; e; e = e->next_callee) 
                {
                  struct cgraph_node *y = e->callee;
                  /* Only look at the master nodes and skip external nodes.  */
                  y = cgraph_master_clone (y);
+
+                 /* Check for immediate recursive functions.  See the
+                    FIXME above.  */
+                 if (w == y)
+                   {
+                     pure_const_state = IPA_NEITHER;
+                     break;
+                   }
                  if (y)
                    {
                      funct_state y_l = get_function_state (y);
Index: ipa-utils.c
===================================================================
--- ipa-utils.c (revision 129944)
+++ ipa-utils.c (working copy)
@@ -76,7 +76,7 @@ struct searchc_env {
    has been customized for cgraph_nodes.  The env parameter is because
    it is recursive and there are no nested functions here.  This
    function should only be called from itself or
-   cgraph_reduced_inorder.  ENV is a stack env and would be
+   ipa_utils_reduced_inorder.  ENV is a stack env and would be
    unnecessary if C had nested functions.  V is the node to start
    searching from.  */



-- 


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

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.



Reply to: