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

Reply via email to