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

zadeck at naturalbridge dot com gcc-bugzilla@gcc.gnu.org
Thu Nov 8 16:48:00 GMT 2007



------- Comment #14 from zadeck at naturalbridge dot com  2007-11-08 16:48 -------
Subject: Re:  [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.  */



-- 


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



More information about the Gcc-bugs mailing list