From: Michael Meissner Date: Wed, 3 Jan 2018 02:38:09 +0000 (+0000) Subject: rs6000.md (floor2): Add support for IEEE 128-bit round to integer instructions. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2d71e7b8d45597f9905580cf645dbe047385cb13;p=gcc.git rs6000.md (floor2): Add support for IEEE 128-bit round to integer instructions. [gcc] 2018-01-02 Michael Meissner * config/rs6000/rs6000.md (floor2): Add support for IEEE 128-bit round to integer instructions. (ceil2): Likewise. (btrunc2): Likewise. (round2): Likewise. [gcc/testsuite] 2018-01-02 Michael Meissner * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b9775434b70..4dd3e4c7974 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-01-02 Michael Meissner + + * config/rs6000/rs6000.md (floor2): Add support for IEEE + 128-bit round to integer instructions. + (ceil2): Likewise. + (btrunc2): Likewise. + (round2): Likewise. + 2018-01-02 Aaron Sawdey * config/rs6000/rs6000-string.c (expand_block_move): Allow the use of diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 2c310d7cf58..531b1eedaca 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -14777,6 +14777,47 @@ (set_attr "type" "vecfloat") (set_attr "size" "128")]) +;; IEEE 128-bit round to integer built-in functions +(define_insn "floor2" + [(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)" + "xsrqpi 1,%0,%1,3" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "ceil2" + [(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)" + "xsrqpi 1,%0,%1,2" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "btrunc2" + [(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)" + "xsrqpi 1,%0,%1,1" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + +(define_insn "round2" + [(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)" + "xsrqpi 0,%0,%1,0" + [(set_attr "type" "vecfloat") + (set_attr "size" "128")]) + ;; IEEE 128-bit instructions with round to odd semantics (define_insn "add3_odd" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 684a99355a4..96a26381911 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2018-01-02 Michael Meissner + + * 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 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 index 00000000000..eb4bed60c47 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw10.c @@ -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 index 00000000000..7bd9b81427a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw11.c @@ -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 +#include +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/float128-hw2.c b/gcc/testsuite/gcc.target/powerpc/float128-hw2.c index f144360da3c..118bed62537 100644 --- a/gcc/testsuite/gcc.target/powerpc/float128-hw2.c +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw2.c @@ -14,6 +14,10 @@ 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 index 00000000000..8621bd869da --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw5.c @@ -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 index 00000000000..89bb93ce690 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw6.c @@ -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 index 00000000000..1a111a361e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw7.c @@ -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 index 00000000000..62f4eae93d1 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw8.c @@ -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 index 00000000000..ca46e151aa9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/float128-hw9.c @@ -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} } } */