[1/5] Improve tree-vect-patterns.c handling of boolean comparisons

Message ID mpto8wvyosi.fsf@arm.com
State New
Headers show
Series
  • Don't defer vector type choice for bools (PR 92596)
Related show

Commit Message

Richard Sandiford Nov. 29, 2019, 10:12 a.m.
vect_recog_bool_pattern assumed that a comparison between two booleans
should always become a comparison of vector mask types (implemented as an
XOR_EXPR).  But if the booleans in question are generated as data values
(e.g. because they're loaded directly from memory), we should treat them
like ordinary integers instead, just as we do for boolean logic ops whose
operands are loaded from memory.  vect_get_mask_type_for_stmt already
handled this case:

      /* We may compare boolean value loaded as vector of integers.
	 Fix mask_type in such case.  */
      if (mask_type
	  && !VECTOR_BOOLEAN_TYPE_P (mask_type)
	  && gimple_code (stmt) == GIMPLE_ASSIGN
	  && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
	mask_type = truth_type_for (mask_type);

and not handling it here complicated later patches.

The initial list of targets for vect_bool_cmp is deliberately conservative.


2019-11-30  Richard Sandiford  <richard.sandiford@arm.com>

gcc/
	* doc/sourcebuild.texi (vect_bool_cmp): Document.
	* tree-vect-patterns.c (search_type_for_mask_1): If neither
	operand to a boolean comparison is a natural vector mask,
	handle both operands like normal integers instead.

gcc/testsuite/
	* gcc.dg/vect/vect-bool-cmp-2.c: New test.
	* lib/target-supports.exp (check_effective_target_vect_bool_cmp): New
	effective target procedure.

Comments

Richard Biener Nov. 29, 2019, 10:34 a.m. | #1
On Fri, Nov 29, 2019 at 11:12 AM Richard Sandiford
<richard.sandiford@arm.com> wrote:
>

> vect_recog_bool_pattern assumed that a comparison between two booleans

> should always become a comparison of vector mask types (implemented as an

> XOR_EXPR).  But if the booleans in question are generated as data values

> (e.g. because they're loaded directly from memory), we should treat them

> like ordinary integers instead, just as we do for boolean logic ops whose

> operands are loaded from memory.  vect_get_mask_type_for_stmt already

> handled this case:

>

>       /* We may compare boolean value loaded as vector of integers.

>          Fix mask_type in such case.  */

>       if (mask_type

>           && !VECTOR_BOOLEAN_TYPE_P (mask_type)

>           && gimple_code (stmt) == GIMPLE_ASSIGN

>           && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)

>         mask_type = truth_type_for (mask_type);

>

> and not handling it here complicated later patches.

>

> The initial list of targets for vect_bool_cmp is deliberately conservative.


OK.

Richard.

>

> 2019-11-30  Richard Sandiford  <richard.sandiford@arm.com>

>

> gcc/

>         * doc/sourcebuild.texi (vect_bool_cmp): Document.

>         * tree-vect-patterns.c (search_type_for_mask_1): If neither

>         operand to a boolean comparison is a natural vector mask,

>         handle both operands like normal integers instead.

>

> gcc/testsuite/

>         * gcc.dg/vect/vect-bool-cmp-2.c: New test.

>         * lib/target-supports.exp (check_effective_target_vect_bool_cmp): New

>         effective target procedure.

>

> Index: gcc/doc/sourcebuild.texi

> ===================================================================

> --- gcc/doc/sourcebuild.texi    2019-11-20 21:11:59.065472803 +0000

> +++ gcc/doc/sourcebuild.texi    2019-11-29 09:11:21.365130870 +0000

> @@ -1522,6 +1522,10 @@ Target does not support a vector add ins

>  @item vect_no_bitwise

>  Target does not support vector bitwise instructions.

>

> +@item vect_bool_cmp

> +Target supports comparison of @code{bool} vectors for at least one

> +vector length.

> +

>  @item vect_char_add

>  Target supports addition of @code{char} vectors for at least one

>  vector length.

> Index: gcc/tree-vect-patterns.c

> ===================================================================

> --- gcc/tree-vect-patterns.c    2019-11-16 10:29:21.207212217 +0000

> +++ gcc/tree-vect-patterns.c    2019-11-29 09:11:21.389130702 +0000

> @@ -3944,7 +3944,8 @@ search_type_for_mask_1 (tree var, vec_in

>                                              vinfo, cache);

>               if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))

>                 res = res2;

> -             break;

> +             if (res)

> +               break;

>             }

