public inbox for fortran@gcc.gnu.org
 help / color / mirror / Atom feed
From: Janne Blomqvist <blomqvist.janne@gmail.com>
To: fortran@gcc.gnu.org,	gcc-patches@gcc.gnu.org
Cc: Janne Blomqvist <blomqvist.janne@gmail.com>
Subject: [PATCH] Unconditionally use MAX_EXPR/MIN_EXPR for MAX/MIN intrinsics
Date: Fri, 10 Aug 2018 20:47:00 -0000	[thread overview]
Message-ID: <20180810204728.20191-1-blomqvist.janne@gmail.com> (raw)

For floating point types, the question is what MAX(a, NaN) or MIN(a,
NaN) should return (where "a" is a normal number).  There are valid
usecases for returning either one, but the Fortran standard doesn't
specify which one should be chosen.  Also, there is no consensus among
other tested compilers.  In short, it's a mess.  So lets just do
whatever is fastest, which is using MAX_EXPR/MIN_EXPR which are not
defined to do anything in particular if one of the operands is a NaN.

Regtested on x86_64-pc-linux-gnu, Ok for trunk?

gcc/fortran/ChangeLog:

2018-08-10  Janne Blomqvist  <jb@gcc.gnu.org>

	* trans-intrinsic.c (gfc_conv_intrinsic_minmax): Use
	MAX_EXPR/MIN_EXPR unconditionally for real arguments.

gcc/testsuite/ChangeLog:

2018-08-10  Janne Blomqvist  <jb@gcc.gnu.org>

	* gfortran.dg/nan_1.f90: Remove tests that test MAX/MIN with NaNs.
---
 gcc/fortran/trans-intrinsic.c       | 55 ++++++-----------------------
 gcc/testsuite/gfortran.dg/nan_1.f90 | 35 ------------------
 2 files changed, 10 insertions(+), 80 deletions(-)

diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index c9b5479740c..190fde66a8d 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -3914,8 +3914,6 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
   mvar = gfc_create_var (type, "M");
   gfc_add_modify (&se->pre, mvar, args[0]);
 
