The following works around the issue that PRE inserts expressions into the VN hashes without having a representative for them. First the patch avoids inserting fully constant expressions and second it deals with the above by assigning a representative once VN insertion needs one.
The way PRE uses the VN hashes here probably needs some (big) overhaul but the following should get us past the failure point in a reasonable way as well. Bootstrap and regtest running on x86_64-unknown-linux-gnu. Richard. 2016-05-11 Richard Biener <rguent...@suse.de> PR tree-optimization/71059 * tree-ssa-pre.c (phi_translate_1): Fully fold translated nary before looking up or entering the expression into the VN hashes. * tree-ssa-sccvn.c (vn_nary_build_or_lookup): Fix comment typo. Make sure to re-use NARYs without result as inserted by phi-translation. * gcc.dg/torture/pr71059.c: New testcase. Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 236069) --- gcc/tree-ssa-pre.c (working copy) *************** phi_translate_1 (pre_expr expr, bitmap_s *** 1464,1469 **** --- 1464,1475 ---- pre_expr constant; unsigned int new_val_id; + PRE_EXPR_NARY (expr) = newnary; + 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, newnary->type, *************** phi_translate_1 (pre_expr expr, bitmap_s *** 1478,1487 **** if (nary) { PRE_EXPR_NARY (expr) = nary; - constant = fully_constant_expression (expr); - if (constant != expr) - return constant; - new_val_id = nary->value_id; get_or_alloc_expression_id (expr); } --- 1484,1489 ---- *************** phi_translate_1 (pre_expr expr, bitmap_s *** 1495,1503 **** &newnary->op[0], result, new_val_id); PRE_EXPR_NARY (expr) = nary; - constant = fully_constant_expression (expr); - if (constant != expr) - return constant; get_or_alloc_expression_id (expr); } add_to_value (new_val_id, expr); --- 1497,1502 ---- Index: gcc/testsuite/gcc.dg/torture/pr71059.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr71059.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr71059.c (working copy) *************** *** 0 **** --- 1,15 ---- + /* { dg-do compile } */ + + short a, c; + union { + unsigned f0; + unsigned short f1; + } b; + volatile int d; + short fn1(short p1) { return p1 + a; } + void fn2() + { + b.f0 = 0; + for (;; b.f0 = fn1(b.f0)) + (c && b.f1) || d; + } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 236159) --- gcc/tree-ssa-sccvn.c (working copy) *************** vn_nary_build_or_lookup (code_helper rco *** 1632,1638 **** { tree result = NULL_TREE; /* We will be creating a value number for ! ROCDE (OPS...). So first simplify and lookup this expression to see if it is already available. */ mprts_hook = vn_lookup_simplify_result; --- 1632,1638 ---- { tree result = NULL_TREE; /* We will be creating a value number for ! RCODE (OPS...). So first simplify and lookup this expression to see if it is already available. */ mprts_hook = vn_lookup_simplify_result; *************** vn_nary_build_or_lookup (code_helper rco *** 1682,1687 **** --- 1682,1697 ---- gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr, new_stmt); VN_INFO (result)->needs_insertion = true; + /* ??? PRE phi-translation inserts NARYs without corresponding + SSA name result. Re-use those but set their result according + to the stmt we just built. */ + vn_nary_op_t nary = NULL; + vn_nary_op_lookup_stmt (new_stmt, &nary); + if (nary) + { + gcc_assert (nary->result == NULL_TREE); + nary->result = gimple_assign_lhs (new_stmt); + } /* As all "inserted" statements are singleton SCCs, insert to the valid table. This is strictly needed to avoid re-generating new value SSA_NAMEs for the same *************** vn_nary_build_or_lookup (code_helper rco *** 1689,1695 **** optimistic table gets cleared after each iteration). We do not need to insert into the optimistic table, as lookups there will fall back to the valid table. */ ! if (current_info == optimistic_info) { current_info = valid_info; vn_nary_op_insert_stmt (new_stmt, result); --- 1699,1705 ---- optimistic table gets cleared after each iteration). We do not need to insert into the optimistic table, as lookups there will fall back to the valid table. */ ! else if (current_info == optimistic_info) { current_info = valid_info; vn_nary_op_insert_stmt (new_stmt, result);