diff mbox series

middle-end slp: Split out patterns away from using SLP_ONLY into their own flag

Message ID patch-14113-tamar@arm.com
State New
Headers show
Series middle-end slp: Split out patterns away from using SLP_ONLY into their own flag | expand

Commit Message

Tamar Christina Feb. 2, 2021, 6:36 p.m. UTC
Hi All,

Previously the SLP pattern matcher was using STMT_VINFO_SLP_VECT_ONLY as a way
to dissolve the SLP only patterns during SLP cancellation.  However it seems
like the semantics for STMT_VINFO_SLP_VECT_ONLY are slightly different than what
I expected.

Namely that the non-SLP path can still use a statement marked
STMT_VINFO_SLP_VECT_ONLY.  One such example is masked loads which are used both
in the SLP and non-SLP path.

To fix this I now introduce a new flag STMT_VINFO_SLP_VECT_ONLY_PATTERN which is
used only by the pattern matcher.

Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
and no issues.

Ok for master?

Thanks,
Tamar

gcc/ChangeLog:

	PR tree-optimization/98928
	* tree-vect-loop.c (vect_analyze_loop_2): Change
	STMT_VINFO_SLP_VECT_ONLY to STMT_VINFO_SLP_VECT_ONLY_PATTERN.
	* tree-vect-slp-patterns.c (complex_pattern::build): Likewise.
	* tree-vectorizer.h (STMT_VINFO_SLP_VECT_ONLY_PATTERN): New.
	(class _stmt_vec_info): Add slp_vect_pattern_only_p.

gcc/testsuite/ChangeLog:

	PR tree-optimization/98928
	* gcc.target/i386/pr98928.c: New test.

--- inline copy of patch -- 
diff --git a/gcc/testsuite/gcc.target/i386/pr98928.c b/gcc/testsuite/gcc.target/i386/pr98928.c
new file mode 100644
index 0000000000000000000000000000000000000000..9503b579a88d95c427d3e3e5a71565b0c048c125


--

Comments

Richard Biener Feb. 3, 2021, 8:01 a.m. UTC | #1
On Tue, 2 Feb 2021, Tamar Christina wrote:

> Hi All,
> 
> Previously the SLP pattern matcher was using STMT_VINFO_SLP_VECT_ONLY as a way
> to dissolve the SLP only patterns during SLP cancellation.  However it seems
> like the semantics for STMT_VINFO_SLP_VECT_ONLY are slightly different than what
> I expected.
> 
> Namely that the non-SLP path can still use a statement marked
> STMT_VINFO_SLP_VECT_ONLY.  One such example is masked loads which are used both
> in the SLP and non-SLP path.
> 
> To fix this I now introduce a new flag STMT_VINFO_SLP_VECT_ONLY_PATTERN which is
> used only by the pattern matcher.
> 
> Bootstrapped Regtested on aarch64-none-linux-gnu, x86_64-pc-linux-gnu
> and no issues.
> 
> Ok for master?

OK.

Thanks,
Richard.

