re PR rtl-optimization/84101 (-O3 and -ftree-vectorize trying too hard for function...
authorRichard Biener <rguenther@suse.de>
Wed, 3 Apr 2019 12:30:16 +0000 (12:30 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Wed, 3 Apr 2019 12:30:16 +0000 (12:30 +0000)
2019-04-03  Richard Biener  <rguenther@suse.de>

PR tree-optimization/84101
* tree-vect-stmts.c: Include explow.h for hard_function_value,
regs.h for hard_regno_nregs.
(cfun_returns): New helper.
(vect_model_store_cost): When vectorizing a store to a decl
we return and the function ABI returns in a multi-reg location
account for the possible spilling that will happen.

* gcc.target/i386/pr84101.c: New testcase.

From-SVN: r270123

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr84101.c [new file with mode: 0644]
gcc/tree-vect-stmts.c

index a280b6c2cc6f29fd324d7b93797c980c8fbd5faf..9149d9c9a9eeeabb604979ba8dd64f9e4118fcb1 100644 (file)
@@ -1,3 +1,13 @@
+2019-04-03  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/84101
+       * tree-vect-stmts.c: Include explow.h for hard_function_value,
+       regs.h for hard_regno_nregs.
+       (cfun_returns): New helper.
+       (vect_model_store_cost): When vectorizing a store to a decl
+       we return and the function ABI returns in a multi-reg location
+       account for the possible spilling that will happen.
+
 2019-04-03  Andreas Krebbel  <krebbel@linux.ibm.com>
 
        * config/s390/s390.c (s390_legitimate_address_p): Reject long
index 0344e24ba1b6a163ff5961cba863def31ff3f97e..94729eed46caebf3530b88b3c85a2797034611b8 100644 (file)
@@ -1,3 +1,8 @@
+2019-04-03  Richard Biener  <rguenther@suse.de>
+
+       PR tree-optimization/84101
+       * gcc.target/i386/pr84101.c: New testcase.
+
 2019-04-02  Jeff Law  <law@redhat.com>
 
        * gcc.target/visium/bit_shift.c: xfail.
diff --git a/gcc/testsuite/gcc.target/i386/pr84101.c b/gcc/testsuite/gcc.target/i386/pr84101.c
new file mode 100644 (file)
index 0000000..006e6a4
--- /dev/null
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-slp2-details" } */
+
+typedef struct uint64_pair uint64_pair_t ;
+struct uint64_pair
+{
+  unsigned long w0 ;
+  unsigned long w1 ;
+} ;
+
+uint64_pair_t pair(int num)
+{
+  uint64_pair_t p ;
+
+  p.w0 = num << 1 ;
+  p.w1 = num >> 1 ;
+
+  return p ;
+}
+
+/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp2" } } */
index 6c631db90399264945bb4d2cabb269976becc45e..2388c93af34dc85fef4424289279682d2af0141d 100644 (file)
@@ -43,6 +43,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-cfg.h"
 #include "tree-ssa-loop-manip.h"
 #include "cfgloop.h"
+#include "explow.h"
 #include "tree-ssa-loop.h"
 #include "tree-scalar-evolution.h"
 #include "tree-vectorizer.h"
@@ -52,6 +53,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "vec-perm-indices.h"
 #include "tree-ssa-loop-niter.h"
 #include "gimple-fold.h"
+#include "regs.h"
 
 /* For lang_hooks.types.type_for_mode.  */
 #include "langhooks.h"
@@ -948,6 +950,37 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
                      "prologue_cost = %d .\n", inside_cost, prologue_cost);
 }
 
+/* Returns true if the current function returns DECL.  */
+
+static bool
+cfun_returns (tree decl)
+{
+  edge_iterator ei;
+  edge e;
+  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+    {
+      greturn *ret = safe_dyn_cast <greturn *> (last_stmt (e->src));
+      if (!ret)
+       continue;
+      if (gimple_return_retval (ret) == decl)
+       return true;
+      /* We often end up with an aggregate copy to the result decl,
+         handle that case as well.  First skip intermediate clobbers
+        though.  */
+      gimple *def = ret;
+      do
+       {
+         def = SSA_NAME_DEF_STMT (gimple_vuse (def));
+       }
+      while (gimple_clobber_p (def));
+      if (is_a <gassign *> (def)
+         && gimple_assign_lhs (def) == gimple_return_retval (ret)
+         && gimple_assign_rhs1 (def) == decl)
+       return true;
+    }
+  return false;
+}
+
 /* Function vect_model_store_cost
 
    Models cost for stores.  In the case of grouped accesses, one access
@@ -1032,6 +1065,37 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
                                       vec_to_scalar, stmt_info, 0, vect_body);
     }
 
+  /* When vectorizing a store into the function result assign
+     a penalty if the function returns in a multi-register location.
+     In this case we assume we'll end up with having to spill the
+     vector result and do piecewise loads as a conservative estimate.  */
+  tree base = get_base_address (STMT_VINFO_DATA_REF (stmt_info)->ref);
+  if (base
+      && (TREE_CODE (base) == RESULT_DECL
+         || (DECL_P (base) && cfun_returns (base)))
+      && !aggregate_value_p (base, cfun->decl))
+    {
+      rtx reg = hard_function_value (TREE_TYPE (base), cfun->decl, 0, 1);
+      /* ???  Handle PARALLEL in some way.  */
+      if (REG_P (reg))
+       {
+         int nregs = hard_regno_nregs (REGNO (reg), GET_MODE (reg));
+         /* Assume that a single reg-reg move is possible and cheap,
+            do not account for vector to gp register move cost.  */
+         if (nregs > 1)
+           {
+             /* Spill.  */
+             prologue_cost += record_stmt_cost (cost_vec, ncopies,
+                                                vector_store,
+                                                stmt_info, 0, vect_epilogue);
+             /* Loads.  */
+             prologue_cost += record_stmt_cost (cost_vec, ncopies * nregs,
+                                                scalar_load,
+                                                stmt_info, 0, vect_epilogue);
+           }
+       }
+    }
+
   if (dump_enabled_p ())
     dump_printf_loc (MSG_NOTE, vect_location,
                      "vect_model_store_cost: inside_cost = %d, "