Submitter | Adhemerval Zanella Netto |
---|---|

Date | Jan. 3, 2018, 6:03 p.m. |

Message ID | <1515002624-26820-1-git-send-email-adhemerval.zanella@linaro.org> |

Download | mbox | patch |

Permalink | /patch/25194/ |

State | New |

Headers | show |

## Comments

On 01/03/2018 10:03 AM, Adhemerval Zanella wrote: > As discussed in libc-alpha [1], alpha ceil{f} and floor{f} > implementation uses cvttq/svm and although the Alpha Architecture > Handbook version 3 states that that CVTfi OUTPUT Exceptions > (B.3 Mapping to IEEE Standard) should not generate Inexact if INE > bit is set on fpcr, the Alpha 21264 [1] chip manual (A.8 IEEE > Floating-Point Conformance) states that CVTfi and CVTif OUTPUT > does generate inexact exception for inexact result regardless. > > As Joseph noted [2] to correctly fix it on alpha we need to either > avoid the instruction or avoid any inexact bit from it being set > on return from the function (while preserving the inexact bit that > might be set on the entry to the function). The later will result > mf_fpcr followed by a mt_fpcr to get and set the fpcr which will > defeat the optimization itself. > > So the patch just remove the alpha optimized and rely on generic > implementation. It fixes the math/test-*-{ceil,floor} on alpha. > > [BZ #15479] > [BZ #22665] > * sysdeps/alpha/fpu/s_ceil.c: Remove file. > * sysdeps/alpha/fpu/s_ceilf.c: Likewise. > * sysdeps/alpha/fpu/s_floor.c: Likewise. > * sysdeps/alpha/fpu/s_floorf.c: Likewise. ACK. r~

## Patch

diff --git a/sysdeps/alpha/fpu/s_ceil.c b/sysdeps/alpha/fpu/s_ceil.c deleted file mode 100644 index 16c8f99..0000000 --- a/sysdeps/alpha/fpu/s_ceil.c +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 1998-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> -#include <math_ldbl_opt.h> -#include <libm-alias-double.h> - -/* Use the -inf rounding mode conversion instructions to implement - ceil, via something akin to -floor(-x). This is much faster than - playing with the fpcr to achieve +inf rounding mode. */ - -double -__ceil (double x) -{ - if (isnan (x)) - return x + x; - - if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ - { - double tmp1, new_x; - - new_x = -x; - __asm ( - "cvttq/svm %2,%1\n\t" - "cvtqt/m %1,%0\n\t" - : "=f"(new_x), "=&f"(tmp1) - : "f"(new_x)); - - /* Fix up the negation we did above, as well as handling -0 properly. */ - x = copysign(new_x, x); - } - return x; -} - -libm_alias_double (__ceil, ceil) diff --git a/sysdeps/alpha/fpu/s_ceilf.c b/sysdeps/alpha/fpu/s_ceilf.c deleted file mode 100644 index 8561232..0000000 --- a/sysdeps/alpha/fpu/s_ceilf.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright (C) 1998-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> -#include <libm-alias-float.h> - -/* Use the -inf rounding mode conversion instructions to implement - ceil, via something akin to -floor(-x). This is much faster than - playing with the fpcr to achieve +inf rounding mode. */ - -float -__ceilf (float x) -{ - if (isnanf (x)) - return x + x; - - if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ - { - /* Note that Alpha S_Floating is stored in registers in a - restricted T_Floating format, so we don't even need to - convert back to S_Floating in the end. The initial - conversion to T_Floating is needed to handle denormals. */ - - float tmp1, tmp2, new_x; - - new_x = -x; - __asm ("cvtst/s %3,%2\n\t" - "cvttq/svm %2,%1\n\t" - "cvtqt/m %1,%0\n\t" - : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) - : "f"(new_x)); - - /* Fix up the negation we did above, as well as handling -0 properly. */ - x = copysignf(new_x, x); - } - return x; -} - -libm_alias_float (__ceil, ceil) diff --git a/sysdeps/alpha/fpu/s_floor.c b/sysdeps/alpha/fpu/s_floor.c deleted file mode 100644 index 285ad36..0000000 --- a/sysdeps/alpha/fpu/s_floor.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright (C) 1998-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> -#include <math_ldbl_opt.h> -#include <libm-alias-double.h> - - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - -double -__floor (double x) -{ - if (isnan (x)) - return x + x; - - if (isless (fabs (x), 9007199254740992.0)) /* 1 << DBL_MANT_DIG */ - { - double tmp1, new_x; - - __asm ( - "cvttq/svm %2,%1\n\t" - "cvtqt/m %1,%0\n\t" - : "=f"(new_x), "=&f"(tmp1) - : "f"(x)); - - /* floor(-0) == -0, and in general we'll always have the same - sign as our input. */ - x = copysign(new_x, x); - } - return x; -} - -libm_alias_double (__floor, floor) diff --git a/sysdeps/alpha/fpu/s_floorf.c b/sysdeps/alpha/fpu/s_floorf.c deleted file mode 100644 index a73b3fd..0000000 --- a/sysdeps/alpha/fpu/s_floorf.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 1998-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Richard Henderson. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - <http://www.gnu.org/licenses/>. */ - -#include <math.h> -#include <libm-alias-float.h> - - -/* Use the -inf rounding mode conversion instructions to implement - floor. We note when the exponent is large enough that the value - must be integral, as this avoids unpleasant integer overflows. */ - -float -__floorf (float x) -{ - if (isnanf (x)) - return x + x; - - if (isless (fabsf (x), 16777216.0f)) /* 1 << FLT_MANT_DIG */ - { - /* Note that Alpha S_Floating is stored in registers in a - restricted T_Floating format, so we don't even need to - convert back to S_Floating in the end. The initial - conversion to T_Floating is needed to handle denormals. */ - - float tmp1, tmp2, new_x; - - __asm ("cvtst/s %3,%2\n\t" - "cvttq/svm %2,%1\n\t" - "cvtqt/m %1,%0\n\t" - : "=f"(new_x), "=&f"(tmp1), "=&f"(tmp2) - : "f"(x)); - - /* floor(-0) == -0, and in general we'll always have the same - sign as our input. */ - x = copysignf(new_x, x); - } - return x; -} - -libm_alias_float (__floor, floor)