Reduced from libiberty:

char ada_demangle (const char *mangled, int len0)
{
  int i;
  for (i = len0 - 2; i >= 0 && mangled[i]; i -= 1)
    ;
  return mangled[i];
}

in tree-ssa-loop-ivopts.c:

static void
rewrite_use_compare (struct ivopts_data *data,
                     struct iv_use *use, struct iv_cand *cand)
{
  tree comp;
  tree *op_p, cond, op, stmts, bound;
  block_stmt_iterator bsi = bsi_for_stmt (use->stmt);
  enum tree_code compare;
  struct cost_pair *cp = get_use_iv_cost (data, use, cand);

  bound = cp->value;
  if (bound)
    {
      tree var = var_at_stmt (data->current_loop, cand, use->stmt);
      tree var_type = TREE_TYPE (var);

      compare = iv_elimination_compare (data, use);
      bound = fold_convert (var_type, bound);

we convert unsigned 4294967295 to -1 (overflowed):

#1  0x0825312e in rewrite_use_compare (data=0xbfcf4a18, use=0x8a5e070,
    cand=0x8a81ca8) at /home/richard/src/trunk2/gcc/tree-ssa-loop-ivopts.c:5128
5128          *use->op_p = build2 (compare, boolean_type_node, var, op);
(gdb) call debug_tree (bound)
 <integer_cst 0xb7ce1df8 type <integer_type 0xb7c512d8 int> constant invariant
public static overflow -1>
(gdb) print *cp
$1 = {cand = 0x8a81ca8, cost = 0, depends_on = 0x0, value = 0xb7c41438}
(gdb) call debug_tree (cp->value)
 <integer_cst 0xb7c41438 type <integer_type 0xb7c51340 unsigned int> constant
invariant 4294967295>

this causes an assert that I added to trip later in tree-vrp.c where I
assert to not register a value range with min/max that have overflow flag set.

Proposed hack:

Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c      (revision 120621)
--- tree-ssa-loop-ivopts.c      (working copy)
*************** rewrite_use_compare (struct ivopts_data
*** 5119,5124 ****
--- 5119,5127 ----

        compare = iv_elimination_compare (data, use);
        bound = fold_convert (var_type, bound);
+       if (TREE_CODE (bound) == INTEGER_CST
+         && TREE_OVERFLOW (bound))
+       goto out;
        op = force_gimple_operand (unshare_expr (bound), &stmts,
                                 true, NULL_TREE);

*************** rewrite_use_compare (struct ivopts_data
*** 5129,5134 ****
--- 5132,5138 ----
        update_stmt (use->stmt);
        return;
      }
+ out:

    /* The induction variable elimination failed; just express the original
       giv.  */


-- 
           Summary: IVOPTS generates comparison with overflowed constant
           Product: gcc
           Version: 4.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rguenth at gcc dot gnu dot org


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

Reply via email to