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


Richard Guenther wrote:
> On 11/7/07, Kenneth Zadeck <zadeck@naturalbridge.com> wrote:
>   
>> 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?
>>     
>
> Ok.
>
> Thanks,
> Richard.
>
>   
>> 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.
>>
>>
>>
>>
>>     
committed as revision 130006.

kenny

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: testsuite/gcc.dg/tree-ssa/20030714-1.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/20030714-1.c	(revision 129944)
+++ testsuite/gcc.dg/tree-ssa/20030714-1.c	(working copy)
@@ -34,13 +34,6 @@ find_base_value (src)
 }
 
 
-/* There should be four IF conditionals.  */
-/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */
-
 /* There should be no casts to short unsigned int.  */
 /* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
 
-/* There should be two loads of ->code.  */
-/* { dg-final { scan-tree-dump-times "->code" 2 "dom3"} } */
-
-/* { dg-final { cleanup-tree-dump "dom3" } } */
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]