On Fri, 12 Aug 2016, Richard Biener wrote: > > The following fixes a missed optimization in PRE which was over-cautionous > with rejecting simplifications to SSA names during phi-translation. > > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Requires some testsuite adjustments as below as PRE now catches quite some predictive commoning cases. Tested on x86_64_unknown-linux-gnu, applied. Richard. 2016-08-12 Richard Biener <rguent...@suse.de> PR tree-optimization/57326 * tree-ssa-pre.c (fully_constant_expression): Handle simplification returning an SSA name. (phi_translate_1): When fully_constant_expression returns a NAME make sure we have a leader for it. * gcc.dg/tree-ssa/ssa-pre-32.c: New testcase. * gcc.dg/tree-ssa/loadpre14.c: Adjust. * gcc.dg/tree-ssa/pr35287.c: Likewise. * gcc.target/i386/pr45685.c: Likewise. * gcc.dg/tree-ssa/predcom-1.c: Disable PRE. * gcc.dg/tree-ssa/predcom-2.c: Likewise. * gcc.dg/tree-ssa/predcom-3.c: Likewise. * gcc.dg/tree-ssa/ssa-sink-10.c: Likewise. * gfortran.dg/pr34163.f90: Likewise. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 239361) --- gcc/tree-ssa-pre.c (working copy) *************** get_or_alloc_expr_for (tree t) *** 1201,1207 **** } /* Return the folded version of T if T, when folded, is a gimple ! min_invariant. Otherwise, return T. */ static pre_expr fully_constant_expression (pre_expr e) --- 1201,1207 ---- } /* Return the folded version of T if T, when folded, is a gimple ! min_invariant or an SSA name. Otherwise, return T. */ static pre_expr fully_constant_expression (pre_expr e) *************** fully_constant_expression (pre_expr e) *** 1218,1227 **** return e; if (is_gimple_min_invariant (res)) return get_or_alloc_expr_for_constant (res); ! /* We might have simplified the expression to a ! SSA_NAME for example from x_1 * 1. But we cannot ! insert a PHI for x_1 unconditionally as x_1 might ! not be available readily. */ return e; } case REFERENCE: --- 1218,1225 ---- return e; if (is_gimple_min_invariant (res)) return get_or_alloc_expr_for_constant (res); ! if (TREE_CODE (res) == SSA_NAME) ! return get_or_alloc_expr_for_name (res); return e; } case REFERENCE: *************** phi_translate_1 (pre_expr expr, bitmap_s *** 1464,1470 **** constant = fully_constant_expression (expr); PRE_EXPR_NARY (expr) = nary; if (constant != expr) ! return constant; tree result = vn_nary_op_lookup_pieces (newnary->length, newnary->opcode, --- 1462,1481 ---- constant = fully_constant_expression (expr); PRE_EXPR_NARY (expr) = nary; if (constant != expr) ! { ! /* For non-CONSTANTs we have to make sure we can eventually ! insert the expression. Which means we need to have a ! leader for it. */ ! if (constant->kind != CONSTANT) ! { ! unsigned value_id = get_expr_value_id (constant); ! constant = find_leader_in_sets (value_id, set1, set2); ! if (constant) ! return constant; ! } ! else ! return constant; ! } tree result = vn_nary_op_lookup_pieces (newnary->length, newnary->opcode, Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c =================================================================== *** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c (revision 0) --- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-32.c (working copy) *************** *** 0 **** --- 1,11 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-pre" } */ + + unsigned f(unsigned x, unsigned y, _Bool b) + { + #define m (b?-1:0) + return (x&m)|(y&~m); + #undef m + } + + /* { dg-final { scan-tree-dump "# prephitmp_\[0-9\]+ = PHI <\[xy\]_\[0-9\]+\\(D\\)\[^,\]*, \[xy\]_\[0-9\]+\\(D\\)" "pre" } } */ Index: gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/loadpre14.c (working copy) @@ -6,7 +6,8 @@ int foo(type *a, int argc) type c = {0, 1}; int d, e; - /* Should be able to eliminate the second load of *a along the main path. */ + /* Should be able to eliminate the second load of *a and the add of zero + along the main path. */ d = (*a)[0]; if (argc) { @@ -15,4 +16,4 @@ int foo(type *a, int argc) e = (*a)[0]; return d + e; } -/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */ +/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */ Index: gcc/testsuite/gcc.dg/tree-ssa/pr35287.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/pr35287.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/pr35287.c (working copy) @@ -10,5 +10,6 @@ int foo(int p) return (*gp + t); } -/* We will eliminate one load of gp and one indirect load of *gp. */ -/* { dg-final { scan-tree-dump-times "Eliminated: 2" 1 "pre"} } */ +/* We will eliminate one load of gp and one indirect load of *gp and + the add of zero. */ +/* { dg-final { scan-tree-dump-times "Eliminated: 3" 1 "pre"} } */ Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/predcom-1.c (working copy) @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-do run } */ -/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */ +/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */ void abort (void); @@ -45,6 +45,6 @@ int main(void) /* Verify that both loops were transformed and unrolled. */ /* { dg-final { scan-tree-dump-times "Unrolling 2 times." 2 "pcom"} } */ -/* Also check that we undid the transformation previously made by PRE. */ -/* { dg-final { scan-tree-dump-times "looparound ref" 1 "pcom"} } */ - +/* Also check that we undid the transformation previously made by PRE. + ??? PRE now does the predictive commoning in count_averages. */ +/* dg-final { scan-tree-dump-times "looparound ref" 1 "pcom" } */ Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/predcom-2.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do run } */ -/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */ +/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */ void abort (void); Index: gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/predcom-3.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details" } */ +/* { dg-options "-O2 -funroll-loops --param max-unroll-times=8 -fpredictive-commoning -fdump-tree-pcom-details -fno-tree-pre" } */ int a[1000], b[1000]; Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c (revision 239406) +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-10.c (working copy) @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-sink-details" } */ +/* { dg-options "-O2 -fdump-tree-sink-details -fno-tree-pre" } */ int x[1024], y[1024], z[1024], w[1024]; void foo (void) Index: gcc/testsuite/gcc.target/i386/pr45685.c =================================================================== --- gcc/testsuite/gcc.target/i386/pr45685.c (revision 239406) +++ gcc/testsuite/gcc.target/i386/pr45685.c (working copy) @@ -36,4 +36,4 @@ int summation_helper_2(int64_t* products return s; } -/* { dg-final { scan-assembler-times "cmov" 4 } } */ +/* { dg-final { scan-assembler-times "cmov" 6 } } */ Index: gcc/testsuite/gfortran.dg/pr34163.f90 =================================================================== --- gcc/testsuite/gfortran.dg/pr34163.f90 (revision 239406) +++ gcc/testsuite/gfortran.dg/pr34163.f90 (working copy) @@ -1,5 +1,5 @@ ! { dg-do compile } -! { dg-options "-O2 -fpredictive-commoning -fdump-tree-pcom-details" } +! { dg-options "-O2 -fno-tree-pre -fpredictive-commoning -fdump-tree-pcom-details" } subroutine trisolve2(x,i1,i2,nxyz) integer :: nxyz real,dimension(nxyz):: au1