Bug 27136 - [4.0/4.1 Regression] Compile failure with -O -ffast-math
Summary: [4.0/4.1 Regression] Compile failure with -O -ffast-math
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.0.4
Assignee: Richard Biener
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2006-04-12 17:25 UTC by Tom Truscott
Modified: 2006-05-09 16:02 UTC (History)
3 users (show)

See Also:
Host: i686-pc-linux-gnu
Target:
Build:
Known to work: 3.4.0 4.2.0
Known to fail: 4.0.0 4.1.0
Last reconfirmed: 2006-05-07 13:13:02


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Truscott 2006-04-12 17:25:28 UTC
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)
        ;
    }
Comment 1 Andrew Pinski 2006-04-13 01:37:35 UTC
Confirmed.
Comment 2 Richard Biener 2006-04-17 10:34:15 UTC
#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.
Comment 3 Richard Biener 2006-04-17 10:51:38 UTC
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)
Comment 4 Richard Biener 2006-04-17 11:12:28 UTC
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.

Comment 5 Richard Biener 2006-04-17 11:18:33 UTC
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.
Comment 6 patchapp@dberlin.org 2006-04-17 13:10:42 UTC
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
Comment 7 Richard Biener 2006-05-07 13:07:33 UTC
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

Comment 8 Richard Biener 2006-05-07 13:13:02 UTC
Fixed on the mainline.
Comment 9 Richard Biener 2006-05-09 15:56:29 UTC
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

Comment 10 Richard Biener 2006-05-09 16:02:02 UTC
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

Comment 11 Richard Biener 2006-05-09 16:02:38 UTC
Fixed.