> Thanks,
> Tamar
> 
> gcc/ChangeLog:
> 
> 	PR tree-optimization/98928
> 	* tree-vect-loop.c (vect_analyze_loop_2): Change
> 	STMT_VINFO_SLP_VECT_ONLY to STMT_VINFO_SLP_VECT_ONLY_PATTERN.
> 	* tree-vect-slp-patterns.c (complex_pattern::build): Likewise.
> 	* tree-vectorizer.h (STMT_VINFO_SLP_VECT_ONLY_PATTERN): New.
> 	(class _stmt_vec_info): Add slp_vect_pattern_only_p.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR tree-optimization/98928
> 	* gcc.target/i386/pr98928.c: New test.
> 
> --- inline copy of patch -- 
> diff --git a/gcc/testsuite/gcc.target/i386/pr98928.c b/gcc/testsuite/gcc.target/i386/pr98928.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..9503b579a88d95c427d3e3e5a71565b0c048c125
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/i386/pr98928.c
> @@ -0,0 +1,59 @@
> +/* { dg-do compile } */
> +/* { dg-additional-options "-Ofast -march=skylake-avx512 -fwhole-program -w" } */
> +
> +typedef float MagickRealType;
> +typedef short Quantum;
> +float InterpolateMagickPixelPacket_alpha[1];
> +int InterpolateMagickPixelPacket_i;
> +
> +void InterpolateMagickPixelPacket();
> +
> +void main() { InterpolateMagickPixelPacket(); }
> +
> +typedef struct {
> +  MagickRealType red, green, blue, opacity, index;
> +} MagickPixelPacket;
> +typedef struct {
> +  Quantum blue, green, red, opacity;
> +} PixelPacket;
> +struct _Image {
> +  int colorspace;
> +  int matte;
> +} GetMagickPixelPacket(MagickPixelPacket *pixel) {
> +  pixel->red = pixel->green = pixel->blue = 0.0;
> +}
> +int AlphaBlendMagickPixelPacket(struct _Image *image, PixelPacket *color,
> +                            Quantum *indexes, MagickPixelPacket *pixel,
> +                            MagickRealType *alpha) {
> +  if (image->matte) {
> +    *alpha = pixel->red = pixel->green = pixel->blue = pixel->opacity =
> +        color->opacity;
> +    pixel->index = 0.0;
> +    if (image->colorspace)
> +      pixel->index = *indexes;
> +    return 0;
> +  }
> +  *alpha = 1.0 / 0.2;
> +  pixel->red = *alpha * color->red;
> +  pixel->green = *alpha * color->green;
> +  pixel->blue = *alpha * color->blue;
> +  pixel->opacity = pixel->index = 0.0;
> +  if (image->colorspace && indexes)
> +    pixel->index = *indexes;
> +}
> +MagickPixelPacket InterpolateMagickPixelPacket_pixels[1];
> +PixelPacket InterpolateMagickPixelPacket_p;
> +
> +void
> +InterpolateMagickPixelPacket(struct _Image *image) {
> +  Quantum *indexes;
> +  for (; InterpolateMagickPixelPacket_i; InterpolateMagickPixelPacket_i++) {
> +    GetMagickPixelPacket(InterpolateMagickPixelPacket_pixels +
> +                         InterpolateMagickPixelPacket_i);
> +    AlphaBlendMagickPixelPacket(
> +        image, &InterpolateMagickPixelPacket_p + InterpolateMagickPixelPacket_i,
> +        indexes + InterpolateMagickPixelPacket_i,
> +        InterpolateMagickPixelPacket_pixels + InterpolateMagickPixelPacket_i,
> +        InterpolateMagickPixelPacket_alpha + InterpolateMagickPixelPacket_i);
> +  }
> +}
> diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
> index acfd1952e3b803ea79cf51433101466743c9793e..200ed27b32ef4aa54c6783afa1864924b6f55582 100644
> --- a/gcc/tree-vect-loop.c
> +++ b/gcc/tree-vect-loop.c
> @@ -2700,7 +2700,7 @@ again:
>  	    {
>  	      stmt_vec_info pattern_stmt_info
>  		= STMT_VINFO_RELATED_STMT (stmt_info);
> -	      if (STMT_VINFO_SLP_VECT_ONLY (pattern_stmt_info))
> +	      if (STMT_VINFO_SLP_VECT_ONLY_PATTERN (pattern_stmt_info))
>  		STMT_VINFO_IN_PATTERN_P (stmt_info) = false;
>  
>  	      gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info);
> diff --git a/gcc/tree-vect-slp-patterns.c b/gcc/tree-vect-slp-patterns.c
> index d25560fab97bb852e949884850d51c6148b14a68..f0817da9f622d22e3df2e30410d1cf610b4ffa1d 100644
> --- a/gcc/tree-vect-slp-patterns.c
> +++ b/gcc/tree-vect-slp-patterns.c
> @@ -599,7 +599,7 @@ complex_pattern::build (vec_info *vinfo)
>  	 the call there.  */
>        vect_mark_pattern_stmts (vinfo, stmt_info, call_stmt,
>  			       SLP_TREE_VECTYPE (node));
> -      STMT_VINFO_SLP_VECT_ONLY (call_stmt_info) = true;
> +      STMT_VINFO_SLP_VECT_ONLY_PATTERN (call_stmt_info) = true;
>  
>        /* Since we are replacing all the statements in the group with the same
>  	 thing it doesn't really matter.  So just set it every time a new stmt
> diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
> index f8bf4488d0ea32e7909f6be2bf4e7cdaee4f55fe..e564fcf835a46a8c1aa6b5fb52f7ecd60bcb1bc9 100644
> --- a/gcc/tree-vectorizer.h
> +++ b/gcc/tree-vectorizer.h
> @@ -1215,6 +1215,10 @@ public:
>  
>    /* True if this is only suitable for SLP vectorization.  */
>    bool slp_vect_only_p;
> +
> +  /* True if this is a pattern that can only be handled by SLP
> +     vectorization.  */
> +  bool slp_vect_pattern_only_p;
>  };
>  
>  /* Information about a gather/scatter call.  */
> @@ -1301,6 +1305,7 @@ struct gather_scatter_info {
>  #define STMT_VINFO_REDUC_VECTYPE(S)     (S)->reduc_vectype
>  #define STMT_VINFO_REDUC_VECTYPE_IN(S)  (S)->reduc_vectype_in
>  #define STMT_VINFO_SLP_VECT_ONLY(S)     (S)->slp_vect_only_p
> +#define STMT_VINFO_SLP_VECT_ONLY_PATTERN(S) (S)->slp_vect_pattern_only_p
>  
>  #define DR_GROUP_FIRST_ELEMENT(S) \
>    (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element)
> 
> 
>
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.target/i386/pr98928.c b/gcc/testsuite/gcc.target/i386/pr98928.c
new file mode 100644
index 0000000000000000000000000000000000000000..9503b579a88d95c427d3e3e5a71565b0c048c125
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr98928.c
@@ -0,0 +1,59 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-Ofast -march=skylake-avx512 -fwhole-program -w" } */
+
+typedef float MagickRealType;
+typedef short Quantum;
+float InterpolateMagickPixelPacket_alpha[1];
+int InterpolateMagickPixelPacket_i;
+
+void InterpolateMagickPixelPacket();
+
+void main() { InterpolateMagickPixelPacket(); }
+
+typedef struct {
+  MagickRealType red, green, blue, opacity, index;
+} MagickPixelPacket;
+typedef struct {
+  Quantum blue, green, red, opacity;
+} PixelPacket;
+struct _Image {
+  int colorspace;
+  int matte;
+} GetMagickPixelPacket(MagickPixelPacket *pixel) {
+  pixel->red = pixel->green = pixel->blue = 0.0;
+}
+int AlphaBlendMagickPixelPacket(struct _Image *image, PixelPacket *color,
+                            Quantum *indexes, MagickPixelPacket *pixel,
+                            MagickRealType *alpha) {
+  if (image->matte) {
+    *alpha = pixel->red = pixel->green = pixel->blue = pixel->opacity =
+        color->opacity;
+    pixel->index = 0.0;
+    if (image->colorspace)
+      pixel->index = *indexes;
+    return 0;
+  }
+  *alpha = 1.0 / 0.2;
+  pixel->red = *alpha * color->red;
+  pixel->green = *alpha * color->green;
+  pixel->blue = *alpha * color->blue;
+  pixel->opacity = pixel->index = 0.0;
+  if (image->colorspace && indexes)
+    pixel->index = *indexes;
+}
+MagickPixelPacket InterpolateMagickPixelPacket_pixels[1];
+PixelPacket InterpolateMagickPixelPacket_p;
+
+void
+InterpolateMagickPixelPacket(struct _Image *image) {
+  Quantum *indexes;
+  for (; InterpolateMagickPixelPacket_i; InterpolateMagickPixelPacket_i++) {
+    GetMagickPixelPacket(InterpolateMagickPixelPacket_pixels +
+                         InterpolateMagickPixelPacket_i);
+    AlphaBlendMagickPixelPacket(
+        image, &InterpolateMagickPixelPacket_p + InterpolateMagickPixelPacket_i,
+        indexes + InterpolateMagickPixelPacket_i,
+        InterpolateMagickPixelPacket_pixels + InterpolateMagickPixelPacket_i,
+        InterpolateMagickPixelPacket_alpha + InterpolateMagickPixelPacket_i);
+  }
+}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index acfd1952e3b803ea79cf51433101466743c9793e..200ed27b32ef4aa54c6783afa1864924b6f55582 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2700,7 +2700,7 @@  again:
 	    {
 	      stmt_vec_info pattern_stmt_info
 		= STMT_VINFO_RELATED_STMT (stmt_info);
-	      if (STMT_VINFO_SLP_VECT_ONLY (pattern_stmt_info))
+	      if (STMT_VINFO_SLP_VECT_ONLY_PATTERN (pattern_stmt_info))
 		STMT_VINFO_IN_PATTERN_P (stmt_info) = false;
 
 	      gimple *pattern_def_seq = STMT_VINFO_PATTERN_DEF_SEQ (stmt_info);
diff --git a/gcc/tree-vect-slp-patterns.c b/gcc/tree-vect-slp-patterns.c
index d25560fab97bb852e949884850d51c6148b14a68..f0817da9f622d22e3df2e30410d1cf610b4ffa1d 100644
--- a/gcc/tree-vect-slp-patterns.c
+++ b/gcc/tree-vect-slp-patterns.c
@@ -599,7 +599,7 @@  complex_pattern::build (vec_info *vinfo)
 	 the call there.  */
       vect_mark_pattern_stmts (vinfo, stmt_info, call_stmt,
 			       SLP_TREE_VECTYPE (node));
-      STMT_VINFO_SLP_VECT_ONLY (call_stmt_info) = true;
+      STMT_VINFO_SLP_VECT_ONLY_PATTERN (call_stmt_info) = true;
 
       /* Since we are replacing all the statements in the group with the same
 	 thing it doesn't really matter.  So just set it every time a new stmt
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index f8bf4488d0ea32e7909f6be2bf4e7cdaee4f55fe..e564fcf835a46a8c1aa6b5fb52f7ecd60bcb1bc9 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -1215,6 +1215,10 @@  public:
 
   /* True if this is only suitable for SLP vectorization.  */
   bool slp_vect_only_p;
+
+  /* True if this is a pattern that can only be handled by SLP
+     vectorization.  */
+  bool slp_vect_pattern_only_p;
 };
 
 /* Information about a gather/scatter call.  */
@@ -1301,6 +1305,7 @@  struct gather_scatter_info {
 #define STMT_VINFO_REDUC_VECTYPE(S)     (S)->reduc_vectype
 #define STMT_VINFO_REDUC_VECTYPE_IN(S)  (S)->reduc_vectype_in
 #define STMT_VINFO_SLP_VECT_ONLY(S)     (S)->slp_vect_only_p
+#define STMT_VINFO_SLP_VECT_ONLY_PATTERN(S) (S)->slp_vect_pattern_only_p
 
 #define DR_GROUP_FIRST_ELEMENT(S) \
   (gcc_checking_assert ((S)->dr_aux.dr), (S)->first_element)