This avoids going back-and-forth from linearized to widened expressions in reassoc twice and only rewrites expressions according to reassoc-width in the last reassoc pass.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2019-06-25 Richard Biener <rguent...@suse.de> PR tree-optimization/90930 * tree-ssa-reassoc.c (reassociate_bb): Only rewrite expression into parallel form in the last pass instance. * gcc.dg/tree-ssa/reassoc-24.c: Adjust. * gcc.dg/tree-ssa/reassoc-25.c: Likewise. Index: gcc/tree-ssa-reassoc.c =================================================================== --- gcc/tree-ssa-reassoc.c (revision 272636) +++ gcc/tree-ssa-reassoc.c (working copy) @@ -6013,12 +6013,7 @@ reassociate_bb (basic_block bb) { machine_mode mode = TYPE_MODE (TREE_TYPE (lhs)); int ops_num = ops.length (); - int width = get_reassociation_width (ops_num, rhs_code, mode); - - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, - "Width = %d was chosen for reassociation\n", width); - + int width; /* For binary bit operations, if there are at least 3 operands and the last last operand in OPS is a constant, @@ -6032,10 +6027,21 @@ reassociate_bb (basic_block bb) && TREE_CODE (ops.last ()->op) == INTEGER_CST) std::swap (*ops[0], *ops[ops_num - 1]); - if (width > 1 - && ops.length () > 3) - rewrite_expr_tree_parallel (as_a <gassign *> (stmt), - width, ops); + /* Only rewrite the expression tree to parallel in the + last reassoc pass to avoid useless work back-and-forth + with initial linearization. */ + if (!reassoc_insert_powi_p + && ops.length () > 3 + && (width = get_reassociation_width (ops_num, rhs_code, + mode)) > 1) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, + "Width = %d was chosen for reassociation\n", + width); + rewrite_expr_tree_parallel (as_a <gassign *> (stmt), + width, ops); + } else { /* When there are three operands left, we want Index: gcc/testsuite/gcc.dg/tree-ssa/reassoc-24.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/reassoc-24.c (revision 272636) +++ gcc/testsuite/gcc.dg/tree-ssa/reassoc-24.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 --param tree-reassoc-width=2 -fdump-tree-reassoc1" } */ +/* { dg-options "-O2 --param tree-reassoc-width=2 -fdump-tree-reassoc2" } */ unsigned int foo (void) @@ -21,4 +21,4 @@ foo (void) /* Verify there are two pairs of __asm__ statements with no intervening stmts. */ -/* { dg-final { scan-tree-dump-times "__asm__\[^;\n]*;\n *__asm__" 2 "reassoc1"} } */ +/* { dg-final { scan-tree-dump-times "__asm__\[^;\n]*;\n *__asm__" 2 "reassoc2"} } */ Index: gcc/testsuite/gcc.dg/tree-ssa/reassoc-25.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/reassoc-25.c (revision 272636) +++ gcc/testsuite/gcc.dg/tree-ssa/reassoc-25.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 --param tree-reassoc-width=3 -fdump-tree-reassoc1-details" } */ +/* { dg-options "-O2 --param tree-reassoc-width=3 -fdump-tree-reassoc2-details" } */ unsigned int foo (int a, int b, int c, int d) @@ -15,4 +15,4 @@ foo (int a, int b, int c, int d) } /* Verify reassociation width was chosen to be 2. */ -/* { dg-final { scan-tree-dump-times "Width = 2" 1 "reassoc1"} } */ +/* { dg-final { scan-tree-dump-times "Width = 2" 1 "reassoc2"} } */