aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meissner <meissner@linux.vnet.ibm.com>2018-03-27 23:14:22 +0000
committerMichael Meissner <meissner@gcc.gnu.org>2018-03-27 23:14:22 +0000
commit566a2fa7e8b3f71c974e034c2b4c33e497c89a29 (patch)
tree066f92cc658234d41fc2b5d288f707c43ab03827
parentfc5dbf7c5449e918cb5570d6edd861fe618830d3 (diff)
downloadgcc-566a2fa7e8b3f71c974e034c2b4c33e497c89a29.zip
gcc-566a2fa7e8b3f71c974e034c2b4c33e497c89a29.tar.gz
gcc-566a2fa7e8b3f71c974e034c2b4c33e497c89a29.tar.bz2
re PR target/84914 (PowerPC complex multiply/divide calls the wrong function when -mabi=ieeelongdouble)
[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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/rs6000/rs6000.c41
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.target/powerpc/divkc3-2.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/divkc3-3.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mulkc3-2.c16
-rw-r--r--gcc/testsuite/gcc.target/powerpc/mulkc3-3.c16
7 files changed, 122 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a07d2ff..69b715e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1fe8b9a..37c55f4 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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");
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4c22980..b195bd7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..d3fcbed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/divkc3-2.c
@@ -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
index 0000000..45695fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/divkc3-3.c
@@ -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
index 0000000..9ba577a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mulkc3-2.c
@@ -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
index 0000000..db87301
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/mulkc3-3.c
@@ -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" } } */