diff mbox series

Fix PR89653

Message ID alpine.LSU.2.20.1903111234450.4934@zhemvz.fhfr.qr
State New
Headers show
Series Fix PR89653 | expand

Commit Message

Richard Biener March 11, 2019, 11:39 a.m. UTC
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  <rguenther@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.

Comments

Richard Biener May 2, 2019, 2:08 p.m. UTC | #1
On Mon, Mar 11, 2019 at 12:39 PM Richard Biener <rguenther@suse.de> wrote:
>
>
> 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.

Applied as r270800.

Richard.

> Richard.
>
> 2019-03-11  Richard Biener  <rguenther@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" } }
diff mbox series

Patch

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" } }