[PATCH, rs6000]Add support to enable vmsumudm behind vec_msum builtin.
authorWill Schmidt <will_schmidt@vnet.ibm.com>
Thu, 18 Jun 2020 20:14:00 +0000 (15:14 -0500)
committerWill Schmidt <will_schmidt@vnet.ibm.com>
Wed, 8 Jul 2020 15:33:09 +0000 (10:33 -0500)
gcc/ChangeLog:

2020-07-08  Will Schmidt  <will_schmidt@vnet.ibm.com>

* config/rs6000/altivec.h (vec_vmsumudm): New define.
* config/rs6000/altivec.md (UNSPEC_VMSUMUDM): New unspec.
  (altivec_vmsumudm): New define_insn.
* config/rs6000/rs6000-builtin.def (altivec_vmsumudm): New BU_ALTIVEC_3
  entry. (vmsumudm): New BU_ALTIVEC_OVERLOAD_3 entry.
* config/rs6000/rs6000-call.c (altivec_overloaded_builtins): Add entries for
  ALTIVEC_BUILTIN_VMSUMUDM variants of vec_msum.
* doc/extend.texi: Add document for vmsumudm behind vmsum.

gcc/testsuite/ChangeLog:

2020-07-08  Will Schmidt  <will_schmidt@vnet.ibm.com>

* gcc.target/powerpc/builtins-msum-runnable.c: New test.
* gcc.target/powerpc/vsx-builtin-msum.c: New test.

gcc/config/rs6000/altivec.h
gcc/config/rs6000/altivec.md
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000-call.c
gcc/doc/extend.texi
gcc/testsuite/gcc.target/powerpc/builtins-msum-runnable.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/vsx-builtin-msum.c [new file with mode: 0644]

index bb1524f4a6793a192d36623387a5a950fad49382..0d199393556df7f3e61b6f0784592a33217b842e 100644 (file)
 #define vec_vmsumubm __builtin_vec_vmsumubm
 #define vec_vmsumshs __builtin_vec_vmsumshs
 #define vec_vmsumuhs __builtin_vec_vmsumuhs
+#define vec_vmsumudm __builtin_vec_vmsumudm
 #define vec_vmulesb __builtin_vec_vmulesb
 #define vec_vmulesh __builtin_vec_vmulesh
 #define vec_vmuleuh __builtin_vec_vmuleuh
