]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtins.c (fold_builtin_fmin_fmax): Handle NaN arguments.
authorKaveh R. Ghazi <ghazi@caip.rutgers.edu>
Sun, 26 Nov 2006 14:35:54 +0000 (14:35 +0000)
committerKaveh Ghazi <ghazi@gcc.gnu.org>
Sun, 26 Nov 2006 14:35:54 +0000 (14:35 +0000)
* 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
gcc/builtins.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/builtin-minmax-1.c

index c04d5c02af8b8bd55c45250c112b4df9fc7ba9ce..274c862f3bee66223ef8e502cb4f02eb44a1c277 100644 (file)
@@ -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.
index 75b47fb239195fc01de5de8ef99ce76f3e7418bc..b2964ded2966dfd6cb173e2a3dabb374b7860f27 100644 (file)
@@ -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);
index 71752094394a7b17e3780f55995a0a45a072eaa3..3adde52429f53fae72df8394beeeb821247521d9 100644 (file)
@@ -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
index 280d3564e3730bf149590d8475a7e5ba5bee4e3b..4948aa9e004f451f0a2ce8a4c51f55bafcbca6cd 100644 (file)
@@ -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()