This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Bug tree-optimization/33826] [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.  */
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]