On March 22, 2017 7:52:40 PM GMT+01:00, Jakub Jelinek <ja...@redhat.com> wrote:
>Hi!
>
>On the huge testcase from the PR (not really reduceable) we run into
>reassoc ranks bigger than INT_MAX (bb_rank is multiples of 65536,
>so it might be enough to have just 32768+ basic blocks to reach that).
>Rank is unsigned int, but we were returning (int) (oeb->rank -
>oea->rank);
>from the comparison function, which means when unlucky enough it could
>sort
>entries with huge rank e.g. after entries with 0 rank.  Rest of reassoc
>relies on the constants (rank 0) being sorted last though.
>
>The patch also applies similar changes to other fields, that are far
>less
>likely to be huge, but could be in theory.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Richard.

>2017-03-22  Jakub Jelinek  <ja...@redhat.com>
>
>       PR tree-optimization/80072
>       * tree-ssa-reassoc.c (struct operand_entry): Change id field type
>       to unsigned int.
>       (next_operand_entry_id): Change type to unsigned int.
>       (sort_by_operand_rank): Make sure to return the right return value
>       even if unsigned fields are bigger than INT_MAX.
>       (struct oecount): Change cnt and id type to unsigned int.
>       (oecount_hasher::equal): Formatting fix.
>       (oecount_cmp): Make sure to return the right return value
>       even if unsigned fields are bigger than INT_MAX.
>       (undistribute_ops_list): Change next_oecount_id type to unsigned int.
>
>--- gcc/tree-ssa-reassoc.c.jj  2017-02-10 09:46:50.000000000 +0100
>+++ gcc/tree-ssa-reassoc.c     2017-03-22 13:57:00.476928949 +0100
>@@ -193,7 +193,7 @@ static struct
> struct operand_entry
> {
>   unsigned int rank;
>-  int id;
>+  unsigned int id;
>   tree op;
>   unsigned int count;
>   gimple *stmt_to_insert;
>@@ -204,7 +204,7 @@ static object_allocator<operand_entry> o
> 
> /* This is used to assign a unique ID to each struct operand_entry
>    so that qsort results are identical on different hosts.  */
>-static int next_operand_entry_id;
>+static unsigned int next_operand_entry_id;
> 
> /* Starting rank number for a given basic block, so that we can rank
>    operations using unmovable instructions in that BB based on the bb
>@@ -505,12 +505,12 @@ sort_by_operand_rank (const void *pa, co
>       else
>       /* To make sorting result stable, we use unique IDs to determine
>          order.  */
>-        return oeb->id - oea->id;
>+      return oeb->id > oea->id ? 1 : -1;
>     }
> 
>   /* Lastly, make sure the versions that are the same go next to each
>      other.  */
>-  if ((oeb->rank - oea->rank == 0)
>+  if (oeb->rank == oea->rank
>       && TREE_CODE (oea->op) == SSA_NAME
>       && TREE_CODE (oeb->op) == SSA_NAME)
>     {
>@@ -543,15 +543,15 @@ sort_by_operand_rank (const void *pa, co
>       }
> 
>       if (SSA_NAME_VERSION (oeb->op) != SSA_NAME_VERSION (oea->op))
>-      return SSA_NAME_VERSION (oeb->op) - SSA_NAME_VERSION (oea->op);
>+      return SSA_NAME_VERSION (oeb->op) > SSA_NAME_VERSION (oea->op) ? 1 :
>-1;
>       else
>-      return oeb->id - oea->id;
>+      return oeb->id > oea->id ? 1 : -1;
>     }
> 
>   if (oeb->rank != oea->rank)
>-    return oeb->rank - oea->rank;
>+    return oeb->rank > oea->rank ? 1 : -1;
>   else
>-    return oeb->id - oea->id;
>+    return oeb->id > oea->id ? 1 : -1;
> }
> 
> /* Add an operand entry to *OPS for the tree operand OP.  */
>@@ -1055,8 +1055,8 @@ static void linearize_expr_tree (vec<ope
> 
> /* Structure for tracking and counting operands.  */
> struct oecount {
>-  int cnt;
>-  int id;
>+  unsigned int cnt;
>+  unsigned int id;
>   enum tree_code oecode;
>   tree op;
> };
>@@ -1090,8 +1090,7 @@ oecount_hasher::equal (int p1, int p2)
> {
>   const oecount *c1 = &cvec[p1 - 42];
>   const oecount *c2 = &cvec[p2 - 42];
>-  return (c1->oecode == c2->oecode
>-        && c1->op == c2->op);
>+  return c1->oecode == c2->oecode && c1->op == c2->op;
> }
> 
>/* Comparison function for qsort sorting oecount elements by count.  */
>@@ -1102,10 +1101,10 @@ oecount_cmp (const void *p1, const void
>   const oecount *c1 = (const oecount *)p1;
>   const oecount *c2 = (const oecount *)p2;
>   if (c1->cnt != c2->cnt)
>-    return c1->cnt - c2->cnt;
>+    return c1->cnt > c2->cnt ? 1 : -1;
>   else
>     /* If counts are identical, use unique IDs to stabilize qsort.  */
>-    return c1->id - c2->id;
>+    return c1->id > c2->id ? 1 : -1;
> }
> 
> /* Return TRUE iff STMT represents a builtin call that raises OP
>@@ -1559,7 +1558,7 @@ undistribute_ops_list (enum tree_code op
>   sbitmap_iterator sbi0;
>   vec<operand_entry *> *subops;
>   bool changed = false;
>-  int next_oecount_id = 0;
>+  unsigned int next_oecount_id = 0;
> 
>   if (length <= 1
>       || opcode != PLUS_EXPR)
>
>       Jakub

Reply via email to