Add IFN_COND_{MUL,DIV,MOD,RDIV}
authorRichard Sandiford <richard.sandiford@linaro.org>
Fri, 25 May 2018 08:53:15 +0000 (08:53 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Fri, 25 May 2018 08:53:15 +0000 (08:53 +0000)
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).

2018-05-25  Richard Sandiford  <richard.sandiford@linaro.org>

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.
* 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_<optab><mode>): 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.

From-SVN: r260713

16 files changed:
gcc/ChangeLog
gcc/config/aarch64/aarch64-sve.md
gcc/config/aarch64/iterators.md
gcc/doc/md.texi
gcc/doc/sourcebuild.texi
gcc/internal-fn.c
gcc/internal-fn.def
gcc/match.pd
gcc/optabs.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr53773.c
gcc/testsuite/gcc.dg/vect/vect-cond-arith-1.c
gcc/testsuite/gcc.target/aarch64/sve/vcond_12.c
gcc/testsuite/gcc.target/aarch64/sve/vcond_8.c
gcc/testsuite/gcc.target/aarch64/sve/vcond_9.c
gcc/testsuite/lib/target-supports.exp

index 0dcece5c219fba08e4cdb27528b6443c60c83547..45566e6a13a5114155334c6461069a5bbf3d3880 100644 (file)
@@ -1,3 +1,26 @@
+2018-05-25  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * 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.
+       * 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_<optab><mode>): New pattern
+       for SVE_INT_BINARY_SD.
+
 2018-05-25  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * config/aarch64/iterators.md (SVE_INT_BINARY_SD): New code iterator.
index eac3ac97590060e46dba35061ca6d2747a81116e..8e2433385a80d606e199ce6252eae6216da42b66 100644 (file)
   aarch64_sve_prepare_conditional_op (operands, 5, commutative_p);
 })
 
