rs6000.md (floor<mode>2): Add support for IEEE 128-bit round to integer instructions.
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Wed, 3 Jan 2018 02:38:09 +0000 (02:38 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 3 Jan 2018 02:38:09 +0000 (02:38 +0000)
[gcc]
2018-01-02  Michael Meissner  <meissner@linux.vnet.ibm.com>

* config/rs6000/rs6000.md (floor<mode>2): Add support for IEEE
128-bit round to integer instructions.
(ceil<mode>2): Likewise.
(btrunc<mode>2): Likewise.
(round<mode>2): Likewise.

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

* gcc.target/powerpc/float128-hw2.c: Add tests for ceilf128,
floorf128, truncf128, and roundf128.
* gcc.target/powerpc/float128-hw5.c: New tests for _Float128
optimizations added in match.pd.
* gcc.target/powerpc/float128-hw6.c: Likewise.
* gcc.target/powerpc/float128-hw7.c: Likewise.
* gcc.target/powerpc/float128-hw8.c: Likewise.
* gcc.target/powerpc/float128-hw9.c: Likewise.
* gcc.target/powerpc/float128-hw10.c: Likewise.
* gcc.target/powerpc/float128-hw11.c: Likewise.

From-SVN: r256118

gcc/ChangeLog
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/float128-hw10.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw11.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw2.c
gcc/testsuite/gcc.target/powerpc/float128-hw5.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw6.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw7.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw8.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/float128-hw9.c [new file with mode: 0644]

index b9775434b700706a7d8b288b467bbcea36291165..4dd3e4c79746593b0035454254776e6897e07d67 100644 (file)
@@ -1,3 +1,11 @@
+2018-01-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * config/rs6000/rs6000.md (floor<mode>2): Add support for IEEE
+       128-bit round to integer instructions.
+       (ceil<mode>2): Likewise.
+       (btrunc<mode>2): Likewise.
+       (round<mode>2): Likewise.
+
 2018-01-02  Aaron Sawdey  <acsawdey@linux.vnet.ibm.com>
 
         * config/rs6000/rs6000-string.c (expand_block_move): Allow the use of
index 2c310d7cf58f9d51c24be702fb465620c9a74b9f..531b1eedacadeef81990967dd560d16be4b63749 100644 (file)
    (set_attr "type" "vecfloat")
    (set_attr "size" "128")])
 
