Re: Add IFN_COND_{MUL,DIV,MOD,RDIV}

2018-05-24 Thread Richard Biener
On Thu, May 24, 2018 at 11:34 AM Richard Sandiford <
richard.sandif...@linaro.org> wrote:

> This patch adds support for conditional multiplication and division.
> It's mostly mechanical, but a few notes:

> * The *_optab name and the .md names are the same as the unconditional
>forms, just with "cond_" added to the front.  This means we still
>have the awkward difference between sdiv and div, etc.

> * It was easier to retain the difference between integer and FP
>division in the function names, given that they map to different
>tree codes (TRUNC_DIV_EXPR and RDIV_EXPR).

> * SVE has no direct support for IFN_COND_MOD, but it seemed more
>consistent to add it anyway.

> * Adding IFN_COND_MUL enables an extra fully-masked reduction
>in gcc.dg/vect/pr53773.c.

> * In practice we don't actually use the integer division forms without
>if-conversion support (added by a later patch).

> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
> and x86_64-linux-gnu.  OK for the non-AArch64 bits?

OK.

Richard.

> Richard


> 2018-05-24  Richard Sandiford  

> gcc/
>  * doc/sourcebuild.texi (vect_double_cond_arith): Include
>  multiplication and division.
>  * doc/md.texi (cond_mul@var{m}, cond_div@var{m}, cond_mod@var{m})
>  (cond_udiv@var{m}, cond_umod@var{m}): Document.
>  * optabs.def (cond_smul_optab, cond_sdiv_optab, cond_smod_optab)
>  (cond_udiv_optab, cond_umod_optab): New optabs.
>  * internal-fn.def (IFN_COND_MUL, IFN_COND_DIV, IFN_COND_MOD)
>  (IFN_COND_RDIV): New internal functions.
>  * internal-fn.c (get_conditional_internal_fn): Handle
TRUNC_DIV_EXPR,
>  TRUNC_MOD_EXPR and RDIV_EXPR.
>  * genmatch.c (commutative_op): Handle CFN_COND_MUL.
>  * match.pd (UNCOND_BINARY, COND_BINARY): Handle them.
>  * config/aarch64/iterators.md (UNSPEC_COND_MUL, UNSPEC_COND_DIV):
>  New unspecs.
>  (SVE_INT_BINARY): Include mult.
>  (SVE_COND_FP_BINARY): Include UNSPEC_MUL and UNSPEC_DIV.
>  (optab, sve_int_op): Handle mult.
>  (optab, sve_fp_op, commutative): Handle UNSPEC_COND_MUL and
>  UNSPEC_COND_DIV.
>  * config/aarch64/aarch64-sve.md (cond_): New pattern
>  for SVE_INT_BINARY_SD.

> gcc/testsuite/
>  * lib/target-supports.exp
>  (check_effective_target_vect_double_cond_arith): Include
>  multiplication and division.
>  * gcc.dg/vect/pr53773.c: Do not expect a scalar tail when using
>  fully-masked loops with a fixed vector length.
>  * gcc.dg/vect/vect-cond-arith-1.c: Add multiplication and division
>  tests.
>  * gcc.target/aarch64/sve/vcond_8.c: Likewise.
>  * gcc.target/aarch64/sve/vcond_9.c: Likewise.
>  * gcc.target/aarch64/sve/vcond_12.c: Add multiplication tests.

> Index: gcc/doc/sourcebuild.texi
> ===
> --- gcc/doc/sourcebuild.texi2018-05-24 09:54:37.508451387 +0100
> +++ gcc/doc/sourcebuild.texi2018-05-24 10:12:10.145352193 +0100
> @@ -1426,8 +1426,9 @@ have different type from the value opera
>   Target supports hardware vectors of @code{double}.

>   @item vect_double_cond_arith
> -Target supports conditional addition, subtraction, minimum and maximum
> -on vectors of @code{double}, via the @code{cond_} optabs.
> +Target supports conditional addition, subtraction, multiplication,
> +division, minimum and maximum on vectors of @code{double}, via the
> +@code{cond_} optabs.