+(define_expand "cond_<optab><mode>"
+  [(set (match_operand:SVE_SDI 0 "register_operand")
+       (unspec:SVE_SDI
+         [(match_operand:<VPRED> 1 "register_operand")
+          (SVE_INT_BINARY_SD:SVE_SDI
+            (match_operand:SVE_SDI 2 "register_operand")
+            (match_operand:SVE_SDI 3 "register_operand"))
+          (match_operand:SVE_SDI 4 "register_operand")]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+{
+  bool commutative_p = (GET_RTX_CLASS (<CODE>) == RTX_COMM_ARITH);
+  aarch64_sve_prepare_conditional_op (operands, 5, commutative_p);
+})
+
 ;; Predicated integer operations.
 (define_insn "*cond_<optab><mode>"
   [(set (match_operand:SVE_I 0 "register_operand" "=w")
   "<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
 )
 
+(define_insn "*cond_<optab><mode>"
+  [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
+       (unspec:SVE_SDI
+         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+          (SVE_INT_BINARY_SD:SVE_SDI
+            (match_operand:SVE_SDI 2 "register_operand" "0")
+            (match_operand:SVE_SDI 3 "register_operand" "w"))
+          (match_dup 2)]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+  "<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+)
+
 ;; Predicated integer operations with the operands reversed.
 (define_insn "*cond_<optab><mode>"
   [(set (match_operand:SVE_I 0 "register_operand" "=w")
   "<sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
 )
 
+(define_insn "*cond_<optab><mode>"
+  [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
+       (unspec:SVE_SDI
+         [(match_operand:<VPRED> 1 "register_operand" "Upl")
+          (SVE_INT_BINARY_SD:SVE_SDI
+            (match_operand:SVE_SDI 2 "register_operand" "w")
+            (match_operand:SVE_SDI 3 "register_operand" "0"))
+          (match_dup 3)]
+         UNSPEC_SEL))]
+  "TARGET_SVE"
+  "<sve_int_op>r\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+)
+
 ;; Set operand 0 to the last active element in operand 3, or to tied
 ;; operand 1 if no elements are active.
 (define_insn "fold_extract_last_<mode>"
index dad07e437f060e0df80099124f66b5c7317c6e88..dbe1e34b61d1dcc96eebbf80b9745df94f130232 100644 (file)
     UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md.
     UNSPEC_COND_ADD    ; Used in aarch64-sve.md.
     UNSPEC_COND_SUB    ; Used in aarch64-sve.md.
+    UNSPEC_COND_MUL    ; Used in aarch64-sve.md.
+    UNSPEC_COND_DIV    ; Used in aarch64-sve.md.
     UNSPEC_COND_MAX    ; Used in aarch64-sve.md.
     UNSPEC_COND_MIN    ; Used in aarch64-sve.md.
     UNSPEC_COND_LT     ; Used in aarch64-sve.md.
 ;; SVE floating-point unary operations.
 (define_code_iterator SVE_FP_UNARY [neg abs sqrt])
 
-(define_code_iterator SVE_INT_BINARY [plus minus smax umax smin umin
+(define_code_iterator SVE_INT_BINARY [plus minus mult smax umax smin umin
                                      and ior xor])
 
 (define_code_iterator SVE_INT_BINARY_REV [minus])
                         (neg "neg")
                         (plus "add")
                         (minus "sub")
+                        (mult "mul")
                         (div "div")
                         (udiv "udiv")
                         (ss_plus "qadd")
 ;; The integer SVE instruction that implements an rtx code.
 (define_code_attr sve_int_op [(plus "add")
                              (minus "sub")
+                             (mult "mul")
                              (div "sdiv")
                              (udiv "udiv")
                              (neg "neg")
 (define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART])
 
 (define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_ADD UNSPEC_COND_SUB
+                                        UNSPEC_COND_MUL UNSPEC_COND_DIV
                                         UNSPEC_COND_MAX UNSPEC_COND_MIN])
 
-(define_int_iterator SVE_COND_FP_BINARY_REV [UNSPEC_COND_SUB])
+(define_int_iterator SVE_COND_FP_BINARY_REV [UNSPEC_COND_SUB UNSPEC_COND_DIV])
 
 (define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
                                      UNSPEC_COND_EQ UNSPEC_COND_NE
                        (UNSPEC_XORV "xor")
                        (UNSPEC_COND_ADD "add")
                        (UNSPEC_COND_SUB "sub")
+                       (UNSPEC_COND_MUL "mul")
+                       (UNSPEC_COND_DIV "div")
                        (UNSPEC_COND_MAX "smax")
                        (UNSPEC_COND_MIN "smin")])
 
 
 (define_int_attr sve_fp_op [(UNSPEC_COND_ADD "fadd")
                            (UNSPEC_COND_SUB "fsub")
+                           (UNSPEC_COND_MUL "fmul")
+                           (UNSPEC_COND_DIV "fdiv")
                            (UNSPEC_COND_MAX "fmaxnm")
                            (UNSPEC_COND_MIN "fminnm")])
 
 (define_int_attr commutative [(UNSPEC_COND_ADD "true")
                              (UNSPEC_COND_SUB "false")
+                             (UNSPEC_COND_MUL "true")
+                             (UNSPEC_COND_DIV "false")
                              (UNSPEC_COND_MIN "true")
                              (UNSPEC_COND_MAX "true")])
index ce46320b418748a51a1d90d6530d4ebade960ab4..02fbfb392a9994c9cfcf8718cf87dd0c89e3e3f3 100644 (file)
@@ -6333,6 +6333,11 @@ operand 0, otherwise (operand 2 + operand 3) is moved.
 
 @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 + operand 3) is moved.
 @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 00e53a657c82ef65ffa5006f3e6cd01443c57caa..09c00531333c726b7146b0050c4753ad1f763740 100644 (file)
@@ -1426,8 +1426,9 @@ have different type from the value operands.
 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 6765a7708197cd0860e1d47c7132887c516574e5..a7bb748b66e1e63c4d99081931d47cb6c18d3390 100644 (file)
@@ -3246,6 +3246,12 @@ get_conditional_internal_fn (tree_code code)
       return IFN_COND_MIN;
     case MAX_EXPR:
       return IFN_COND_MAX;
+    case TRUNC_DIV_EXPR:
+      return IFN_COND_DIV;
+    case TRUNC_MOD_EXPR:
+      return IFN_COND_MOD;
+    case RDIV_EXPR:
+      return IFN_COND_RDIV;
     case BIT_AND_EXPR:
       return IFN_COND_AND;
     case BIT_IOR_EXPR:
index c56b731addbd2cf2ab3a4cb06466e98f540976c0..66336d8062b12c5c473c199bc206fba6d9e65203 100644 (file)
@@ -145,6 +145,12 @@ DEF_INTERNAL_OPTAB_FN (FNMS, ECF_CONST, fnms, ternary)
 
 DEF_INTERNAL_OPTAB_FN (COND_ADD, ECF_CONST, cond_add, cond_binary)
 DEF_INTERNAL_OPTAB_FN (COND_SUB, ECF_CONST, cond_sub, cond_binary)
+DEF_INTERNAL_OPTAB_FN (COND_MUL, ECF_CONST, cond_smul, cond_binary)
+DEF_INTERNAL_SIGNED_OPTAB_FN (COND_DIV, ECF_CONST, first,
+                             cond_sdiv, cond_udiv, cond_binary)
+DEF_INTERNAL_SIGNED_OPTAB_FN (COND_MOD, ECF_CONST, first,
+                             cond_smod, cond_umod, cond_binary)
+DEF_INTERNAL_OPTAB_FN (COND_RDIV, ECF_CONST, cond_sdiv, cond_binary)
 DEF_INTERNAL_SIGNED_OPTAB_FN (COND_MIN, ECF_CONST, first,
                              cond_smin, cond_umin, cond_binary)
 DEF_INTERNAL_SIGNED_OPTAB_FN (COND_MAX, ECF_CONST, first,
index f08571ef28c6bc95a78f906631341ac92d6b975e..14386da070b0b71c59981310843505680872b1df 100644 (file)
@@ -78,10 +78,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 /* Binary operations and their associated IFN_COND_* function.  */
 (define_operator_list UNCOND_BINARY
   plus minus
+  mult trunc_div trunc_mod rdiv
   min max
   bit_and bit_ior bit_xor)
 (define_operator_list COND_BINARY
   IFN_COND_ADD IFN_COND_SUB
+  IFN_COND_MUL IFN_COND_DIV IFN_COND_MOD IFN_COND_RDIV
   IFN_COND_MIN IFN_COND_MAX
   IFN_COND_AND IFN_COND_IOR IFN_COND_XOR)
     
index 2c30f0eb39668f9e4c678305f754f3d1a3954bca..a1ecb757bb2141a27d415a50fa094435692b7e8b 100644 (file)
@@ -222,6 +222,11 @@ OPTAB_D (notcc_optab, "not$acc")
 OPTAB_D (movcc_optab, "mov$acc")
 OPTAB_D (cond_add_optab, "cond_add$a")
 OPTAB_D (cond_sub_optab, "cond_sub$a")
+OPTAB_D (cond_smul_optab, "cond_mul$a")
+OPTAB_D (cond_sdiv_optab, "cond_div$a")
+OPTAB_D (cond_smod_optab, "cond_mod$a")
+OPTAB_D (cond_udiv_optab, "cond_udiv$a")
+OPTAB_D (cond_umod_optab, "cond_umod$a")
 OPTAB_D (cond_and_optab, "cond_and$a")
 OPTAB_D (cond_ior_optab, "cond_ior$a")
 OPTAB_D (cond_xor_optab, "cond_xor$a")
index c1e289a9bbf632efaabe02ba67e9acd8278c4892..1399fb17087d665310f35b16f80b5b9dd1e0c6dd 100644 (file)
@@ -1,3 +1,16 @@
+2018-05-25  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * 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.
+
 2018-05-25  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * gcc.target/aarch64/sve/div_1.c: New test.
index 1bee98b75d9b84de3b7a72c83b634b57e941b272..0bcc021767e636aff950eced04e778cb990976d0 100644 (file)
@@ -14,5 +14,8 @@ foo (int integral, int decimal, int power_ten)
   return integral+decimal;
 }
 
-/* { dg-final { scan-tree-dump-times "\\* 10" 2 "optimized" } } */
+/* We can avoid a scalar tail when using fully-masked loops with a fixed
+   vector length.  */
+/* { dg-final { scan-tree-dump-times "\\* 10" 2 "optimized" { target { { ! vect_fully_masked } || vect_variable_length } } } } */
+/* { dg-final { scan-tree-dump-times "\\* 10" 0 "optimized" { target { vect_fully_masked && { ! vect_variable_length } } } } } */
 
index 9f2fccd7187b39706266525e87105ab073122620..d52e81e9109cc4d81de84adf370b2322799c8c27 100644 (file)
@@ -6,6 +6,8 @@
 
 #define add(A, B) ((A) + (B))
 #define sub(A, B) ((A) - (B))
+#define mul(A, B) ((A) * (B))
+#define div(A, B) ((A) / (B))
 
 #define DEF(OP)                                                        \
   void __attribute__ ((noipa))                                 \
@@ -34,6 +36,8 @@
 #define FOR_EACH_OP(T)                         \
   T (add)                                      \
   T (sub)                                      \
+  T (mul)                                      \
+  T (div)                                      \
   T (__builtin_fmax)                           \
   T (__builtin_fmin)
 
@@ -54,5 +58,7 @@ main (void)
 
 /* { dg-final { scan-tree-dump { = \.COND_ADD} "optimized" { target vect_double_cond_arith } } } */
 /* { dg-final { scan-tree-dump { = \.COND_SUB} "optimized" { target vect_double_cond_arith } } } */
+/* { dg-final { scan-tree-dump { = \.COND_MUL} "optimized" { target vect_double_cond_arith } } } */
+/* { dg-final { scan-tree-dump { = \.COND_RDIV} "optimized" { target vect_double_cond_arith } } } */
 /* { dg-final { scan-tree-dump { = \.COND_MAX} "optimized" { target vect_double_cond_arith } } } */
 /* { dg-final { scan-tree-dump { = \.COND_MIN} "optimized" { target vect_double_cond_arith } } } */
index 95b371a177358ded0c3a1f1cad5ba5edb5497697..de650bf39e27b5cdb0f06d04b5d7948b3cc94a54 100644 (file)
@@ -5,6 +5,8 @@
 
 #define add(A, B) ((A) + (B))
 #define sub(A, B) ((A) - (B))
+#define mul(A, B) ((A) * (B))
+#define div(A, B) ((A) / (B))
 #define max(A, B) ((A) > (B) ? (A) : (B))
 #define min(A, B) ((A) < (B) ? (A) : (B))
 #define and(A, B) ((A) & (B))
@@ -29,6 +31,7 @@
 #define FOR_EACH_INT_TYPE(T, TYPE) \
   T (TYPE, TYPE, add) \
   T (TYPE, TYPE, sub) \
+  T (TYPE, TYPE, mul) \
   T (TYPE, TYPE, max) \
   T (TYPE, TYPE, min) \
   T (TYPE, TYPE, and) \
@@ -38,6 +41,8 @@
 #define FOR_EACH_FP_TYPE(T, TYPE, CMPTYPE, SUFFIX) \
   T (TYPE, CMPTYPE, add) \
   T (TYPE, CMPTYPE, sub) \
+  T (TYPE, CMPTYPE, mul) \
+  /* No div because that gets converted into a mul anyway.  */ \
   T (TYPE, CMPTYPE, __builtin_fmax##SUFFIX) \
   T (TYPE, CMPTYPE, __builtin_fmin##SUFFIX)
 
@@ -58,10 +63,10 @@ FOR_EACH_LOOP (DEF_LOOP)
 
 /* { dg-final { scan-assembler-not {\tmov\tz[0-9]+\.., z[0-9]+} } } */
 
-/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b,} 14 } } */
-/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h,} 18 } } */
-/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s,} 18 } } */
-/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d,} 18 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.b,} 16 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h,} 21 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s,} 21 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d,} 21 } } */
 
 /* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
 /* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
@@ -73,6 +78,11 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
 /* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
 
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
@@ -116,6 +126,10 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
 
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
index c32ab5967169d0b4ab04d02945f7bb1a1bd3d22e..d49dee733618be6061ff17a3db79e964c2968b4a 100644 (file)
@@ -5,6 +5,8 @@
 
 #define add(A, B) ((A) + (B))
 #define sub(A, B) ((A) - (B))
+#define mul(A, B) ((A) * (B))
+#define div(A, B) ((A) / (B))
 #define max(A, B) ((A) > (B) ? (A) : (B))
 #define min(A, B) ((A) < (B) ? (A) : (B))
 #define and(A, B) ((A) & (B))
@@ -27,6 +29,7 @@
 #define FOR_EACH_INT_TYPE(T, TYPE) \
   T (TYPE, TYPE, add) \
   T (TYPE, TYPE, sub) \
+  T (TYPE, TYPE, mul) \
   T (TYPE, TYPE, max) \
   T (TYPE, TYPE, min) \
   T (TYPE, TYPE, and) \
@@ -36,6 +39,8 @@
 #define FOR_EACH_FP_TYPE(T, TYPE, CMPTYPE, SUFFIX) \
   T (TYPE, CMPTYPE, add) \
   T (TYPE, CMPTYPE, sub) \
+  T (TYPE, CMPTYPE, mul) \
+  T (TYPE, CMPTYPE, div) \
   T (TYPE, CMPTYPE, __builtin_fmax##SUFFIX) \
   T (TYPE, CMPTYPE, __builtin_fmin##SUFFIX)
 
@@ -67,6 +72,11 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
 /* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
 
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
@@ -110,6 +120,14 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
 
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfdiv\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
index 618e187d5872072424ac12773e6139171ced9c34..806af7f19143b6125e6f37f563dd06535145df12 100644 (file)
@@ -5,6 +5,8 @@
 
 #define add(A, B) ((A) + (B))
 #define sub(A, B) ((A) - (B))
+#define mul(A, B) ((A) * (B))
+#define div(A, B) ((A) / (B))
 #define max(A, B) ((A) > (B) ? (A) : (B))
 #define min(A, B) ((A) < (B) ? (A) : (B))
 #define and(A, B) ((A) & (B))
@@ -27,6 +29,7 @@
 #define FOR_EACH_INT_TYPE(T, TYPE) \
   T (TYPE, TYPE, add) \
   T (TYPE, TYPE, sub) \
+  T (TYPE, TYPE, mul) \
   T (TYPE, TYPE, max) \
   T (TYPE, TYPE, min) \
   T (TYPE, TYPE, and) \
@@ -36,6 +39,8 @@
 #define FOR_EACH_FP_TYPE(T, TYPE, CMPTYPE, SUFFIX) \
   T (TYPE, CMPTYPE, add) \
   T (TYPE, CMPTYPE, sub) \
+  T (TYPE, CMPTYPE, mul) \
+  T (TYPE, CMPTYPE, div) \
   T (TYPE, CMPTYPE, __builtin_fmax##SUFFIX) \
   T (TYPE, CMPTYPE, __builtin_fmin##SUFFIX)
 
@@ -67,6 +72,11 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tsubr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
 /* { dg-final { scan-assembler-times {\tsubr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
 
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmul\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
@@ -110,6 +120,14 @@ FOR_EACH_LOOP (DEF_LOOP)
 /* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
 
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfdivr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfdivr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfdivr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
 /* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
index 0f8edce69bf944b043cdff562a9757afa330d413..3c2c62a58004677411ca380259043d5a9d484469 100644 (file)
@@ -5590,8 +5590,9 @@ proc check_effective_target_vect_double { } {
     return $et_vect_double_saved($et_index)
 }
 
-# Return 1 if the target supports conditional addition, subtraction, minimum
-# and maximum on vectors of double, via the cond_ optabs.  Return 0 otherwise.
+# Return 1 if the target supports conditional addition, subtraction,
+# multiplication, division, minimum and maximum on vectors of double,
+# via the cond_ optabs.  Return 0 otherwise.
 
 proc check_effective_target_vect_double_cond_arith { } {
     return [check_effective_target_aarch64_sve]