aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>2006-11-26 14:35:54 +0000
committerKaveh Ghazi <ghazi@gcc.gnu.org>2006-11-26 14:35:54 +0000
commita8e3bad42b9636e20442b52a3924c914dc34dd82 (patch)
tree734a8de765f4b48ee96ae36a16bd7acbc013212e
parentd19c0f4fa6599e454c1c7b12917252f6f34852e7 (diff)
downloadgcc-a8e3bad42b9636e20442b52a3924c914dc34dd82.zip
gcc-a8e3bad42b9636e20442b52a3924c914dc34dd82.tar.gz
gcc-a8e3bad42b9636e20442b52a3924c914dc34dd82.tar.bz2
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
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/builtins.c14
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c25
4 files changed, 47 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c04d5c0..274c862 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,7 @@
+2006-11-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * builtins.c (fold_builtin_fmin_fmax): Handle NaN arguments.
+
2006-11-26 Razya Ladklesky <razya@il.ibm.com>
* testsuite/gcc.dg/ipa/ipa-6.c: New.
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 75b47fb..b2964de 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 7175209..3adde52 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-11-26 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
+
+ * gcc.dg/torture/builtin-minmax-1.c: Test NaN in fmin/fmax.
+ Don't ever inline the testcase.
+
2006-11-25 Andrew Pinski <pinskia@gmail.com>
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 280d356..4948aa9 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()