>   @item vect_element_align_preferred
>   The target's preferred vector alignment is the same as the element
> Index: gcc/doc/md.texi
> ===
> --- gcc/doc/md.texi 2018-05-24 09:32:10.522816506 +0100
> +++ gcc/doc/md.texi 2018-05-24 10:12:10.142352315 +0100
> @@ -6333,6 +6333,11 @@ operand 0, otherwise (operand 2 + operan

>   @cindex @code{cond_add@var{mode}} instruction pattern
>   @cindex @code{cond_sub@var{mode}} instruction pattern
> +@cindex @code{cond_mul@var{mode}} instruction pattern
> +@cindex @code{cond_div@var{mode}} instruction pattern
> +@cindex @code{cond_udiv@var{mode}} instruction pattern
> +@cindex @code{cond_mod@var{mode}} instruction pattern
> +@cindex @code{cond_umod@var{mode}} instruction pattern
>   @cindex @code{cond_and@var{mode}} instruction pattern
>   @cindex @code{cond_ior@var{mode}} instruction pattern
>   @cindex @code{cond_xor@var{mode}} instruction pattern
> @@ -6342,6 +6347,11 @@ operand 0, otherwise (operand 2 + operan
>   @cindex @code{cond_umax@var{mode}} instruction pattern
>   @item @samp{cond_add@var{mode}}
>   @itemx @samp{cond_sub@var{mode}}
> +@itemx @samp{cond_mul@var{mode}}
> +@itemx @samp{cond_div@var{mode}}
> +@itemx @samp{cond_udiv@var{mode}}
> +@itemx @samp{cond_mod@var{mode}}
> +@itemx @samp{cond_umod@var{mode}}
>   @itemx 

Add IFN_COND_{MUL,DIV,MOD,RDIV}

2018-05-24 Thread Richard Sandiford
This patch adds support for conditional multiplication and division.
It's mostly mechanical, but a few notes:

* The *_optab name and the .md names are the same as the unconditional
  forms, just with "cond_" added to the front.  This means we still
  have the awkward difference between sdiv and div, etc.

* It was easier to retain the difference between integer and FP
  division in the function names, given that they map to different
  tree codes (TRUNC_DIV_EXPR and RDIV_EXPR).

* SVE has no direct support for IFN_COND_MOD, but it seemed more
  consistent to add it anyway.

* Adding IFN_COND_MUL enables an extra fully-masked reduction
  in gcc.dg/vect/pr53773.c.

* In practice we don't actually use the integer division forms without
  if-conversion support (added by a later patch).

Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
and x86_64-linux-gnu.  OK for the non-AArch64 bits?

Richard


2018-05-24  Richard Sandiford  

gcc/
* doc/sourcebuild.texi (vect_double_cond_arith): Include
multiplication and division.
* doc/md.texi (cond_mul@var{m}, cond_div@var{m}, cond_mod@var{m})
(cond_udiv@var{m}, cond_umod@var{m}): Document.
* optabs.def (cond_smul_optab, cond_sdiv_optab, cond_smod_optab)
(cond_udiv_optab, cond_umod_optab): New optabs.
* internal-fn.def (IFN_COND_MUL, IFN_COND_DIV, IFN_COND_MOD)
(IFN_COND_RDIV): New internal functions.
* internal-fn.c (get_conditional_internal_fn): Handle TRUNC_DIV_EXPR,
TRUNC_MOD_EXPR and RDIV_EXPR.
* genmatch.c (commutative_op): Handle CFN_COND_MUL.
* match.pd (UNCOND_BINARY, COND_BINARY): Handle them.
* config/aarch64/iterators.md (UNSPEC_COND_MUL, UNSPEC_COND_DIV):
New unspecs.
(SVE_INT_BINARY): Include mult.
(SVE_COND_FP_BINARY): Include UNSPEC_MUL and UNSPEC_DIV.
(optab, sve_int_op): Handle mult.
(optab, sve_fp_op, commutative): Handle UNSPEC_COND_MUL and
UNSPEC_COND_DIV.
* config/aarch64/aarch64-sve.md (cond_): New pattern
for SVE_INT_BINARY_SD.

gcc/testsuite/
* lib/target-supports.exp
(check_effective_target_vect_double_cond_arith): Include
multiplication and division.
* gcc.dg/vect/pr53773.c: Do not expect a scalar tail when using
fully-masked loops with a fixed vector length.
* gcc.dg/vect/vect-cond-arith-1.c: Add multiplication and division
tests.
* gcc.target/aarch64/sve/vcond_8.c: Likewise.
* gcc.target/aarch64/sve/vcond_9.c: Likewise.
* gcc.target/aarch64/sve/vcond_12.c: Add multiplication tests.

Index: gcc/doc/sourcebuild.texi
===
--- gcc/doc/sourcebuild.texi2018-05-24 09:54:37.508451387 +0100
+++ gcc/doc/sourcebuild.texi2018-05-24 10:12:10.145352193 +0100
@@ -1426,8 +1426,9 @@ have different type from the value opera
 Target supports hardware vectors of @code{double}.
 
 @item vect_double_cond_arith
-Target supports conditional addition, subtraction, minimum and maximum
-on vectors of @code{double}, via the @code{cond_} optabs.
+Target supports conditional addition, subtraction, multiplication,
+division, minimum and maximum on vectors of @code{double}, via the
+@code{cond_} optabs.
 
 @item vect_element_align_preferred
 The target's preferred vector alignment is the same as the element
Index: gcc/doc/md.texi
===
--- gcc/doc/md.texi 2018-05-24 09:32:10.522816506 +0100
+++ gcc/doc/md.texi 2018-05-24 10:12:10.142352315 +0100
@@ -6333,6 +6333,11 @@ operand 0, otherwise (operand 2 + operan
 
 @cindex @code{cond_add@var{mode}} instruction pattern
 @cindex @code{cond_sub@var{mode}} instruction pattern
+@cindex @code{cond_mul@var{mode}} instruction pattern
+@cindex @code{cond_div@var{mode}} instruction pattern
+@cindex @code{cond_udiv@var{mode}} instruction pattern
+@cindex @code{cond_mod@var{mode}} instruction pattern
+@cindex @code{cond_umod@var{mode}} instruction pattern
 @cindex @code{cond_and@var{mode}} instruction pattern
 @cindex @code{cond_ior@var{mode}} instruction pattern
 @cindex @code{cond_xor@var{mode}} instruction pattern
@@ -6342,6 +6347,11 @@ operand 0, otherwise (operand 2 + operan
 @cindex @code{cond_umax@var{mode}} instruction pattern
 @item @samp{cond_add@var{mode}}
 @itemx @samp{cond_sub@var{mode}}
+@itemx @samp{cond_mul@var{mode}}
+@itemx @samp{cond_div@var{mode}}
+@itemx @samp{cond_udiv@var{mode}}
+@itemx @samp{cond_mod@var{mode}}
+@itemx @samp{cond_umod@var{mode}}
 @itemx @samp{cond_and@var{mode}}
 @itemx @samp{cond_ior@var{mode}}
 @itemx @samp{cond_xor@var{mode}}
Index: gcc/optabs.def
===
--- gcc/optabs.def  2018-05-16 12:48:59.194282896 +0100
+++ gcc/optabs.def  2018-05-24 10:12:10.146352152 +0100
@@ -222,6 +222,11 @@ OPTAB_D