-  internal_fn ifn = op == GT_EXPR ? IFN_FMAX : IFN_FMIN;
-
   for (i = 1, argexpr = argexpr->next; i < nargs; i++, argexpr = argexpr->next)
     {
       tree cond = NULL_TREE;
@@ -3936,49 +3934,16 @@ gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
 	val = gfc_evaluate_now (val, &se->pre);
 
       tree calc;
-      /* If we dealing with integral types or we don't care about NaNs
-	 just do a MIN/MAX_EXPR.  */
-      if (!HONOR_NANS (type) && !HONOR_SIGNED_ZEROS (type))
-	{
-
-	  tree_code code = op == GT_EXPR ? MAX_EXPR : MIN_EXPR;
-	  calc = fold_build2_loc (input_location, code, type,
-				  convert (type, val), mvar);
-	  tmp = build2_v (MODIFY_EXPR, mvar, calc);
-
-	}
-      /* If we care about NaNs and we have internal functions available for
-	 fmin/fmax to perform the comparison, use those.  */
-      else if (SCALAR_FLOAT_TYPE_P (type)
-	      && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED))
-	{
-	  calc = build_call_expr_internal_loc (input_location, ifn, type,
-						2, mvar, convert (type, val));
-	  tmp = build2_v (MODIFY_EXPR, mvar, calc);
-
-	}
-      /* Otherwise expand to:
-	mvar = a1;
-	if (a2 .op. mvar || isnan (mvar))
-	  mvar = a2;
-	if (a3 .op. mvar || isnan (mvar))
-	  mvar = a3;
-	...  */
-      else
-	{
-	  tree isnan = build_call_expr_loc (input_location,
-					builtin_decl_explicit (BUILT_IN_ISNAN),
-					1, mvar);
-	  tmp = fold_build2_loc (input_location, op, logical_type_node,
-				 convert (type, val), mvar);
-
-	  tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR,
-				  logical_type_node, tmp,
-				  fold_convert (logical_type_node, isnan));
-	  tmp = build3_v (COND_EXPR, tmp,
-			  build2_v (MODIFY_EXPR, mvar, convert (type, val)),
-			  build_empty_stmt (input_location));
-	}
+      /* For floating point types, the question is what MAX(a, NaN) or
+	 MIN(a, NaN) should return (where "a" is a normal number).
+	 There are valid usecase for returning either one, but the
+	 Fortran standard doesn't specify which one should be chosen.
+	 Also, there is no consensus among other tested compilers.  In
+	 short, it's a mess.  So lets just do whatever is fastest.  */
+      tree_code code = op == GT_EXPR ? MAX_EXPR : MIN_EXPR;
+      calc = fold_build2_loc (input_location, code, type,
+			      convert (type, val), mvar);
+      tmp = build2_v (MODIFY_EXPR, mvar, calc);
 
       if (cond != NULL_TREE)
 	tmp = build3_v (COND_EXPR, cond, tmp,
diff --git a/gcc/testsuite/gfortran.dg/nan_1.f90 b/gcc/testsuite/gfortran.dg/nan_1.f90
index e64b4ce65e1..1b39cc1f21c 100644
--- a/gcc/testsuite/gfortran.dg/nan_1.f90
+++ b/gcc/testsuite/gfortran.dg/nan_1.f90
@@ -66,35 +66,12 @@ program test
   if (isinf(-nan) .or. isinf(-large) .or. .not. isinf(-inf)) STOP 4
 
   ! Check that MIN and MAX behave correctly
-  if (max(2.0, nan) /= 2.0) STOP 5
-  if (min(2.0, nan) /= 2.0) STOP 6
-  if (max(nan, 2.0) /= 2.0) STOP 7
-  if (min(nan, 2.0) /= 2.0) STOP 8
-
-  if (max(2.d0, nan) /= 2.d0) STOP 9! { dg-warning "Extension: Different type kinds" }
-  if (min(2.d0, nan) /= 2.d0) STOP 10! { dg-warning "Extension: Different type kinds" }
-  if (max(nan, 2.d0) /= 2.d0) STOP 11! { dg-warning "Extension: Different type kinds" }
-  if (min(nan, 2.d0) /= 2.d0) STOP 12! { dg-warning "Extension: Different type kinds" }
 
   if (.not. isnan(min(nan,nan))) STOP 13
   if (.not. isnan(max(nan,nan))) STOP 14
 
   ! Same thing, with more arguments
 
-  if (max(3.0, 2.0, nan) /= 3.0) STOP 15
-  if (min(3.0, 2.0, nan) /= 2.0) STOP 16
-  if (max(3.0, nan, 2.0) /= 3.0) STOP 17
-  if (min(3.0, nan, 2.0) /= 2.0) STOP 18
-  if (max(nan, 3.0, 2.0) /= 3.0) STOP 19
-  if (min(nan, 3.0, 2.0) /= 2.0) STOP 20
-
-  if (max(3.d0, 2.d0, nan) /= 3.d0) STOP 21! { dg-warning "Extension: Different type kinds" }
-  if (min(3.d0, 2.d0, nan) /= 2.d0) STOP 22! { dg-warning "Extension: Different type kinds" }
-  if (max(3.d0, nan, 2.d0) /= 3.d0) STOP 23! { dg-warning "Extension: Different type kinds" }
-  if (min(3.d0, nan, 2.d0) /= 2.d0) STOP 24! { dg-warning "Extension: Different type kinds" }
-  if (max(nan, 3.d0, 2.d0) /= 3.d0) STOP 25! { dg-warning "Extension: Different type kinds" }
-  if (min(nan, 3.d0, 2.d0) /= 2.d0) STOP 26! { dg-warning "Extension: Different type kinds" }
-
   if (.not. isnan(min(nan,nan,nan))) STOP 27
   if (.not. isnan(max(nan,nan,nan))) STOP 28
   if (.not. isnan(min(nan,nan,nan,nan))) STOP 29
@@ -105,20 +82,8 @@ program test
   ! Large values, INF and NaNs
   if (.not. isinf(max(large, inf))) STOP 33
   if (isinf(min(large, inf))) STOP 34
-  if (.not. isinf(max(nan, large, inf))) STOP 35
-  if (isinf(min(nan, large, inf))) STOP 36
-  if (.not. isinf(max(large, nan, inf))) STOP 37
-  if (isinf(min(large, nan, inf))) STOP 38
-  if (.not. isinf(max(large, inf, nan))) STOP 39
-  if (isinf(min(large, inf, nan))) STOP 40
 
   if (.not. isinf(min(-large, -inf))) STOP 41
   if (isinf(max(-large, -inf))) STOP 42
-  if (.not. isinf(min(nan, -large, -inf))) STOP 43
-  if (isinf(max(nan, -large, -inf))) STOP 44
-  if (.not. isinf(min(-large, nan, -inf))) STOP 45
-  if (isinf(max(-large, nan, -inf))) STOP 46
-  if (.not. isinf(min(-large, -inf, nan))) STOP 47
-  if (isinf(max(-large, -inf, nan))) STOP 48
 
 end program test
-- 
2.17.1

             reply	other threads:[~2018-08-10 20:47 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-08-10 20:47 Janne Blomqvist [this message]
2018-08-19 16:01 ` Janne Blomqvist
2018-08-19 19:47   ` Thomas Koenig
2018-08-22  6:59     ` Janne Blomqvist

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180810204728.20191-1-blomqvist.janne@gmail.com \
    --to=blomqvist.janne@gmail.com \
    --cc=fortran@gcc.gnu.org \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).