------- Additional Comments From steven at gcc dot gnu dot org 2005-09-18 15:59 ------- Actually fold_stmt has nothing to do with it. It is fold (cached_lhs) in trhead_across_edge that is the problem here. Jeff, what do you think about this patch? Index: tree-ssa-dom.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-ssa-dom.c,v retrieving revision 2.127 diff -u -3 -p -r2.127 tree-ssa-dom.c --- tree-ssa-dom.c 2 Aug 2005 00:12:39 -0000 2.127 +++ tree-ssa-dom.c 18 Sep 2005 15:57:22 -0000 @@ -701,7 +701,7 @@ thread_across_edge (struct dom_walk_data else { /* Copy the operands. */ - tree *copy; + tree *copy, prefold_lhs; ssa_op_iter iter; use_operand_p use_p; unsigned int num, i = 0; @@ -725,12 +725,33 @@ thread_across_edge (struct dom_walk_data /* Try to fold/lookup the new expression. Inserting the expression into the hash table is unlikely to help - simplify anything later, so just query the hashtable. */ - cached_lhs = fold (TREE_OPERAND (stmt, 1)); - if (TREE_CODE (cached_lhs) != SSA_NAME - && !is_gimple_min_invariant (cached_lhs)) - cached_lhs = lookup_avail_expr (stmt, false); + simplify anything later, so just query the hashtable. + Sadly, we have to handle conditional assignments specially + here, because fold expects all the operands of an expression + to be folded before the expression itself is folded, but we + can't just substitute the folded condition here. */ + if (TREE_CODE (TREE_OPERAND (stmt, 1)) == COND_EXPR) + { + tree cond = COND_EXPR_COND (TREE_OPERAND (stmt, 1)); + cond = fold (cond); + if (cond == boolean_true_node) + prefold_lhs = COND_EXPR_THEN (TREE_OPERAND (stmt, 1)); + else if (cond == boolean_false_node) + prefold_lhs = COND_EXPR_ELSE (TREE_OPERAND (stmt, 1)); + else + prefold_lhs = NULL; + } + else + prefold_lhs = TREE_OPERAND (stmt, 1); + + if (prefold_lhs) + { + cached_lhs = fold (prefold_lhs); + if (TREE_CODE (cached_lhs) != SSA_NAME + && !is_gimple_min_invariant (cached_lhs)) + cached_lhs = lookup_avail_expr (stmt, false); + } /* Restore the statement's original uses/defs. */ i = 0;
-- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23049