+;; IEEE 128-bit round to integer built-in functions
+(define_insn "floor<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128
+        [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+        UNSPEC_FRIM))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,3"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "ceil<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128
+        [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+        UNSPEC_FRIP))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,2"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "btrunc<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128
+        [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+        UNSPEC_FRIZ))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 1,%0,%1,1"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
+(define_insn "round<mode>2"
+  [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
+       (unspec:IEEE128
+        [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
+        UNSPEC_FRIN))]
+  "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
+  "xsrqpi 0,%0,%1,0"
+  [(set_attr "type" "vecfloat")
+   (set_attr "size" "128")])
+
 ;; IEEE 128-bit instructions with round to odd semantics
 (define_insn "add<mode>3_odd"
   [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
index 684a99355a4ab7b394504212fa7fd16bba0219ac..96a263819117c1dd5174dc0e4ad58a5327b219c2 100644 (file)
@@ -1,3 +1,16 @@
+2018-01-02  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/float128-hw2.c: Add tests for ceilf128,
+       floorf128, truncf128, and roundf128.
+       * gcc.target/powerpc/float128-hw5.c: New tests for _Float128
+       optimizations added in match.pd.
+       * gcc.target/powerpc/float128-hw6.c: Likewise.
+       * gcc.target/powerpc/float128-hw7.c: Likewise.
+       * gcc.target/powerpc/float128-hw8.c: Likewise.
+       * gcc.target/powerpc/float128-hw9.c: Likewise.
+       * gcc.target/powerpc/float128-hw10.c: Likewise.
+       * gcc.target/powerpc/float128-hw11.c: Likewise.
+
 2018-01-02  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/83556
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw10.c b/gcc/testsuite/gcc.target/powerpc/float128-hw10.c
new file mode 100644 (file)
index 0000000..eb4bed6
--- /dev/null
@@ -0,0 +1,38 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 floorf128 (_Float128);
+extern _Float128 ceilf128 (_Float128);
+extern _Float128 roundf128 (_Float128);
+extern _Float128 truncf128 (_Float128);
+
+/* Check rounding optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+floor_floor_x (_Float128 x)
+{
+  return floorf128 (floorf128 (x));
+}
+
+_Float128
+ceil_ceil_x (_Float128 x)
+{
+  return ceilf128 (ceilf128 (x));
+}
+
+_Float128
+trunc_trunc_x (_Float128 x)
+{
+  return truncf128 (truncf128 (x));
+}
+
+_Float128
+round_round_x (_Float128 x)
+{
+  return roundf128 (roundf128 (x));
+}
+
+/* { dg-final { scan-assembler-times {\mxsrqpi\M} 4 } } */
+/* { dg-final { scan-assembler-not   {\mbl\M}       } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw11.c b/gcc/testsuite/gcc.target/powerpc/float128-hw11.c
new file mode 100644 (file)
index 0000000..7bd9b81
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do run { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target p9vector_hw } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1
+#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1
+
+#include <math.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+extern _Float128 roundf128 (_Float128);
+extern _Float128 floorf128 (_Float128);
+extern _Float128 ceilf128  (_Float128);
+extern _Float128 truncf128 (_Float128);
+
+static const struct {
+  _Float128 value;
+  _Float128 exp_round;
+  _Float128 exp_floor;
+  _Float128 exp_ceil;
+  _Float128 exp_trunc;
+} a[] = {
+  { -2.0Q, -2.0Q, -2.0Q, -2.0Q, -2.0Q },
+  { -1.7Q, -2.0Q, -2.0Q, -1.0Q, -1.0Q },
+  { -1.5Q, -2.0Q, -2.0Q, -1.0Q, -1.0Q },
+  { -1.3Q, -1.0Q, -2.0Q, -1.0Q, -1.0Q },
+  { +0.0Q, +0.0Q, +0.0Q, +0.0Q, +0.0Q },
+  { +1.3Q, +1.0Q, +1.0Q, +2.0Q, +1.0Q },
+  { +1.5Q, +2.0Q, +1.0Q, +2.0Q, +1.0Q },
+  { +1.7Q, +2.0Q, +1.0Q, +2.0Q, +1.0Q },
+  { +2.0Q, +2.0Q, +2.0Q, +2.0Q, +2.0Q }
+};
+
+int
+main (void)
+{
+  size_t i;
+  _Float128 v;
+
+  for (i = 0; i < sizeof (a) / sizeof (a[0]); i++)
+    {
+      v = a[i].value;
+      if (roundf128 (v) != a[i].exp_round)
+       abort ();
+
+      if (floorf128 (v) != a[i].exp_floor)
+       abort ();
+
+      if (ceilf128 (v) != a[i].exp_ceil)
+       abort ();
+
+      if (truncf128 (v) != a[i].exp_trunc)
+       abort ();
+    }
+
+  return 0;
+}
index f144360da3cba6fe5fe24d2afa466033eb5e6d37..118bed625375d2e81143121918cd2c294072a10f 100644 (file)
 extern _Float128 copysignf128 (_Float128, _Float128);
 extern _Float128 sqrtf128 (_Float128);
 extern _Float128 fmaf128 (_Float128, _Float128, _Float128);
+extern _Float128 ceilf128 (_Float128);
+extern _Float128 floorf128 (_Float128);
+extern _Float128 truncf128 (_Float128);
+extern _Float128 roundf128 (_Float128);
 
 _Float128
 do_copysign (_Float128 a, _Float128 b)
@@ -51,10 +55,35 @@ do_nfms (_Float128 a, _Float128 b, _Float128 c)
   return -fmaf128 (a, b, -c);
 }
 
+_Float128
+do_ceil (_Float128 a)
+{
+  return ceilf128 (a);
+}
+
+_Float128
+do_floor (_Float128 a)
+{
+  return floorf128 (a);
+}
+
+_Float128
+do_trunc (_Float128 a)
+{
+  return truncf128 (a);
+}
+
+_Float128
+do_round (_Float128 a)
+{
+  return roundf128 (a);
+}
+
 /* { dg-final { scan-assembler     {\mxscpsgnqp\M} } } */
 /* { dg-final { scan-assembler     {\mxssqrtqp\M}  } } */
 /* { dg-final { scan-assembler     {\mxsmaddqp\M}  } } */
 /* { dg-final { scan-assembler     {\mxsmsubqp\M}  } } */
 /* { dg-final { scan-assembler     {\mxsnmaddqp\M} } } */
 /* { dg-final { scan-assembler     {\mxsnmsubqp\M} } } */
+/* { dg-final { scan-assembler     {\mxsrqpi\M}    } } */
 /* { dg-final { scan-assembler-not {\mbl\M}        } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw5.c b/gcc/testsuite/gcc.target/powerpc/float128-hw5.c
new file mode 100644 (file)
index 0000000..8621bd8
--- /dev/null
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
+
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+x_times_cs_one_negx (_Float128 x)
+{
+  return x * copysignf128 (1.0Q, -x);  /* XSNABSQP  */
+}
+
+_Float128
+x_times_cs_one_x (_Float128 x)
+{
+  return x * copysignf128 (1.0Q, x);   /* XSABSQP  */
+}
+
+_Float128
+cs_x_x (_Float128 x)
+{
+  return copysignf128 (x, x);          /* no operation.  */
+}
+
+/* { dg-final { scan-assembler-times {\mxsabsqp\M}  1 } } */
+/* { dg-final { scan-assembler-times {\mxsnabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-not   {\mxscpsgnqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mlxvx\M}       } } */
+/* { dg-final { scan-assembler-not   {\mlxv\M}        } } */
+/* { dg-final { scan-assembler-not   {\mbl\M}         } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw6.c b/gcc/testsuite/gcc.target/powerpc/float128-hw6.c
new file mode 100644 (file)
index 0000000..89bb93c
--- /dev/null
@@ -0,0 +1,26 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fabsf128 (_Float128);
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+cs_negx_y (_Float128 x, _Float128 y)
+{
+  return copysignf128 (-x, y);                 /* eliminate negation.  */
+}
+
+_Float128
+cs_absx_y (_Float128 x, _Float128 y)
+{
+  return copysignf128 (fabsf128 (x), y);       /* eliminate fabsf128.  */
+}
+
+/* { dg-final { scan-assembler-times {\mxscpsgnqp\M} 2 } } */
+/* { dg-final { scan-assembler-not   {\mxsnegqp\M}     } } */
+/* { dg-final { scan-assembler-not   {\mxsabsqp\M}     } } */
+/* { dg-final { scan-assembler-not   {\mbl\M}          } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw7.c b/gcc/testsuite/gcc.target/powerpc/float128-hw7.c
new file mode 100644 (file)
index 0000000..1a111a3
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fabsf128 (_Float128);
+extern _Float128 copysignf128 (_Float128, _Float128);
+
+/* Check copysign optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+cs_x_pos1 (_Float128 x)
+{
+  return copysignf128 (x, 1.0Q);               /* XSABSQP.  */
+}
+
+_Float128 cs_x_neg2 (_Float128 x)
+{
+  return copysignf128 (x, -2.0Q);              /* XSNABSQP.  */
+}
+
+/* { dg-final { scan-assembler-times {\mxsabsqp\M}  1 } } */
+/* { dg-final { scan-assembler-not   {\mxsnabsqp\M} 1 } } */
+/* { dg-final { scan-assembler-not   {\mxscpsgnqp\M}  } } */
+/* { dg-final { scan-assembler-not   {\mlxvx\M}       } } */
+/* { dg-final { scan-assembler-not   {\mlxv\M}        } } */
+/* { dg-final { scan-assembler-not   {\mbl\M}         } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw8.c b/gcc/testsuite/gcc.target/powerpc/float128-hw8.c
new file mode 100644 (file)
index 0000000..62f4eae
--- /dev/null
@@ -0,0 +1,24 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2" } */
+
+extern _Float128 fminf128 (_Float128, _Float128);
+extern _Float128 fmaxf128 (_Float128, _Float128);
+
+/* Check min/max optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+min_x_x (_Float128 x)
+{
+  return fminf128 (x, x);
+}
+
+_Float128
+max_x_x (_Float128 x)
+{
+  return fmaxf128 (x, x);
+}
+
+/* { dg-final { scan-assembler-not {\mxscmpuqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}       } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw9.c b/gcc/testsuite/gcc.target/powerpc/float128-hw9.c
new file mode 100644 (file)
index 0000000..ca46e15
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-mpower9-vector -O2 -ffast-math" } */
+
+extern _Float128 sqrtf128 (_Float128);
+
+/* Check sqrt optimizations that are done for double are also done for
+   _Float128.  */
+
+_Float128
+sqrt_x_times_sqrt_x (_Float128 x)
+{
+  return sqrtf128 (x) * sqrtf128 (x);
+}
+
+/* { dg-final { scan-assembler-not {\mxssqrtqp\M} } } */
+/* { dg-final { scan-assembler-not {\mbl\M}       } } */