http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52198
Bug #: 52198 Summary: SLP vectorization does not consider swapped operands consistently Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Keywords: missed-optimization Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: rgue...@gcc.gnu.org While vect_get_and_check_slp_defs swaps operands of binary operations in some cases it does not do so when vect_build_slp_tree would reject the tree because the operands have different operations in def stmts, for example with D.1751_23 = s_3(D) * D.1737_13; D.1753_25 = s_3(D) * D.1734_16; D.1755_27 = s_3(D) * D.1731_19; D.1757_29 = s_3(D) * D.1728_22; D.1777_7 = MEM[(const struct LorentzVector &)res_4(D)].theT; D.1775_31 = D.1777_7 + D.1751_23; D.1774_32 = MEM[(const struct LorentzVector &)res_4(D)].theZ; D.1772_34 = D.1753_25 + D.1774_32; D.1771_35 = MEM[(const struct LorentzVector &)res_4(D)].theY; D.1769_37 = D.1755_27 + D.1771_35; D.1768_38 = MEM[(const struct LorentzVector &)res_4(D)].theX; D.1766_40 = D.1757_29 + D.1768_38; res_4(D)->theX = D.1766_40; res_4(D)->theY = D.1769_37; res_4(D)->theZ = D.1772_34; res_4(D)->theT = D.1775_31; where you can see that the first addition stmt has its operands swapped (because of SSA name numbering contributing to canonicalization here). This issue triggers in g++.dg/vect/slp-pr50819.cc if you install a patch to properly release virtual operands of the call stmt during inlining which frees up that SSA name for re-use: Index: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c (revision 184088) +++ gcc/tree-inline.c (working copy) @@ -4002,6 +4002,9 @@ expand_call_inline (basic_block bb, gimp /* Unlink the calls virtual operands before replacing it. */ unlink_stmt_vdef (stmt); + if (gimple_vdef (stmt) + && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME) + release_ssa_name (gimple_vdef (stmt)); /* If the inlined function returns a result that we care about, substitute the GIMPLE_CALL with an assignment of the return