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. 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. 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" } } */