index 2ce9227c765ad9545369fe723ddd672af245f9bc..0481642fd95ca3405a796f34bb9e26648422b9b5 100644 (file)
@@ -21,6 +21,7 @@
 (define_c_enum "unspec"
   [UNSPEC_VCMPBFP
    UNSPEC_VMSUMU
+   UNSPEC_VMSUMUDM
    UNSPEC_VMSUMM
    UNSPEC_VMSUMSHM
    UNSPEC_VMSUMUHS
   "vmsumu<VI_char>m %0,%1,%2,%3"
   [(set_attr "type" "veccomplex")])
 
+(define_insn "altivec_vmsumudm"
+  [(set (match_operand:V1TI 0 "register_operand" "=v")
+       (unspec:V1TI [(match_operand:V2DI 1 "register_operand" "v")
+                     (match_operand:V2DI 2 "register_operand" "v")
+                     (match_operand:V1TI 3 "register_operand" "v")]
+                    UNSPEC_VMSUMUDM))]
+  "TARGET_P8_VECTOR"
+  "vmsumudm %0,%1,%2,%3"
+  [(set_attr "type" "veccomplex")])
+
 (define_insn "altivec_vmsumm<VI_char>m"
   [(set (match_operand:V4SI 0 "register_operand" "=v")
         (unspec:V4SI [(match_operand:VIshort 1 "register_operand" "v")
index 363656ec05cc23ed66d20ef346a85b9ee4c616d0..ee0d787cfa2258e42dc7d483ec1ca969fcc8a039 100644 (file)
@@ -1142,6 +1142,7 @@ BU_ALTIVEC_3 (VMLADDUHM,      "vmladduhm",      CONST,    fmav8hi4)
 BU_ALTIVEC_3 (VMSUMUBM,       "vmsumubm",       CONST,         altivec_vmsumubm)
 BU_ALTIVEC_3 (VMSUMMBM,       "vmsummbm",       CONST,         altivec_vmsummbm)
 BU_ALTIVEC_3 (VMSUMUHM,       "vmsumuhm",       CONST,         altivec_vmsumuhm)
+BU_ALTIVEC_3 (VMSUMUDM,       "vmsumudm",       CONST,         altivec_vmsumudm)
 BU_ALTIVEC_3 (VMSUMSHM,       "vmsumshm",       CONST,         altivec_vmsumshm)
 BU_ALTIVEC_3 (VMSUMUHS,       "vmsumuhs",       SAT,           altivec_vmsumuhs)
 BU_ALTIVEC_3 (VMSUMSHS,       "vmsumshs",       SAT,           altivec_vmsumshs)
@@ -1499,6 +1500,7 @@ BU_ALTIVEC_OVERLOAD_3 (VMSUMSHM,   "vmsumshm")
 BU_ALTIVEC_OVERLOAD_3 (VMSUMSHS,   "vmsumshs")
 BU_ALTIVEC_OVERLOAD_3 (VMSUMUBM,   "vmsumubm")
 BU_ALTIVEC_OVERLOAD_3 (VMSUMUHM,   "vmsumuhm")
+BU_ALTIVEC_OVERLOAD_3 (VMSUMUDM,   "vmsumudm")
 BU_ALTIVEC_OVERLOAD_3 (VMSUMUHS,   "vmsumuhs")
 
 /* Altivec DST overloaded builtins.  */
index d3cf2de88780e2f9cb81af858b8b00ab9ee9b04f..8e7bb54c73d16f87c18ce2993bd19c14a71c385c 100644 (file)
@@ -3089,6 +3089,12 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
     RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V4SI },
   { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMSHM,
     RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI },
+
+  { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUDM,
+    RS6000_BTI_V1TI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, RS6000_BTI_V1TI },
+  { ALTIVEC_BUILTIN_VEC_MSUM, ALTIVEC_BUILTIN_VMSUMUDM,
+    RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V1TI },
+
   { ALTIVEC_BUILTIN_VEC_VMSUMSHM, ALTIVEC_BUILTIN_VMSUMSHM,
     RS6000_BTI_V4SI, RS6000_BTI_V8HI, RS6000_BTI_V8HI, RS6000_BTI_V4SI },
   { ALTIVEC_BUILTIN_VEC_VMSUMUHM, ALTIVEC_BUILTIN_VMSUMUHM,
index ecd3661d257107604de10fd49e7bdc9e1568a8bd..3f92171a3b1fb956521e52a0b758fef37f79611f 100644 (file)
@@ -20218,6 +20218,13 @@ bool scalar_test_data_class (__ieee128 source, const int condition);
 bool scalar_test_neg (float source);
 bool scalar_test_neg (double source);
 bool scalar_test_neg (__ieee128 source);
+
+vector _uint128_t vec_msum (vector unsigned long long,
+                           vector unsigned long long,
+                           vector _uint128_t);
+vector _int128_t vec_msum (vector signed long long,
+                          vector signed long long,
+                          vector _int128_t);
 @end smallexample
 
 The @code{scalar_extract_exp} and @code{scalar_extract_sig}
@@ -20237,6 +20244,9 @@ Note that the sign of the significand is not represented in the result
 returned from the @code{scalar_extract_sig} function.  Use the
 @code{scalar_test_neg} function to test the sign of its @code{double}
 argument.
+The @code{vec_msum} functions perform a vector multiply-sum, returning
+the result of arg1*arg2+arg3.  ISA 3.0 adds support for vec_msum returning
+a vector int128 result.
 
 The @code{scalar_insert_exp}
 functions require a 64-bit environment supporting ISA 3.0 or later.
diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-msum-runnable.c b/gcc/testsuite/gcc.target/powerpc/builtins-msum-runnable.c
new file mode 100644 (file)
index 0000000..0fa5c31
--- /dev/null
@@ -0,0 +1,74 @@
+/* { dg-do run { target { p9vector_hw } } } */
+/* { dg-options "-mdejagnu-cpu=power9 -O2" } */
+
+#include <altivec.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+void abort (void);
+
+int
+main()
+{
+  vector __uint128_t arg_uint128, result_uint128, expected_uint128;
+  vector __int128_t arg_int128, result_int128, expected_int128;
+
+  arg_uint128[0] = 0x1627384950617243;
+  arg_uint128[0] = arg_uint128[0] << 64;
+  arg_uint128[0] |= 0x9405182930415263;
+  expected_uint128[0] = 0x1627384950617243;
+  expected_uint128[0] = expected_uint128[0] << 64;
+  expected_uint128[0] |= 0xb6b07e42a570e5fe;
+  vector unsigned long long arg_vull2 = {0x12345678,0x44445555};
+  vector unsigned long long arg_vull3 = {0x6789abcd,0x66667777};
+  result_uint128 = vec_msum (arg_vull2, arg_vull3, arg_uint128);
+
+  if (result_uint128[0] != expected_uint128[0])
+    {
+#ifdef DEBUG
+       printf("result_uint128[0] doesn't match expected_u128[0]\n");
+       printf("arg_vull2  %llx %llx \n",  arg_vull2[0], arg_vull2[1]);
+       printf("arg_vull3  %llx %llx \n",  arg_vull3[0], arg_vull3[1]);
+       printf("arg_uint128[0] =  %llx ", arg_uint128[0] >> 64);
+       printf(" %llx\n",        arg_uint128[0] & 0xFFFFFFFFFFFFFFFF);
+
+       printf("result_uint128[0] =  %llx ", result_uint128[0] >> 64);
+       printf(" %llx\n", result_uint128[0] & 0xFFFFFFFFFFFFFFFF);
+
+       printf("expected_uint128[0] =  %llx ", expected_uint128[0] >> 64);
+       printf(" %llx\n", expected_uint128[0] & 0xFFFFFFFFFFFFFFFF);
+#else
+       abort();
+#endif
+    }
+
+  arg_int128[0] = 0x1627384950617283;
+  arg_int128[0] = arg_int128[0] << 64;
+  arg_int128[0] |= 0x9405182930415263;
+  expected_int128[0] = 0x1627384950617283;
+  expected_int128[0] = expected_int128[0] << 64;
+  expected_int128[0] |= 0xd99f35969c11cbfa;
+  vector signed long long arg_vll2 = { 0x567890ab, 0x1233456 };
+  vector signed long long arg_vll3 = { 0xcdef0123, 0x9873451 };
+  result_int128 = vec_msum (arg_vll2, arg_vll3, arg_int128);
+
+  if (result_int128[0] != expected_int128[0])
+    {
+#ifdef DEBUG
+       printf("result_int128[0] doesn't match expected128[0]\n");
+       printf("arg_int128[0] =  %llx ", arg_int128[0] >> 64);
+       printf(" %llx\n",        arg_int128[0] & 0xFFFFFFFFFFFFFFFF);
+
+       printf("result_int128[0] =  %llx ", result_int128[0] >> 64);
+       printf(" %llx\n", result_int128[0] & 0xFFFFFFFFFFFFFFFF);
+
+       printf("expected_int128[0] =  %llx ", expected_int128[0] >> 64);
+       printf(" %llx\n", expected_int128[0] & 0xFFFFFFFFFFFFFFFF);
+#else
+       abort();
+#endif
+    }
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-builtin-msum.c b/gcc/testsuite/gcc.target/powerpc/vsx-builtin-msum.c
new file mode 100644 (file)
index 0000000..058ca0b
--- /dev/null
@@ -0,0 +1,26 @@
+/* Verify that overloaded built-ins for vec_msum with __int128
+   inputs generate the proper code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-require-effective-target int128 } */
+/* { dg-options "-mdejagnu-cpu=power9  -O3" } */
+
+#include <altivec.h>
+
+vector signed __int128
+test_msum_si (vector signed long long vsll_1, vector signed long long vsll_2,
+          vector signed __int128 vsi128)
+{
+  return vec_msum (vsll_1, vsll_2, vsi128);
+}
+
+vector unsigned __int128
+test_msum_ui (vector unsigned long long vull_1, vector unsigned long long vull_2,
+          vector unsigned __int128 vui128)
+{
+  return vec_msum (vull_1, vull_2, vui128);
+}
+
+/* { dg_final { scan_assembler_times "vmsumudm" 2 } } */
+