Re: [14/n] Vectorise conversions between differently-sized integer vectors

2019-11-12 Thread Richard Biener
On Wed, Nov 6, 2019 at 1:45 PM Richard Sandiford
 wrote:
>
> Richard Biener  writes:
> > On Fri, Oct 25, 2019 at 2:51 PM Richard Sandiford
> >  wrote:
> >>
> >> This patch adds AArch64 patterns for converting between 64-bit and
> >> 128-bit integer vectors, and makes the vectoriser and expand pass
> >> use them.
> >
> > So on GIMPLE we'll see
> >
> > v4si _1;
> > v4di _2;
> >
> >  _1 = (v4si) _2;
> >
> > then, correct?  Likewise for float conversions.
> >
> > I think that's "new", can you add to tree-cfg.c:verify_gimple_assign_unary
> > verification that the number of lanes of the LHS and the RHS match please?
>
> Ah, yeah.  How's this?  Tested as before.

OK.

Thanks,
Richard.

> Richard
>
>
> 2019-11-06  Richard Sandiford  
>
> gcc/
> * tree-cfg.c (verify_gimple_assign_unary): Handle conversions
> between vector types.
> * tree-vect-stmts.c (vectorizable_conversion): Extend the
> non-widening and non-narrowing path to handle standard
> conversion codes, if the target supports them.
> * expr.c (convert_move): Try using the extend and truncate optabs
> for vectors.
> * optabs-tree.c (supportable_convert_operation): Likewise.
> * config/aarch64/iterators.md (Vnarroqw): New iterator.
> * config/aarch64/aarch64-simd.md (2)
> (trunc2): New patterns.
>
> gcc/testsuite/
> * gcc.dg/vect/bb-slp-pr69907.c: Do not expect BB vectorization
> to fail for aarch64 targets.
> * gcc.dg/vect/no-scevccp-outer-12.c: Expect the test to pass
> on aarch64 targets.
> * gcc.dg/vect/vect-double-reduc-5.c: Likewise.
> * gcc.dg/vect/vect-outer-4e.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_5.c: New test.
> * gcc.target/aarch64/vect_mixed_sizes_6.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_7.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_8.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_9.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_10.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_11.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_12.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_13.c: Likewise.
>
> Index: gcc/tree-cfg.c
> ===
> --- gcc/tree-cfg.c  2019-09-05 08:49:30.829739618 +0100
> +++ gcc/tree-cfg.c  2019-11-06 12:44:22.832365429 +
> @@ -3553,6 +3553,24 @@ verify_gimple_assign_unary (gassign *stm
>  {
>  CASE_CONVERT:
>{
> +   /* Allow conversions between vectors with the same number of elements,
> +  provided that the conversion is OK for the element types too.  */
> +   if (VECTOR_TYPE_P (lhs_type)
> +   && VECTOR_TYPE_P (rhs1_type)
> +   && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
> +TYPE_VECTOR_SUBPARTS (rhs1_type)))
> + {
> +   lhs_type = TREE_TYPE (lhs_type);
> +   rhs1_type = TREE_TYPE (rhs1_type);
> + }
> +   else if (VECTOR_TYPE_P (lhs_type) || VECTOR_TYPE_P (rhs1_type))
> + {
> +   error ("invalid vector types in nop conversion");
> +   debug_generic_expr (lhs_type);
> +   debug_generic_expr (rhs1_type);
> +   return true;
> + }
> +
> /* Allow conversions from pointer type to integral type only if
>there is no sign or zero extension involved.
>For targets were the precision of ptrofftype doesn't match that
> Index: gcc/tree-vect-stmts.c
> ===
> --- gcc/tree-vect-stmts.c   2019-11-06 12:44:10.896448608 +
> +++ gcc/tree-vect-stmts.c   2019-11-06 12:44:22.832365429 +
> @@ -4869,7 +4869,9 @@ vectorizable_conversion (stmt_vec_info s
>switch (modifier)
>  {
>  case NONE:
> -  if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
> +  if (code != FIX_TRUNC_EXPR
> + && code != FLOAT_EXPR
> + && !CONVERT_EXPR_CODE_P (code))
> return false;
>if (supportable_convert_operation (code, vectype_out, vectype_in,
>  , ))
> Index: gcc/expr.c
> ===
> --- gcc/expr.c  2019-11-06 12:29:17.394677341 +
> +++ gcc/expr.c  2019-11-06 12:44:22.828365457 +
> @@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsi
>
>if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
>  {
> +  if (GET_MODE_UNIT_PRECISION (to_mode)
> + > GET_MODE_UNIT_PRECISION (from_mode))
> +   {
> + optab op = unsignedp ? zext_optab : sext_optab;
> + insn_code icode = convert_optab_handler (op, to_mode, from_mode);
> + if (icode != CODE_FOR_nothing)
> +   {
> + emit_unop_insn (icode, to, from,
> + unsignedp ? 

Re: [14/n] Vectorise conversions between differently-sized integer vectors

2019-11-06 Thread Richard Sandiford
Richard Biener  writes:
> On Fri, Oct 25, 2019 at 2:51 PM Richard Sandiford
>  wrote:
>>
>> This patch adds AArch64 patterns for converting between 64-bit and
>> 128-bit integer vectors, and makes the vectoriser and expand pass
>> use them.
>
> So on GIMPLE we'll see
>
> v4si _1;
> v4di _2;
>
>  _1 = (v4si) _2;
>
> then, correct?  Likewise for float conversions.
>
> I think that's "new", can you add to tree-cfg.c:verify_gimple_assign_unary
> verification that the number of lanes of the LHS and the RHS match please?

Ah, yeah.  How's this?  Tested as before.

Richard


2019-11-06  Richard Sandiford  

gcc/
* tree-cfg.c (verify_gimple_assign_unary): Handle conversions
between vector types.
* tree-vect-stmts.c (vectorizable_conversion): Extend the
non-widening and non-narrowing path to handle standard
conversion codes, if the target supports them.
* expr.c (convert_move): Try using the extend and truncate optabs
for vectors.
* optabs-tree.c (supportable_convert_operation): Likewise.
* config/aarch64/iterators.md (Vnarroqw): New iterator.
* config/aarch64/aarch64-simd.md (2)
(trunc2): New patterns.

gcc/testsuite/
* gcc.dg/vect/bb-slp-pr69907.c: Do not expect BB vectorization
to fail for aarch64 targets.
* gcc.dg/vect/no-scevccp-outer-12.c: Expect the test to pass
on aarch64 targets.
* gcc.dg/vect/vect-double-reduc-5.c: Likewise.
* gcc.dg/vect/vect-outer-4e.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_5.c: New test.
* gcc.target/aarch64/vect_mixed_sizes_6.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_7.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_8.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_9.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_10.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_11.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_12.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_13.c: Likewise.

Index: gcc/tree-cfg.c
===
--- gcc/tree-cfg.c  2019-09-05 08:49:30.829739618 +0100
+++ gcc/tree-cfg.c  2019-11-06 12:44:22.832365429 +
@@ -3553,6 +3553,24 @@ verify_gimple_assign_unary (gassign *stm
 {
 CASE_CONVERT:
   {
+   /* Allow conversions between vectors with the same number of elements,
+  provided that the conversion is OK for the element types too.  */
+   if (VECTOR_TYPE_P (lhs_type)
+   && VECTOR_TYPE_P (rhs1_type)
+   && known_eq (TYPE_VECTOR_SUBPARTS (lhs_type),
+TYPE_VECTOR_SUBPARTS (rhs1_type)))
+ {
+   lhs_type = TREE_TYPE (lhs_type);
+   rhs1_type = TREE_TYPE (rhs1_type);
+ }
+   else if (VECTOR_TYPE_P (lhs_type) || VECTOR_TYPE_P (rhs1_type))
+ {
+   error ("invalid vector types in nop conversion");
+   debug_generic_expr (lhs_type);
+   debug_generic_expr (rhs1_type);
+   return true;
+ }
+
/* Allow conversions from pointer type to integral type only if
   there is no sign or zero extension involved.
   For targets were the precision of ptrofftype doesn't match that
Index: gcc/tree-vect-stmts.c
===
--- gcc/tree-vect-stmts.c   2019-11-06 12:44:10.896448608 +
+++ gcc/tree-vect-stmts.c   2019-11-06 12:44:22.832365429 +
@@ -4869,7 +4869,9 @@ vectorizable_conversion (stmt_vec_info s
   switch (modifier)
 {
 case NONE:
-  if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
+  if (code != FIX_TRUNC_EXPR
+ && code != FLOAT_EXPR
+ && !CONVERT_EXPR_CODE_P (code))
return false;
   if (supportable_convert_operation (code, vectype_out, vectype_in,
 , ))
Index: gcc/expr.c
===
--- gcc/expr.c  2019-11-06 12:29:17.394677341 +
+++ gcc/expr.c  2019-11-06 12:44:22.828365457 +
@@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsi
 
   if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
 {
+  if (GET_MODE_UNIT_PRECISION (to_mode)
+ > GET_MODE_UNIT_PRECISION (from_mode))
+   {
+ optab op = unsignedp ? zext_optab : sext_optab;
+ insn_code icode = convert_optab_handler (op, to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+   {
+ emit_unop_insn (icode, to, from,
+ unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
+ return;
+   }
+   }
+
+  if (GET_MODE_UNIT_PRECISION (to_mode)
+ < GET_MODE_UNIT_PRECISION (from_mode))
+   {
+ insn_code icode = convert_optab_handler (trunc_optab,
+  to_mode, from_mode);
+ 

Re: [14/n] Vectorise conversions between differently-sized integer vectors

2019-11-05 Thread Richard Biener
On Fri, Oct 25, 2019 at 2:51 PM Richard Sandiford
 wrote:
>
> This patch adds AArch64 patterns for converting between 64-bit and
> 128-bit integer vectors, and makes the vectoriser and expand pass
> use them.

So on GIMPLE we'll see

v4si _1;
v4di _2;

 _1 = (v4si) _2;

then, correct?  Likewise for float conversions.

I think that's "new", can you add to tree-cfg.c:verify_gimple_assign_unary
verification that the number of lanes of the LHS and the RHS match please?

OK with that change.
Thanks,
Richard.

>
> 2019-10-24  Richard Sandiford  
>
> gcc/
> * tree-vect-stmts.c (vectorizable_conversion): Extend the
> non-widening and non-narrowing path to handle standard
> conversion codes, if the target supports them.
> * expr.c (convert_move): Try using the extend and truncate optabs
> for vectors.
> * optabs-tree.c (supportable_convert_operation): Likewise.
> * config/aarch64/iterators.md (Vnarroqw): New iterator.
> * config/aarch64/aarch64-simd.md (2)
> (trunc2): New patterns.
>
> gcc/testsuite/
> * gcc.dg/vect/no-scevccp-outer-12.c: Expect the test to pass
> on aarch64 targets.
> * gcc.dg/vect/vect-double-reduc-5.c: Likewise.
> * gcc.dg/vect/vect-outer-4e.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_5.c: New test.
> * gcc.target/aarch64/vect_mixed_sizes_6.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_7.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_8.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_9.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_10.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_11.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_12.c: Likewise.
> * gcc.target/aarch64/vect_mixed_sizes_13.c: Likewise.
>
> Index: gcc/tree-vect-stmts.c
> ===
> --- gcc/tree-vect-stmts.c   2019-10-25 13:27:32.877640367 +0100
> +++ gcc/tree-vect-stmts.c   2019-10-25 13:27:36.197616908 +0100
> @@ -4861,7 +4861,9 @@ vectorizable_conversion (stmt_vec_info s
>switch (modifier)
>  {
>  case NONE:
> -  if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
> +  if (code != FIX_TRUNC_EXPR
> + && code != FLOAT_EXPR
> + && !CONVERT_EXPR_CODE_P (code))
> return false;
>if (supportable_convert_operation (code, vectype_out, vectype_in,
>  , ))
> Index: gcc/expr.c
> ===
> --- gcc/expr.c  2019-10-22 08:46:57.359355939 +0100
> +++ gcc/expr.c  2019-10-25 13:27:36.193616936 +0100
> @@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsi
>
>if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
>  {
> +  if (GET_MODE_UNIT_PRECISION (to_mode)
> + > GET_MODE_UNIT_PRECISION (from_mode))
> +   {
> + optab op = unsignedp ? zext_optab : sext_optab;
> + insn_code icode = convert_optab_handler (op, to_mode, from_mode);
> + if (icode != CODE_FOR_nothing)
> +   {
> + emit_unop_insn (icode, to, from,
> + unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
> + return;
> +   }
> +   }
> +
> +  if (GET_MODE_UNIT_PRECISION (to_mode)
> + < GET_MODE_UNIT_PRECISION (from_mode))
> +   {
> + insn_code icode = convert_optab_handler (trunc_optab,
> +  to_mode, from_mode);
> + if (icode != CODE_FOR_nothing)
> +   {
> + emit_unop_insn (icode, to, from, TRUNCATE);
> + return;
> +   }
> +   }
> +
>gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
> GET_MODE_BITSIZE (to_mode)));
>
> Index: gcc/optabs-tree.c
> ===
> --- gcc/optabs-tree.c   2019-10-08 09:23:31.894529571 +0100
> +++ gcc/optabs-tree.c   2019-10-25 13:27:36.193616936 +0100
> @@ -303,6 +303,20 @@ supportable_convert_operation (enum tree
>return true;
>  }
>
> +  if (GET_MODE_UNIT_PRECISION (m1) > GET_MODE_UNIT_PRECISION (m2)
> +  && can_extend_p (m1, m2, TYPE_UNSIGNED (vectype_in)))
> +{
> +  *code1 = code;
> +  return true;
> +}
> +
> +  if (GET_MODE_UNIT_PRECISION (m1) < GET_MODE_UNIT_PRECISION (m2)
> +  && convert_optab_handler (trunc_optab, m1, m2) != CODE_FOR_nothing)
> +{
> +  *code1 = code;
> +  return true;
> +}
> +
>/* Now check for builtin.  */
>if (targetm.vectorize.builtin_conversion
>&& targetm.vectorize.builtin_conversion (code, vectype_out, 
> vectype_in))
> Index: gcc/config/aarch64/iterators.md
> ===
> --- gcc/config/aarch64/iterators.md 2019-10-17 14:23:07.71142 +0100
> +++ 

[14/n] Vectorise conversions between differently-sized integer vectors

2019-10-25 Thread Richard Sandiford
This patch adds AArch64 patterns for converting between 64-bit and
128-bit integer vectors, and makes the vectoriser and expand pass
use them.


2019-10-24  Richard Sandiford  

gcc/
* tree-vect-stmts.c (vectorizable_conversion): Extend the
non-widening and non-narrowing path to handle standard
conversion codes, if the target supports them.
* expr.c (convert_move): Try using the extend and truncate optabs
for vectors.
* optabs-tree.c (supportable_convert_operation): Likewise.
* config/aarch64/iterators.md (Vnarroqw): New iterator.
* config/aarch64/aarch64-simd.md (2)
(trunc2): New patterns.

gcc/testsuite/
* gcc.dg/vect/no-scevccp-outer-12.c: Expect the test to pass
on aarch64 targets.
* gcc.dg/vect/vect-double-reduc-5.c: Likewise.
* gcc.dg/vect/vect-outer-4e.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_5.c: New test.
* gcc.target/aarch64/vect_mixed_sizes_6.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_7.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_8.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_9.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_10.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_11.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_12.c: Likewise.
* gcc.target/aarch64/vect_mixed_sizes_13.c: Likewise.

Index: gcc/tree-vect-stmts.c
===
--- gcc/tree-vect-stmts.c   2019-10-25 13:27:32.877640367 +0100
+++ gcc/tree-vect-stmts.c   2019-10-25 13:27:36.197616908 +0100
@@ -4861,7 +4861,9 @@ vectorizable_conversion (stmt_vec_info s
   switch (modifier)
 {
 case NONE:
-  if (code != FIX_TRUNC_EXPR && code != FLOAT_EXPR)
+  if (code != FIX_TRUNC_EXPR
+ && code != FLOAT_EXPR
+ && !CONVERT_EXPR_CODE_P (code))
return false;
   if (supportable_convert_operation (code, vectype_out, vectype_in,
 , ))
Index: gcc/expr.c
===
--- gcc/expr.c  2019-10-22 08:46:57.359355939 +0100
+++ gcc/expr.c  2019-10-25 13:27:36.193616936 +0100
@@ -250,6 +250,31 @@ convert_move (rtx to, rtx from, int unsi
 
   if (VECTOR_MODE_P (to_mode) || VECTOR_MODE_P (from_mode))
 {
+  if (GET_MODE_UNIT_PRECISION (to_mode)
+ > GET_MODE_UNIT_PRECISION (from_mode))
+   {
+ optab op = unsignedp ? zext_optab : sext_optab;
+ insn_code icode = convert_optab_handler (op, to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+   {
+ emit_unop_insn (icode, to, from,
+ unsignedp ? ZERO_EXTEND : SIGN_EXTEND);
+ return;
+   }
+   }
+
+  if (GET_MODE_UNIT_PRECISION (to_mode)
+ < GET_MODE_UNIT_PRECISION (from_mode))
+   {
+ insn_code icode = convert_optab_handler (trunc_optab,
+  to_mode, from_mode);
+ if (icode != CODE_FOR_nothing)
+   {
+ emit_unop_insn (icode, to, from, TRUNCATE);
+ return;
+   }
+   }
+
   gcc_assert (known_eq (GET_MODE_BITSIZE (from_mode),
GET_MODE_BITSIZE (to_mode)));
 
Index: gcc/optabs-tree.c
===
--- gcc/optabs-tree.c   2019-10-08 09:23:31.894529571 +0100
+++ gcc/optabs-tree.c   2019-10-25 13:27:36.193616936 +0100
@@ -303,6 +303,20 @@ supportable_convert_operation (enum tree
   return true;
 }
 
+  if (GET_MODE_UNIT_PRECISION (m1) > GET_MODE_UNIT_PRECISION (m2)
+  && can_extend_p (m1, m2, TYPE_UNSIGNED (vectype_in)))
+{
+  *code1 = code;
+  return true;
+}
+
+  if (GET_MODE_UNIT_PRECISION (m1) < GET_MODE_UNIT_PRECISION (m2)
+  && convert_optab_handler (trunc_optab, m1, m2) != CODE_FOR_nothing)
+{
+  *code1 = code;
+  return true;
+}
+
   /* Now check for builtin.  */
   if (targetm.vectorize.builtin_conversion
   && targetm.vectorize.builtin_conversion (code, vectype_out, vectype_in))
Index: gcc/config/aarch64/iterators.md
===
--- gcc/config/aarch64/iterators.md 2019-10-17 14:23:07.71142 +0100
+++ gcc/config/aarch64/iterators.md 2019-10-25 13:27:36.189616964 +0100
@@ -860,6 +860,8 @@ (define_mode_attr VNARROWQ [(V8HI "V8QI"
(V2DI "V2SI")
(DI   "SI")   (SI   "HI")
(HI   "QI")])
+(define_mode_attr Vnarrowq [(V8HI "v8qi") (V4SI "v4hi")
+   (V2DI "v2si")])
 
 ;; Narrowed quad-modes for VQN (Used for XTN2).
 (define_mode_attr VNARROWQ2 [(V8HI "V16QI") (V4SI "V8HI")
Index: gcc/config/aarch64/aarch64-simd.md