The following fixes the SLP miscompile in PR68861 which happens because we didn't think of stmts appering multiple times in a SLP node when doing the operand swapping support.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2015-12-16 Richard Biener <rguent...@suse.de> PR tree-optimization/68861 * tree-vect-slp.c (vect_build_slp_tree): Properly handle duplicate stmts when applying swapping to stmts. Index: gcc/tree-vect-slp.c =================================================================== *** gcc/tree-vect-slp.c (revision 231675) --- gcc/tree-vect-slp.c (working copy) *************** vect_build_slp_tree (vec_info *vinfo, *** 1049,1059 **** if we end up building the operand from scalars as we'll continue to process swapped operand two. */ for (j = 0; j < group_size; ++j) ! if (!matches[j]) { gimple *stmt = SLP_TREE_SCALAR_STMTS (*node)[j]; ! swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt), ! gimple_assign_rhs2_ptr (stmt)); } /* If we have all children of child built up from scalars then --- 1049,1077 ---- if we end up building the operand from scalars as we'll continue to process swapped operand two. */ for (j = 0; j < group_size; ++j) ! { ! gimple *stmt = SLP_TREE_SCALAR_STMTS (*node)[j]; ! gimple_set_plf (stmt, GF_PLF_1, false); ! } ! for (j = 0; j < group_size; ++j) ! { ! gimple *stmt = SLP_TREE_SCALAR_STMTS (*node)[j]; ! if (!matches[j]) ! { ! /* Avoid swapping operands twice. */ ! if (gimple_plf (stmt, GF_PLF_1)) ! continue; ! swap_ssa_operands (stmt, gimple_assign_rhs1_ptr (stmt), ! gimple_assign_rhs2_ptr (stmt)); ! gimple_set_plf (stmt, GF_PLF_1, true); ! } ! } ! /* Verify we swap all duplicates or none. */ ! if (flag_checking) ! for (j = 0; j < group_size; ++j) { gimple *stmt = SLP_TREE_SCALAR_STMTS (*node)[j]; ! gcc_assert (gimple_plf (stmt, GF_PLF_1) == ! matches[j]); } /* If we have all children of child built up from scalars then