From debf7618f68deed8b378beb199525d4467edb6d4 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Fri, 27 May 2016 17:31:21 +0000 Subject: [PATCH] Fix powerpc32 ceil, rint etc. on sNaN input (bug 20160). The powerpc32 versions of ceil, floor, round, trunc, rint, nearbyint and their float versions return sNaN for sNaN input when they should return qNaN. This patch fixes them to add a NaN argument to itself to quiet sNaNs before returning. The powerpc64 versions, which have the same bug, will be addressed separately. Tested for powerpc32. [BZ #20160] * sysdeps/powerpc/powerpc32/fpu/s_ceil.S (__ceil): Add NaN argument to itself before returning the result. * sysdeps/powerpc/powerpc32/fpu/s_ceilf.S (__ceilf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_floor.S (__floor): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_floorf.S (__floorf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S (__nearbyint): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S (__nearbyintf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_rint.S (__rint): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_rintf.S (__rintf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_round.S (__round): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_roundf.S (__roundf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_trunc.S (__trunc): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_truncf.S (__truncf): Likewise. --- ChangeLog | 19 +++++++++++++++++++ sysdeps/powerpc/powerpc32/fpu/s_ceil.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_ceilf.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_floor.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_floorf.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_rint.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_rintf.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_round.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_roundf.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_trunc.S | 8 +++++++- sysdeps/powerpc/powerpc32/fpu/s_truncf.S | 8 +++++++- 13 files changed, 103 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 812f0a51aba..e652a0387cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2016-05-27 Joseph Myers + + [BZ #20160] + * sysdeps/powerpc/powerpc32/fpu/s_ceil.S (__ceil): Add NaN + argument to itself before returning the result. + * sysdeps/powerpc/powerpc32/fpu/s_ceilf.S (__ceilf): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_floor.S (__floor): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_floorf.S (__floorf): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S (__nearbyint): + Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S (__nearbyintf): + Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_rint.S (__rint): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_rintf.S (__rintf): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_round.S (__round): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_roundf.S (__roundf): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_trunc.S (__trunc): Likewise. + * sysdeps/powerpc/powerpc32/fpu/s_truncf.S (__truncf): Likewise. + 2016-05-27 Paul E. Murphy * libm-test.inc: Replace usage of M_El with diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S index 07d031e22ee..161295962de 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S @@ -44,7 +44,7 @@ ENTRY (__ceil) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,2 /* Set rounding mode toward +inf. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -64,6 +64,12 @@ ENTRY (__ceil) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__ceil) weak_alias (__ceil, ceil) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S index 3987e24e41a..63ffd5f8ecb 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S @@ -43,7 +43,7 @@ ENTRY (__ceilf) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,2 /* Set rounding mode toward +inf. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -63,6 +63,12 @@ ENTRY (__ceilf) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__ceilf) weak_alias (__ceilf, ceilf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floor.S b/sysdeps/powerpc/powerpc32/fpu/s_floor.S index b951666bd7c..269e1dc8082 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floor.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floor.S @@ -44,7 +44,7 @@ ENTRY (__floor) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,3 /* Set rounding mode toward -inf. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -64,6 +64,12 @@ ENTRY (__floor) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__floor) weak_alias (__floor, floor) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S index 64b87b1cc14..642d910561c 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S @@ -43,7 +43,7 @@ ENTRY (__floorf) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,3 /* Set rounding mode toward -inf. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -63,6 +63,12 @@ ENTRY (__floorf) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__floorf) weak_alias (__floorf, floorf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S index 68e3182b0d5..fee7e9e8b04 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyint.S @@ -49,7 +49,7 @@ ENTRY (__nearbyint) fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52 */ - bgelr cr7 + bge cr7,.L10 fcmpu cr7,fp1,fp12 /* if (x > 0.0 */ ble cr7,L(lessthanzero) mffs fp11 @@ -68,6 +68,12 @@ L(lessthanzero): fnabs fp1,fp1 /* if (x == 0.0) */ mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__nearbyint) weak_alias (__nearbyint, nearbyint) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S index 107b035a248..7490e9c6d3d 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_nearbyintf.S @@ -48,7 +48,7 @@ ENTRY (__nearbyintf) fabs fp0,fp1 fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23 */ - bgelr cr7 + bge cr7,.L10 fcmpu cr7,fp1,fp12 /* if (x > 0.0 */ ble cr7,L(lessthanzero) mffs fp11 @@ -67,6 +67,12 @@ L(lessthanzero): fnabs fp1,fp1 /* if (x == 0.0) */ mtfsf 0xff,fp11 /* Restore FE_INEXACT state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__nearbyintf) weak_alias (__nearbyintf, nearbyintf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rint.S b/sysdeps/powerpc/powerpc32/fpu/s_rint.S index 5d78f3a5fcf..8124feec8d4 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rint.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rint.S @@ -45,7 +45,7 @@ ENTRY (__rint) fsub fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO52) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr cr7 + bnl cr7,.L10 bng cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ fsub fp1,fp1,fp13 /* x-= TWO52; */ @@ -57,6 +57,12 @@ ENTRY (__rint) fadd fp1,fp1,fp13 /* x+= TWO52; */ fnabs fp1,fp1 /* if (x == 0.0) */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__rint) weak_alias (__rint, rint) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S index 94b7045da6b..1fd4c2ab0f2 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S @@ -41,7 +41,7 @@ ENTRY (__rintf) fsubs fp12,fp13,fp13 /* generate 0.0 */ fcmpu cr7,fp0,fp13 /* if (fabs(x) > TWO23) */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr cr7 + bnl cr7,.L10 bng cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ fsubs fp1,fp1,fp13 /* x-= TWO23; */ @@ -53,6 +53,12 @@ ENTRY (__rintf) fadds fp1,fp1,fp13 /* x+= TWO23; */ fnabs fp1,fp1 /* if (x == 0.0) */ blr /* x = -0.0; */ +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__rintf) weak_alias (__rintf, rintf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_round.S b/sysdeps/powerpc/powerpc32/fpu/s_round.S index ae25364bd90..c224e0c2e3a 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_round.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_round.S @@ -57,7 +57,7 @@ ENTRY (__round) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding mode toward 0. */ #ifdef SHARED lfs fp10,.LC1-.LC0(r9) @@ -85,6 +85,12 @@ ENTRY (__round) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__round) weak_alias (__round, round) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S index f63248138ff..d1341c71495 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S @@ -56,7 +56,7 @@ ENTRY (__roundf ) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding mode toward 0. */ #ifdef SHARED lfs fp10,.LC1-.LC0(r9) @@ -83,6 +83,12 @@ ENTRY (__roundf ) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__roundf) weak_alias (__roundf, roundf) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S index 260b4fd336c..a4e9a2d9d62 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S @@ -51,7 +51,7 @@ ENTRY (__trunc) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding toward 0 mode. */ ble- cr6,.L4 fadd fp1,fp1,fp13 /* x+= TWO52; */ @@ -71,6 +71,12 @@ ENTRY (__trunc) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadd fp1,fp1,fp1 + blr END (__trunc) weak_alias (__trunc, trunc) diff --git a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S index 6c2c959e711..6006f1553bf 100644 --- a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S +++ b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S @@ -50,7 +50,7 @@ ENTRY (__truncf) mffs fp11 /* Save current FPU rounding mode and "inexact" state. */ fcmpu cr6,fp1,fp12 /* if (x > 0.0) */ - bnllr- cr7 + bnl- cr7,.L10 mtfsfi 7,1 /* Set rounding toward 0 mode. */ ble- cr6,.L4 fadds fp1,fp1,fp13 /* x+= TWO23; */ @@ -70,6 +70,12 @@ ENTRY (__truncf) mtfsf 0xff,fp11 /* Restore previous rounding mode and "inexact" state. */ blr +.L10: + /* Ensure sNaN input is converted to qNaN. */ + fcmpu cr7,fp1,fp1 + beqlr cr7 + fadds fp1,fp1,fp1 + blr END (__truncf) weak_alias (__truncf, truncf) -- 2.47.2