re PR target/84914 (PowerPC complex multiply/divide calls the wrong function when...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Tue, 27 Mar 2018 23:14:22 +0000 (23:14 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Tue, 27 Mar 2018 23:14:22 +0000 (23:14 +0000)
[gcc]
2018-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/84914
* config/rs6000/rs6000.c (create_complex_muldiv): New helper
function to create the function decl for complex long double
multiply and divide for -mabi=ieeelongdouble.
(init_float128_ieee): Call it.

[gcc/testsuite]
2018-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>

PR target/84914
* gcc.target/powerpc/mulkc-2.c: New tests to make sure complex
long double multiply/divide uses the correct function.
* gcc.target/powerpc/mulkc-3.c: Likewise.
* gcc.target/powerpc/divkc-2.c: Likewise.
* gcc.target/powerpc/divkc-3.c: Likewise.

From-SVN: r258908

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/divkc3-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/divkc3-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/mulkc3-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/mulkc3-3.c [new file with mode: 0644]

index a07d2ff7838d9ed47d73fa1e5d76829b27d469e8..69b715eb099e0ff2e145adf54bf3076dbca3b0a0 100644 (file)
@@ -1,3 +1,11 @@
+2018-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/84914
+       * config/rs6000/rs6000.c (create_complex_muldiv): New helper
+       function to create the function decl for complex long double
+       multiply and divide for -mabi=ieeelongdouble.
+       (init_float128_ieee): Call it.
+
 2018-03-27  H.J. Lu  <hongjiu.lu@intel.com>
 
        PR target/85044
index 1fe8b9ac53f7dc30ece27b08c62d1f7339e43508..37c55f43c56df500745cbc07193e259484e4648c 100644 (file)
@@ -18561,6 +18561,26 @@ init_float128_ibm (machine_mode mode)
     }
 }
 
+/* Create a decl for either complex long double multiply or complex long double
+   divide when long double is IEEE 128-bit floating point.  We can't use
+   __multc3 and __divtc3 because the original long double using IBM extended
+   double used those names.  The complex multiply/divide functions are encoded
+   as builtin functions with a complex result and 4 scalar inputs.  */
+
+static void
+create_complex_muldiv (const char *name, built_in_function fncode, tree fntype)
+{
+  tree fndecl = add_builtin_function (name, fntype, fncode, BUILT_IN_NORMAL,
+                                     name, NULL_TREE);
+
+  set_builtin_decl (fncode, fndecl, true);
+
+  if (TARGET_DEBUG_BUILTIN)
+    fprintf (stderr, "create complex %s, fncode: %d\n", name, (int) fncode);
+
+  return;
+}
+
 /* Set up IEEE 128-bit floating point routines.  Use different names if the
    arguments can be passed in a vector register.  The historical PowerPC
    implementation of IEEE 128-bit floating point used _q_<op> for the names, so
@@ -18572,6 +18592,27 @@ init_float128_ieee (machine_mode mode)
 {
   if (FLOAT128_VECTOR_P (mode))
     {
+      /* Set up to call __mulkc3 and __divkc3 under -mabi=ieeelongdouble.  */
+     if (mode == TFmode && TARGET_IEEEQUAD)
+       {
+        built_in_function fncode_mul =
+          (built_in_function) (BUILT_IN_COMPLEX_MUL_MIN + TCmode
+                               - MIN_MODE_COMPLEX_FLOAT);
+        built_in_function fncode_div =
+          (built_in_function) (BUILT_IN_COMPLEX_DIV_MIN + TCmode
+                               - MIN_MODE_COMPLEX_FLOAT);
+
+        tree fntype = build_function_type_list (complex_long_double_type_node,
+                                                long_double_type_node,
+                                                long_double_type_node,
+                                                long_double_type_node,
+                                                long_double_type_node,
+                                                NULL_TREE);
+
+        create_complex_muldiv ("__mulkc3", fncode_mul, fntype);
+        create_complex_muldiv ("__divkc3", fncode_div, fntype);
+       }
+
       set_optab_libfunc (add_optab, mode, "__addkf3");
       set_optab_libfunc (sub_optab, mode, "__subkf3");
       set_optab_libfunc (neg_optab, mode, "__negkf2");
index 4c2298024c27c4292b82da531499fdd701260f2e..b195bd77bf5809db653e10a1797481ea7a3c92b1 100644 (file)
@@ -1,3 +1,12 @@
+2018-03-27  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       PR target/84914
+       * gcc.target/powerpc/mulkc-2.c: New tests to make sure complex
+       long double multiply/divide uses the correct function.
+       * gcc.target/powerpc/mulkc-3.c: Likewise.
+       * gcc.target/powerpc/divkc-2.c: Likewise.
+       * gcc.target/powerpc/divkc-3.c: Likewise.
+
 2018-03-27  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/85067
diff --git a/gcc/testsuite/gcc.target/powerpc/divkc3-2.c b/gcc/testsuite/gcc.target/powerpc/divkc3-2.c
new file mode 100644 (file)
index 0000000..d3fcbed
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mpower8-vector -mabi=ieeelongdouble -Wno-psabi" } */
+
+/* Check that complex multiply generates the right call when long double is
+   IEEE 128-bit floating point.  */
+
+typedef _Complex long double cld_t;
+
+void
+divide (cld_t *p, cld_t *q, cld_t *r)
+{
+  *p = *q / *r;
+}
+
+/* { dg-final { scan-assembler "bl __divkc3" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/divkc3-3.c b/gcc/testsuite/gcc.target/powerpc/divkc3-3.c
new file mode 100644 (file)
index 0000000..45695fe
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mpower8-vector -mabi=ibmlongdouble -Wno-psabi" } */
+
+/* Check that complex multiply generates the right call when long double is
+   IBM extended double floating point.  */
+
+typedef _Complex long double cld_t;
+
+void
+divide (cld_t *p, cld_t *q, cld_t *r)
+{
+  *p = *q / *r;
+}
+
+/* { dg-final { scan-assembler "bl __divtc3" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mulkc3-2.c b/gcc/testsuite/gcc.target/powerpc/mulkc3-2.c
new file mode 100644 (file)
index 0000000..9ba577a
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mpower8-vector -mabi=ieeelongdouble -Wno-psabi" } */
+
+/* Check that complex multiply generates the right call when long double is
+   IEEE 128-bit floating point.  */
+
+typedef _Complex long double cld_t;
+
+void
+multiply (cld_t *p, cld_t *q, cld_t *r)
+{
+  *p = *q * *r;
+}
+
+/* { dg-final { scan-assembler "bl __mulkc3" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/mulkc3-3.c b/gcc/testsuite/gcc.target/powerpc/mulkc3-3.c
new file mode 100644 (file)
index 0000000..db87301
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-O2 -mpower8-vector -mabi=ibmlongdouble -Wno-psabi" } */
+
+/* Check that complex multiply generates the right call when long double is
+   IBM extended double floating point.  */
+
+typedef _Complex long double cld_t;
+
+void
+multiply (cld_t *p, cld_t *q, cld_t *r)
+{
+  *p = *q * *r;
+}
+
+/* { dg-final { scan-assembler "bl __multc3" } } */