The following fixes a missed vectorization of std::min() when
only one argument is a temporary.  The following patch is the least
intrusive and safest one - PRE already performs the necessary
work to make this vectorizable, it's just that we end up with
a dead store and clobber of a stack-local that the vectorizer is
not happy about.  The easiest fix is to schedule an update-address-taken
phase at the right spot which rewrites it into SSA and then DCE
can get rid of it.  DSE would also do the job but is more expensive.
Since PRE/VN have the chance to expose things that can be written
into SSA doing so before loop opts sounds like a good idea in any case.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

Queued for GCC 10 for which I also have a fix for phiprop which
usually deals with std::min/max if-conversion.  The one below
is quite safe but it's not a regression unfortunately.

Richard.

2019-03-11  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/89653
        * tree-ssa-loop.c (pass_data_tree_loop_init): Execute
        update-address-taken before the pass.
        * passes.def (pass_tree_loop_init): Put comment before it.

        * g++.dg/vect/pr89653.cc: New testcase.

Index: gcc/tree-ssa-loop.c
===================================================================
--- gcc/tree-ssa-loop.c (revision 269569)
+++ gcc/tree-ssa-loop.c (working copy)
@@ -330,7 +330,7 @@ const pass_data pass_data_tree_loop_init
   PROP_cfg, /* properties_required */
   0, /* properties_provided */
   0, /* properties_destroyed */
-  0, /* todo_flags_start */
+  TODO_update_address_taken, /* todo_flags_start */
   0, /* todo_flags_finish */
 };
 
Index: gcc/passes.def
===================================================================
--- gcc/passes.def      (revision 269569)
+++ gcc/passes.def      (working copy)
@@ -261,6 +261,8 @@ along with GCC; see the file COPYING3.
       NEXT_PASS (pass_fix_loops);
       NEXT_PASS (pass_tree_loop);
       PUSH_INSERT_PASSES_WITHIN (pass_tree_loop)
+          /* Before loop_init we rewrite no longer addressed locals into SSA
+            form if possible.  */
          NEXT_PASS (pass_tree_loop_init);
          NEXT_PASS (pass_tree_unswitch);
          NEXT_PASS (pass_scev_cprop);
Index: gcc/testsuite/g++.dg/vect/pr89653.cc
===================================================================
--- gcc/testsuite/g++.dg/vect/pr89653.cc        (nonexistent)
+++ gcc/testsuite/g++.dg/vect/pr89653.cc        (working copy)
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-require-effective-target vect_double }
+
+#include <algorithm>
+
+void loop1(double * const __restrict__ vec, double x, int end)
+{
+  for (int i = 0; i < end; ++i)
+    vec[i] = std::min(vec[i], vec[i]/x);
+}
+
+// { dg-final { scan-tree-dump "vectorized 1 loops" "vect" } }

Reply via email to