Bug 32694

Summary: [4.1 Regression] ICE with long long arithmetic
Product: gcc Reporter: Jakub Jelinek <jakub>
Component: tree-optimizationAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: dnovillo, fang, gcc-bugs, pinskia, rakdver, reichelt, rguenth
Priority: P1 Keywords: ice-on-valid-code, monitored
Version: 4.1.2   
Target Milestone: 4.2.2   
Host: Target:
Build: Known to work: 4.1.0 4.1.1 4.1.2 4.2.2
Known to fail: 4.1.3 4.2.0 4.2.1 Last reconfirmed: 2007-12-27 17:34:18

Description Jakub Jelinek 2007-07-09 12:35:56 UTC
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.
Comment 1 Richard Biener 2007-07-09 12:46:06 UTC
which target?  I cannot reproduce this.
Comment 2 Jakub Jelinek 2007-07-09 12:52:24 UTC
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.
Comment 3 Jakub Jelinek 2007-07-09 12:53:56 UTC
*** Bug 32695 has been marked as a duplicate of this bug. ***
Comment 4 Jakub Jelinek 2007-07-09 12:54:19 UTC
*** Bug 32696 has been marked as a duplicate of this bug. ***
Comment 5 Jakub Jelinek 2007-07-10 13:10:12 UTC
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?
Comment 6 Jakub Jelinek 2007-09-25 15:14:53 UTC
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

Comment 7 Volker Reichelt 2007-12-27 17:34:18 UTC
Confirmed.
Comment 8 Joseph S. Myers 2008-07-04 16:11:06 UTC
Closing 4.1 branch.