rs6000.md (floor<mode>2): Add support for IEEE 128-bit round to integer instructions.

[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
This commit is contained in:
Michael Meissner 2018-01-03 02:38:09 +00:00 committed by Michael Meissner
parent 50d75500a3
commit 2d71e7b8d4
11 changed files with 314 additions and 0 deletions

View 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

View file

@ -14777,6 +14777,47 @@
(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")

View 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

View file

@ -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} } } */

View file

@ -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;
}

View file

@ -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} } } */

View file

@ -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} } } */

View file

@ -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} } } */

View file

@ -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} } } */

View file

@ -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} } } */

View file

@ -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} } } */