typedef signed long long int WordS64; typedef unsigned long long int Word64; int foo (Word64 *p) { while (1) { WordS64 c = 0x1llu; WordS64 x = *p; if (c >= 0) { if (x > (WordS64) 0x7FFFFFFFFFFFFFFFll - c) return 6; } else if (x < (WordS64) 0x8000000000000000ll - c) return 7; p++; } } ICEs at -O1 or -O2 in chain_of_csts_start, which is called on <nop_expr 0x2aaaae936d40 type <integer_type 0x2aaaae93b790 long long int sizes-gimplified DI size <integer_cst 0x2aaaae92bdb0 constant invariant 64> unit size <integer_cst 0x2aaaae92bde0 constant invariant 8> align 64 symtab 0 alias set 3 precision 64 min <integer_cst 0x2aaaae92bf00 -9223372036854775808> max <integer_cst 0x2aaaae92bf30 9223372036854775807> pointer_to_this <pointer_type 0x2aaaae9e1840>> arg 0 <ssa_name 0x2aaaaeafb780 type <integer_type 0x2aaaaeaf69a0 WordS64 sizes-gimplified public DI size <integer_cst 0x2aaaae92bdb0 64> unit size <integer_cst 0x2aaaae92bde0 8> align 64 symtab 0 alias set -1 precision 64 min <integer_cst 0x2aaaae92bf00 -9223372036854775808> max <integer_cst 0x2aaaae92bf30 9223372036854775807>> var <var_decl 0x2aaaaeaf6d10 x> def_stmt <modify_expr 0x2aaaae931960> version 6>> but assumes the argument is SSA_NAME.
which target? I cannot reproduce this.
x86_64-linux. Rebuilding gcc 4.2 with --enable-checking yields a verify_stmt failure already after ccp, which changes WordS64D.1870 xD.1876; long long intD.5 D.1879; ... D.1879_7 = 9223372036854775807 - cD.1875_4; if (D.1879_7 < xD.1876_6) goto <L2>; else goto <L6>; into: WordS64D.1870 xD.1876; if ((long long intD.5) xD.1876_6 == 9223372036854775807) goto <L2>; else goto <L6>; which is invalid gimple. But the operands of the comparison had different types of arguments already before. Guess the gimple type system patches cured this on the trunk.
*** Bug 32695 has been marked as a duplicate of this bug. ***
*** Bug 32696 has been marked as a duplicate of this bug. ***
This got fixed by http://gcc.gnu.org/ml/gcc-patches/2006-11/msg00206.html on the trunk. Even is subset of those changes fixes this on 4.2 branch: --- gcc/tree-ssa-ccp.c.jj 2007-03-20 00:22:09.000000000 +0100 +++ gcc/tree-ssa-ccp.c 2007-07-10 14:49:15.000000000 +0200 @@ -2063,12 +2063,13 @@ fold_stmt_r (tree *expr_p, int *walk_sub tem = fold_binary (TREE_CODE (op0), TREE_TYPE (op0), TREE_OPERAND (op0, 0), TREE_OPERAND (op0, 1)); - set = tem && is_gimple_condexpr (tem); + set = tem && set_rhs (expr_p, tem); fold_undefer_overflow_warnings (set, fold_stmt_r_data->stmt, 0); if (set) - TREE_OPERAND (expr, 0) = tem; - t = expr; - break; + { + t = *expr_p; + break; + } } default: --- gcc/tree-ssa-propagate.c.jj 2007-03-20 00:22:09.000000000 +0100 +++ gcc/tree-ssa-propagate.c 2007-07-10 14:55:18.000000000 +0200 @@ -571,7 +571,8 @@ set_rhs (tree *stmt_p, tree expr) ssa_op_iter iter; /* Verify the constant folded result is valid gimple. */ - if (TREE_CODE_CLASS (code) == tcc_binary) + if (TREE_CODE_CLASS (code) == tcc_binary + || TREE_CODE_CLASS (code) == tcc_comparison) { if (!is_gimple_val (TREE_OPERAND (expr, 0)) || !is_gimple_val (TREE_OPERAND (expr, 1))) which prevents in this case generating invalid gimple. On gcc-4_1-branch, even just the tree-ssa-propagate.c chunk cures this. Is this something which can safely be changed on the release branches?
Subject: Bug 32694 Author: jakub Date: Tue Sep 25 15:14:42 2007 New Revision: 128766 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128766 Log: PR tree-optimization/32694 2006-11-08 Roger Sayle <roger@eyesopen.com> * tree-ssa-propagate.c (set_rhs): Verify tcc_comparison the same way as tcc_binary. * tree-ssa-ccp.c (fold_stmt_r) <COND_EXPR>: Use set_rhs to modify the condition after calling fold_binary. * gcc.c-torture/compile/20070925-1.c: New test. Added: branches/gcc-4_2-branch/gcc/testsuite/gcc.c-torture/compile/20070925-1.c Modified: branches/gcc-4_2-branch/gcc/ChangeLog branches/gcc-4_2-branch/gcc/testsuite/ChangeLog branches/gcc-4_2-branch/gcc/tree-ssa-ccp.c branches/gcc-4_2-branch/gcc/tree-ssa-propagate.c
Confirmed.
Closing 4.1 branch.