This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug middle-end/42512] [4.5 Regression] integer wrong code bug with loop



------- Comment #5 from rguenth at gcc dot gnu dot org  2010-01-08 14:07 -------
I believe we can only either allow truncations or widenings in following
SSA edges.  Otherwise we miss that in

  int l_2; 
  for (l_2 = -1; l_2 != 0; l_2 = (unsigned char)(l_2 - 1))
    g_3 |= l_2;

the evolution is irregular in that the initial value is integer -1.  That is
what happens - we compute the evolution of the result of (unsigned char)(l_2
-1)
as { 255, +, 255 }_1 but we may not use this evolution to derive that of
the value assigned to l_2, (int) { 255, +, 255 }_1 because we cannot represent
this.  The correct evolution is -1, 254, 253 ..., 0 which isn't representable.

Thus I think we need to either kill the conversion code completely or
at least severely restrict it with sth like

Index: gcc/tree-scalar-evolution.c
===================================================================
--- gcc/tree-scalar-evolution.c (revision 155732)
+++ gcc/tree-scalar-evolution.c (working copy)
@@ -1161,9 +1161,19 @@ follow_ssa_edge_expr (struct loop *loop,
     {
     CASE_CONVERT:
       /* This assignment is under the form "a_1 = (cast) rhs.  */
-      res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
-                                 halting_phi, evolution_of_loop, limit);
-      *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+      rhs0 = TREE_OPERAND (expr, 0);
+      if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs0))
+         || TREE_CODE (*evolution_of_loop) != POLYNOMIAL_CHREC)
+       {
+         res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
+                                     halting_phi, evolution_of_loop, limit);
+         *evolution_of_loop = chrec_convert (type, *evolution_of_loop,
at_stmt);
+       }
+      else
+       {
+         *evolution_of_loop = chrec_dont_know;
+         res = t_false;
+       }
       break;

     case INTEGER_CST:
@@ -1219,14 +1229,25 @@ follow_ssa_edge_in_rhs (struct loop *loo
   enum tree_code code = gimple_assign_rhs_code (stmt);
   tree type = gimple_expr_type (stmt), rhs1, rhs2;
   t_bool res;
+  tree name;

   switch (code)
     {
     CASE_CONVERT:
       /* This assignment is under the form "a_1 = (cast) rhs.  */
-      res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
-                                 halting_phi, evolution_of_loop, limit);
-      *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
+      name = gimple_assign_rhs1 (stmt);
+      if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (name))
+         || TREE_CODE (*evolution_of_loop) != POLYNOMIAL_CHREC)
+       {
+         res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
+                                     halting_phi, evolution_of_loop, limit);
+         *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
+       }
+      else
+       {
+         *evolution_of_loop = chrec_dont_know;
+         res = t_false;
+       }
       break;

     case POINTER_PLUS_EXPR:
@@ -1759,7 +1780,11 @@ interpret_rhs_expr (struct loop *loop, g

     CASE_CONVERT:
       chrec1 = analyze_scalar_evolution (loop, rhs1);
-      res = chrec_convert (type, chrec1, at_stmt);
+      if (TYPE_PRECISION (type) == TYPE_PRECISION (TREE_TYPE (rhs1))
+         || TREE_CODE (chrec1) != POLYNOMIAL_CHREC)
+       res = chrec_convert (type, chrec1, at_stmt);
+      else
+       res = chrec_dont_know;
       break;

     default:


Sebastian - any better idea?  This will at least regress

FAIL: gcc.dg/tree-ssa/scev-cast.c scan-tree-dump-times optimized "= \(unsigned
char\)" 1
FAIL: gcc.dg/tree-ssa/scev-cast.c scan-tree-dump-times optimized "= \(char\)" 1


because we cannot distinguish the really critical cases from ok ones.
The patch in comment #4 just makes the issue latent again.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42512


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]