>

>           comp_vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (rhs1));

> Index: gcc/testsuite/gcc.dg/vect/vect-bool-cmp-2.c

> ===================================================================

> --- /dev/null   2019-09-17 11:41:18.176664108 +0100

> +++ gcc/testsuite/gcc.dg/vect/vect-bool-cmp-2.c 2019-11-29 09:11:21.373130815 +0000

> @@ -0,0 +1,10 @@

> +/* { dg-do compile } */

> +

> +void

> +f (_Bool *restrict x, _Bool *restrict y)

> +{

> +  for (int i = 0; i < 128; ++i)

> +    x[i] = x[i] == y[i];

> +}

> +

> +/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target vect_bool_cmp } } } */

> Index: gcc/testsuite/lib/target-supports.exp

> ===================================================================

> --- gcc/testsuite/lib/target-supports.exp       2019-11-26 22:11:24.494545152 +0000

> +++ gcc/testsuite/lib/target-supports.exp       2019-11-29 09:11:21.373130815 +0000

> @@ -5749,6 +5749,16 @@ proc check_effective_target_vect_bswap {

>              || [istarget amdgcn-*-*] }}]

>  }

>

> +# Return 1 if the target supports comparison of bool vectors for at

> +# least one vector length.

> +

> +proc check_effective_target_vect_bool_cmp { } {

> +    return [check_cached_effective_target_indexed vect_bool_cmp {

> +      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]

> +            || [istarget aarch64*-*-*]

> +            || [is-effective-target arm_neon] }}]

> +}

> +

>  # Return 1 if the target supports addition of char vectors for at least

>  # one vector length.

>

Patch

Index: gcc/doc/sourcebuild.texi
===================================================================
--- gcc/doc/sourcebuild.texi	2019-11-20 21:11:59.065472803 +0000
+++ gcc/doc/sourcebuild.texi	2019-11-29 09:11:21.365130870 +0000
@@ -1522,6 +1522,10 @@  Target does not support a vector add ins
 @item vect_no_bitwise
 Target does not support vector bitwise instructions.
 
+@item vect_bool_cmp
+Target supports comparison of @code{bool} vectors for at least one
+vector length.
+
 @item vect_char_add
 Target supports addition of @code{char} vectors for at least one
 vector length.
Index: gcc/tree-vect-patterns.c
===================================================================
--- gcc/tree-vect-patterns.c	2019-11-16 10:29:21.207212217 +0000
+++ gcc/tree-vect-patterns.c	2019-11-29 09:11:21.389130702 +0000
@@ -3944,7 +3944,8 @@  search_type_for_mask_1 (tree var, vec_in
 					     vinfo, cache);
 	      if (!res || (res2 && TYPE_PRECISION (res) > TYPE_PRECISION (res2)))
 		res = res2;
-	      break;
+	      if (res)
+		break;
 	    }
 
 	  comp_vectype = get_vectype_for_scalar_type (vinfo, TREE_TYPE (rhs1));
Index: gcc/testsuite/gcc.dg/vect/vect-bool-cmp-2.c
===================================================================
--- /dev/null	2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/gcc.dg/vect/vect-bool-cmp-2.c	2019-11-29 09:11:21.373130815 +0000
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+
+void
+f (_Bool *restrict x, _Bool *restrict y)
+{
+  for (int i = 0; i < 128; ++i)
+    x[i] = x[i] == y[i];
+}
+
+/* { dg-final { scan-tree-dump "loop vectorized" "vect" { target vect_bool_cmp } } } */
Index: gcc/testsuite/lib/target-supports.exp
===================================================================
--- gcc/testsuite/lib/target-supports.exp	2019-11-26 22:11:24.494545152 +0000
+++ gcc/testsuite/lib/target-supports.exp	2019-11-29 09:11:21.373130815 +0000
@@ -5749,6 +5749,16 @@  proc check_effective_target_vect_bswap {
 	     || [istarget amdgcn-*-*] }}]
 }
 
+# Return 1 if the target supports comparison of bool vectors for at
+# least one vector length.
+
+proc check_effective_target_vect_bool_cmp { } {
+    return [check_cached_effective_target_indexed vect_bool_cmp {
+      expr { [istarget i?86-*-*] || [istarget x86_64-*-*]
+	     || [istarget aarch64*-*-*]
+	     || [is-effective-target arm_neon] }}]
+}
+
 # Return 1 if the target supports addition of char vectors for at least
 # one vector length.