From a8e3bad42b9636e20442b52a3924c914dc34dd82 Mon Sep 17 00:00:00 2001 From: "Kaveh R. Ghazi" Date: Sun, 26 Nov 2006 14:35:54 +0000 Subject: [PATCH] builtins.c (fold_builtin_fmin_fmax): Handle NaN arguments. * builtins.c (fold_builtin_fmin_fmax): Handle NaN arguments. testsuite: * gcc.dg/torture/builtin-minmax-1.c: Test NaN in fmin/fmax. Don't ever inline the testcase. From-SVN: r119224 --- gcc/ChangeLog | 4 +++ gcc/builtins.c | 14 +++++++++++ gcc/testsuite/ChangeLog | 5 ++++ .../gcc.dg/torture/builtin-minmax-1.c | 25 ++++++++++++++++++- 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c04d5c02af8..274c862f3be 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2006-11-26 Kaveh R. Ghazi + + * builtins.c (fold_builtin_fmin_fmax): Handle NaN arguments. + 2006-11-26 Razya Ladklesky * testsuite/gcc.dg/ipa/ipa-6.c: New. diff --git a/gcc/builtins.c b/gcc/builtins.c index 75b47fb2391..b2964ded296 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -8734,6 +8734,20 @@ fold_builtin_fmin_fmax (tree arglist, tree type, bool max) if (res) return res; + /* If either argument is NaN, return the other one. Avoid the + transformation if we get (and honor) a signalling NaN. Using + omit_one_operand() ensures we create a non-lvalue. */ + if (TREE_CODE (arg0) == REAL_CST + && real_isnan (&TREE_REAL_CST (arg0)) + && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg0))) + || ! TREE_REAL_CST (arg0).signalling)) + return omit_one_operand (type, arg1, arg0); + if (TREE_CODE (arg1) == REAL_CST + && real_isnan (&TREE_REAL_CST (arg1)) + && (! HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1))) + || ! TREE_REAL_CST (arg1).signalling)) + return omit_one_operand (type, arg0, arg1); + /* Transform fmin/fmax(x,x) -> x. */ if (operand_equal_p (arg0, arg1, OEP_PURE_SAME)) return omit_one_operand (type, arg0, arg1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 71752094394..3adde52429f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-11-26 Kaveh R. Ghazi + + * gcc.dg/torture/builtin-minmax-1.c: Test NaN in fmin/fmax. + Don't ever inline the testcase. + 2006-11-25 Andrew Pinski PR fortran/29982 diff --git a/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c b/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c index 280d3564e37..4948aa9e004 100644 --- a/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c +++ b/gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c @@ -74,7 +74,25 @@ extern int pure(int) __attribute__ ((__pure__)); link_error(__LINE__); \ } while (0) -void foo (float xf, double x, long double xl, +/* Test that FUNC(NaN,x) == x. We cast to (long) so "!=" folds. Set + parameter SIGNAL to `s' for testing signaling NaN. */ +#define TEST_NAN(FUNC,SIGNAL) do { \ + if ((long)FUNC##f(__builtin_nan##SIGNAL##f(""),xf) != (long)xf) \ + link_error(__LINE__); \ + if ((long)FUNC##f(xf,__builtin_nan##SIGNAL##f("")) != (long)xf) \ + link_error(__LINE__); \ + if ((long)FUNC(__builtin_nan##SIGNAL(""),x) != (long)x) \ + link_error(__LINE__); \ + if ((long)FUNC(x,__builtin_nan##SIGNAL("")) != (long)x) \ + link_error(__LINE__); \ + if ((long)FUNC##l(__builtin_nan##SIGNAL##l(""),xl) != (long)xl) \ + link_error(__LINE__); \ + if ((long)FUNC##l(xl,__builtin_nan##SIGNAL##l("")) != (long)xl) \ + link_error(__LINE__); \ + } while (0) + +void __attribute__ ((__noinline__)) + foo (float xf, double x, long double xl, float yf, double y, long double yl, int i, int j) { @@ -91,6 +109,11 @@ void foo (float xf, double x, long double xl, TEST_NONNEG(fmin); TEST_NONNEG(fmax); + + TEST_NAN(fmin,); + TEST_NAN(fmax,); + TEST_NAN(fmin,s); + TEST_NAN(fmax,s); } int main() -- 2.30.2