This program, compiled -O -ffast-math, seems to consume infinite stack space /* -O -ffast-math */ void foo() { double x; for (x = 2; x < 10; x *= x) ; }
Confirmed.
#5 0x081a8738 in get_val_for (x=0xb7dedea0, base=0xb7d70480) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/tree-ssa-loop-niter.c:1254 1254 val = fold (TREE_OPERAND (stmt, 1)); (gdb) call debug_generic_expr(stmt) xD.1278_3 = __builtin_pow (4.0e+0, 2.0e+0) which we don't evaluate at compile-time. So loop_niter_by_eval builds (gdb) call debug_generic_expr(expr) __builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow (__builtin_pow ...... on which we punt at some point. Now, we definitely should fold 4.0**2.0 at compile time, too.
Hmm, looks more like a tree sharing problem Breakpoint 5, fold_ternary (code=CALL_EXPR, type=0xb7d5fa6c, op0=0xb7d55540, op1=0xb7dd9048, op2=0x0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/fold-const.c:9945 9945 tree arg0 = NULL_TREE, arg1 = NULL_TREE; (gdb) call debug_tree(op1) <tree_list 0xb7dd9048 value <call_expr 0xb7dd1028 type <real_type 0xb7d5fa6c double sizes-gimplified DF size <integer_cst 0xb7d50540 constant invariant 64> unit size <integer_cst 0xb7d50558 constant invariant 8> align 64 symtab 0 alias set -1 precision 64 pointer_to_this <pointer_type 0xb7d5fb80>> nothrow arg 0 <addr_expr 0xb7d55240 type <pointer_type 0xb7dcf3f4> readonly constant invariant arg 0 <function_decl 0xb7d80d80 __builtin_pow>> arg 1 <tree_list 0xb7dd67e0 value <call_expr 0xb7dd1028> chain <tree_list 0xb7dd67c8 value <real_cst 0xb7dd6798 type <real_type 0xb7d5fa6c double> constant invariant 2.0e+0>>> t.c:5> chain <tree_list 0xb7dd9030 value <real_cst 0xb7dd9000 type <real_type 0xb7d5fa6c double> constant invariant 3.2e+1>>> we are self-referencing and so built up an infinite chain of pow (pow (..., 2)
1329 aval[j] = get_val_for (op[j], val[j]); (gdb) call debug_generic_expr(val[0]) __builtin_pow (xD.1278_4, 2.0e+0) (gdb) call debug_generic_expr(op[0]) xD.1278_3 Program received signal SIGSEGV, Segmentation fault. 0x08316db6 in operand_equal_p (arg0=0xb7dc0798, arg1=0xb7c556c0, flags=0) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/fold-const.c:2423 2423 if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))) I think the brute-force evaluation should stop as soon as val[i] is no longer a constant. get_val_for (x=0xb7d3aea0, base=0xb7d39028) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/tree-ssa-loop-niter.c:1242 1246 if (TREE_CODE (stmt) == PHI_NODE) (gdb) call debug_generic_expr(stmt) xD.1278_3 = __builtin_pow (xD.1278_4, 2.0e+0) (gdb) call debug_generic_expr(x) xD.1278_3 (gdb) call debug_generic_expr(base) __builtin_pow (xD.1278_4, 2.0e+0) now, stmt is the same as the stmt of the first use. get_val_for (x=0xb7d40104, base=0xb7d39028) at /space/rguenther/src/svn/gcc-4_1-branch/gcc/tree-ssa-loop-niter.c:1242 1242 if (!x) (gdb) finish Value returned is $11 = (union tree_node *) 0xb7d39028 (gdb) call debug_generic_expr($11) __builtin_pow (xD.1278_4, 2.0e+0) 1253 SET_USE (op, val); kaboom. We just created a self-referencing tree here. Now, either punt on non-constant/SSA_NAME val, or unshare val, or punt earlier.
Now, the comment before get_val_for is confusing, as it says * if BASE is NULL_TREE, X must be a constant and we return X. but we do if (!x) return base; now, I believe a gcc_assert (is_gimple_min_invariant (base)); before this statement is what needs to hold. So the caller needs to be fixed.
Subject: Bug number PR 27136 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-04/msg00623.html
Subject: Bug 27136 Author: rguenth Date: Sun May 7 13:07:22 2006 New Revision: 113601 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113601 Log: 2006-05-07 Richard Guenther <rguenther@suse.de> PR tree-optimization/27136 * tree-ssa-loop-niter.c (get_val_for): Correct function comment, assert requirements. (loop_niter_by_eval): Stop processing if the iterated value did not simplify. * gcc.dg/torture/pr27136.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr27136.c Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-loop-niter.c
Fixed on the mainline.
Subject: Bug 27136 Author: rguenth Date: Tue May 9 15:56:12 2006 New Revision: 113656 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113656 Log: 2006-05-09 Richard Guenther <rguenther@suse.de> PR tree-optimization/27136 * tree-ssa-loop-niter.c (get_val_for): Correct function comment, assert requirements. (loop_niter_by_eval): Stop processing if the iterated value did not simplify. * gcc.dg/torture/pr27136.c: New testcase. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/torture/pr27136.c - copied unchanged from r113601, trunk/gcc/testsuite/gcc.dg/torture/pr27136.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/testsuite/ChangeLog branches/gcc-4_1-branch/gcc/tree-ssa-loop-niter.c
Subject: Bug 27136 Author: rguenth Date: Tue May 9 16:01:53 2006 New Revision: 113657 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=113657 Log: 2006-05-09 Richard Guenther <rguenther@suse.de> PR tree-optimization/27136 * tree-ssa-loop-niter.c (get_val_for): Correct function comment, assert requirements. (loop_niter_by_eval): Stop processing if the iterated value did not simplify. * gcc.dg/torture/pr27136.c: New testcase. Added: branches/gcc-4_0-branch/gcc/testsuite/gcc.dg/torture/pr27136.c - copied unchanged from r113601, trunk/gcc/testsuite/gcc.dg/torture/pr27136.c Modified: branches/gcc-4_0-branch/gcc/ChangeLog branches/gcc-4_0-branch/gcc/testsuite/ChangeLog branches/gcc-4_0-branch/gcc/tree-ssa-loop-niter.c
Fixed.