This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug middle-end/42512] [4.5 Regression] integer wrong code bug with loop
- From: "rguenth at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 8 Jan 2010 14:07:24 -0000
- Subject: [Bug middle-end/42512] [4.5 Regression] integer wrong code bug with loop
- References: <bug-42512-12544@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- 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