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: gcc-bugzilla at gcc dot gnu dot org
- Cc: zadeck at gcc dot gnu dot org, gcc-patches <gcc-patches at gcc dot gnu dot org>, Eric Botcazou <ebotcazou at libertysurf dot fr>
- Date: Wed, 07 Nov 2007 13:43:51 -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>
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. */