This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [Bug tree-optimization/33826] [4.1/4.2/4.3 Regression] GCC generates wrong code for infinitely recursive functions
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: Richard Guenther <richard dot guenther at gmail dot com>
- Cc: gcc-bugzilla at gcc dot gnu dot org, gcc-patches <gcc-patches at gcc dot gnu dot org>, Eric Botcazou <ebotcazou at libertysurf dot fr>
- Date: Thu, 08 Nov 2007 11:48:11 -0500
- Subject: Re: [Bug tree-optimization/33826] [4.1/4.2/4.3 Regression] GCC generates wrong code for infinitely recursive functions
- References: <bug-33826-12387@http.gcc.gnu.org/bugzilla/> <20071106212132.30537.qmail@sourceware.org> <47320767.4010004@naturalbridge.com> <84fc9c000711080108u284cd84alb1c46c927295a72c@mail.gmail.com>
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. */