Blame SOURCES/gcc11-fortran-fdec-promotion.patch

6f0f47
From 7a27318818e359a277f2fa5f7dc3932d0fb950f5 Mon Sep 17 00:00:00 2001
6f0f47
From: Mark Eggleston <markeggleston@gcc.gnu.org>
6f0f47
Date: Fri, 22 Jan 2021 14:58:07 +0000
6f0f47
Subject: [PATCH 08/10] Support type promotion in calls to intrinsics
6f0f47
6f0f47
Use -fdec-promotion or -fdec to enable this feature.
6f0f47
6f0f47
Merged 2 commits: worked on by Ben Brewer <ben.brewer@codethink.co.uk>,
6f0f47
Francisco Redondo Marchena <francisco.marchena@codethink.co.uk> and
6f0f47
Jeff Law <law@redhat.com>
6f0f47
6f0f47
Re-worked by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
---
6f0f47
 gcc/fortran/check.c                           |  71 +++++-
6f0f47
 gcc/fortran/intrinsic.c                       |   5 +
6f0f47
 gcc/fortran/iresolve.c                        |  91 ++++---
6f0f47
 gcc/fortran/lang.opt                          |   4 +
6f0f47
 gcc/fortran/options.c                         |   1 +
6f0f47
 gcc/fortran/simplify.c                        | 240 ++++++++++++++----
6f0f47
 ...trinsic_int_real_array_const_promotion_1.f |  18 ++
6f0f47
 ...trinsic_int_real_array_const_promotion_2.f |  18 ++
6f0f47
 ...trinsic_int_real_array_const_promotion_3.f |  18 ++
6f0f47
 ...dec_intrinsic_int_real_const_promotion_1.f |  90 +++++++
6f0f47
 ...dec_intrinsic_int_real_const_promotion_2.f |  90 +++++++
6f0f47
 ...dec_intrinsic_int_real_const_promotion_3.f |  92 +++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_1.f      | 130 ++++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_2.f      | 130 ++++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_3.f      | 130 ++++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_4.f      | 118 +++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_5.f      | 118 +++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_6.f      | 118 +++++++++
6f0f47
 .../dec_intrinsic_int_real_promotion_7.f      | 118 +++++++++
6f0f47
 .../gfortran.dg/dec_kind_promotion-1.f        |  40 +++
6f0f47
 .../gfortran.dg/dec_kind_promotion-2.f        |  40 +++
6f0f47
 .../gfortran.dg/dec_kind_promotion-3.f        |  39 +++
6f0f47
 22 files changed, 1639 insertions(+), 80 deletions(-)
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
6f0f47
 create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
6f0f47
6f0f47
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
6f0f47
index 623c1cc470e..e20a834a860 100644
6f0f47
--- a/gcc/fortran/check.c
6f0f47
+++ b/gcc/fortran/check.c
6f0f47
@@ -1396,12 +1396,40 @@ gfc_check_allocated (gfc_expr *array)
6f0f47
 }
6f0f47
 
6f0f47
 
6f0f47
+/* Check function where both arguments must be real or integer
6f0f47
+   and warn if they are different types.  */
6f0f47
+
6f0f47
+bool
6f0f47
+check_int_real_promotion (gfc_expr *a, gfc_expr *b)
6f0f47
+{
6f0f47
+  gfc_expr *i;
6f0f47
+
6f0f47
+  if (!int_or_real_check (a, 0))
6f0f47
+    return false;
6f0f47
+
6f0f47
+  if (!int_or_real_check (b, 1))
6f0f47
+    return false;
6f0f47
+
6f0f47
+  if (a->ts.type != b->ts.type)
6f0f47
+    {
6f0f47
+      i = (a->ts.type != BT_REAL ? a : b);
6f0f47
+      gfc_warning_now (OPT_Wconversion, "Conversion from INTEGER to REAL "
6f0f47
+		       "at %L might lose precision", &i->where);
6f0f47
+    }
6f0f47
+
6f0f47
+  return true;
6f0f47
+}
6f0f47
+
6f0f47
+
6f0f47
 /* Common check function where the first argument must be real or
6f0f47
    integer and the second argument must be the same as the first.  */
6f0f47
 
6f0f47
 bool
6f0f47
 gfc_check_a_p (gfc_expr *a, gfc_expr *p)
6f0f47
 {
6f0f47
+  if (flag_dec_promotion)
6f0f47
+    return check_int_real_promotion (a, p);
6f0f47
+
6f0f47
   if (!int_or_real_check (a, 0))
6f0f47
     return false;
6f0f47
 
6f0f47
@@ -3724,6 +3752,41 @@ check_rest (bt type, int kind, gfc_actual_arglist *arglist)
6f0f47
 }
6f0f47
 
6f0f47
 
6f0f47
+/* Check function where all arguments of an argument list must be real
6f0f47
+   or integer.  */
6f0f47
+
6f0f47
+static bool
6f0f47
+check_rest_int_real (gfc_actual_arglist *arglist)
6f0f47
+{
6f0f47
+  gfc_actual_arglist *arg, *tmp;
6f0f47
+  gfc_expr *x;
6f0f47
+  int m, n;
6f0f47
+
6f0f47
+  if (!min_max_args (arglist))
6f0f47
+    return false;
6f0f47
+
6f0f47
+  for (arg = arglist, n=1; arg; arg = arg->next, n++)
6f0f47
+    {
6f0f47
+      x = arg->expr;
6f0f47
+      if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
6f0f47
+	{
6f0f47
+	  gfc_error ("%<a%d%> argument of %qs intrinsic at %L must be "
6f0f47
+		     "INTEGER or REAL", n, gfc_current_intrinsic, &x->where);
6f0f47
+	  return false;
6f0f47
+	}
6f0f47
+
6f0f47
+      for (tmp = arglist, m=1; tmp != arg; tmp = tmp->next, m++)
6f0f47
+	if (!gfc_check_conformance (tmp->expr, x,
6f0f47
+				    "arguments 'a%d' and 'a%d' for "
6f0f47
+				    "intrinsic '%s'", m, n,
6f0f47
+				    gfc_current_intrinsic))
6f0f47
+	  return false;
6f0f47
+    }
6f0f47
+
6f0f47
+  return true;
6f0f47
+}
6f0f47
+
6f0f47
+
6f0f47
 bool
6f0f47
 gfc_check_min_max (gfc_actual_arglist *arg)
6f0f47
 {
6f0f47
@@ -3748,7 +3811,10 @@ gfc_check_min_max (gfc_actual_arglist *arg)
6f0f47
       return false;
6f0f47
     }
6f0f47
 
6f0f47
-  return check_rest (x->ts.type, x->ts.kind, arg);
6f0f47
+  if (flag_dec_promotion && x->ts.type != BT_CHARACTER)
6f0f47
+    return check_rest_int_real (arg);
6f0f47
+  else
6f0f47
+    return check_rest (x->ts.type, x->ts.kind, arg);
6f0f47
 }
6f0f47
 
6f0f47
 
6f0f47
@@ -5121,6 +5187,9 @@ gfc_check_shift (gfc_expr *i, gfc_expr *shift)
6f0f47
 bool
6f0f47
 gfc_check_sign (gfc_expr *a, gfc_expr *b)
6f0f47
 {
6f0f47
+  if (flag_dec_promotion)
6f0f47
+    return check_int_real_promotion (a, b);
6f0f47
+
6f0f47
   if (!int_or_real_check (a, 0))
6f0f47
     return false;
6f0f47
 
6f0f47
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
6f0f47
index e68eff8bdbb..81b3a24c2be 100644
6f0f47
--- a/gcc/fortran/intrinsic.c
6f0f47
+++ b/gcc/fortran/intrinsic.c
6f0f47
@@ -4467,6 +4467,11 @@ check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
6f0f47
       if (ts.kind == 0)
6f0f47
 	ts.kind = actual->expr->ts.kind;
6f0f47
 
6f0f47
+      /* If kind promotion is allowed don't check for kind if it is smaller */
6f0f47
+      if (flag_dec_promotion && ts.type == BT_INTEGER)
6f0f47
+	if (actual->expr->ts.kind < ts.kind)
6f0f47
+	  ts.kind = actual->expr->ts.kind;
6f0f47
+
6f0f47
       if (!gfc_compare_types (&ts, &actual->expr->ts))
6f0f47
 	{
6f0f47
 	  if (error_flag)
6f0f47
diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c
6f0f47
index e17fe45f080..b9cdaff2499 100644
6f0f47
--- a/gcc/fortran/iresolve.c
6f0f47
+++ b/gcc/fortran/iresolve.c
6f0f47
@@ -817,19 +817,22 @@ gfc_resolve_dble (gfc_expr *f, gfc_expr *a)
6f0f47
 void
6f0f47
 gfc_resolve_dim (gfc_expr *f, gfc_expr *a, gfc_expr *p)
6f0f47
 {
6f0f47
-  f->ts.type = a->ts.type;
6f0f47
   if (p != NULL)
6f0f47
-    f->ts.kind = gfc_kind_max (a,p);
6f0f47
-  else
6f0f47
-    f->ts.kind = a->ts.kind;
6f0f47
-
6f0f47
-  if (p != NULL && a->ts.kind != p->ts.kind)
6f0f47
     {
6f0f47
-      if (a->ts.kind == gfc_kind_max (a,p))
6f0f47
-	gfc_convert_type (p, &a->ts, 2);
6f0f47
+      f->ts.kind = gfc_kind_max (a,p);
6f0f47
+      if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
6f0f47
+	f->ts.type = BT_REAL;
6f0f47
       else
6f0f47
-	gfc_convert_type (a, &p->ts, 2);
6f0f47
+	f->ts.type = BT_INTEGER;
6f0f47
+
6f0f47
+      if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (a, &f->ts, 2);
6f0f47
+
6f0f47
+      if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (p, &f->ts, 2);
6f0f47
     }
6f0f47
+  else
6f0f47
+    f->ts = a->ts;
6f0f47
 
6f0f47
   f->value.function.name
6f0f47
     = gfc_get_string ("__dim_%c%d", gfc_type_letter (f->ts.type), f->ts.kind);
6f0f47
@@ -1606,14 +1609,17 @@ gfc_resolve_minmax (const char *name, gfc_expr *f, gfc_actual_arglist *args)
6f0f47
   /* Find the largest type kind.  */
6f0f47
   for (a = args->next; a; a = a->next)
6f0f47
     {
6f0f47
+      if (a->expr-> ts.type == BT_REAL)
6f0f47
+	f->ts.type = BT_REAL;
6f0f47
+
6f0f47
       if (a->expr->ts.kind > f->ts.kind)
6f0f47
 	f->ts.kind = a->expr->ts.kind;
6f0f47
     }
6f0f47
 
6f0f47
-  /* Convert all parameters to the required kind.  */
6f0f47
+  /* Convert all parameters to the required type and/or kind.  */
6f0f47
   for (a = args; a; a = a->next)
6f0f47
     {
6f0f47
-      if (a->expr->ts.kind != f->ts.kind)
6f0f47
+      if (a->expr->ts.type != f->ts.type || a->expr->ts.kind != f->ts.kind)
6f0f47
 	gfc_convert_type (a->expr, &f->ts, 2);
6f0f47
     }
6f0f47
 
6f0f47
@@ -2106,19 +2112,22 @@ gfc_resolve_minval (gfc_expr *f, gfc_expr *array, gfc_expr *dim,
6f0f47
 void
6f0f47
 gfc_resolve_mod (gfc_expr *f, gfc_expr *a, gfc_expr *p)
6f0f47
 {
6f0f47
-  f->ts.type = a->ts.type;
6f0f47
   if (p != NULL)
6f0f47
-    f->ts.kind = gfc_kind_max (a,p);
6f0f47
-  else
6f0f47
-    f->ts.kind = a->ts.kind;
6f0f47
-
6f0f47
-  if (p != NULL && a->ts.kind != p->ts.kind)
6f0f47
     {
6f0f47
-      if (a->ts.kind == gfc_kind_max (a,p))
6f0f47
-	gfc_convert_type (p, &a->ts, 2);
6f0f47
+      f->ts.kind = gfc_kind_max (a,p);
6f0f47
+      if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
6f0f47
+	f->ts.type = BT_REAL;
6f0f47
       else
6f0f47
-	gfc_convert_type (a, &p->ts, 2);
6f0f47
+	f->ts.type = BT_INTEGER;
6f0f47
+
6f0f47
+      if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (a, &f->ts, 2);
6f0f47
+
6f0f47
+      if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (p, &f->ts, 2);
6f0f47
     }
6f0f47
+  else
6f0f47
+    f->ts = a->ts;
6f0f47
 
6f0f47
   f->value.function.name
6f0f47
     = gfc_get_string ("__mod_%c%d", gfc_type_letter (f->ts.type), f->ts.kind);
6f0f47
@@ -2128,19 +2137,22 @@ gfc_resolve_mod (gfc_expr *f, gfc_expr *a, gfc_expr *p)
6f0f47
 void
6f0f47
 gfc_resolve_modulo (gfc_expr *f, gfc_expr *a, gfc_expr *p)
6f0f47
 {
6f0f47
-  f->ts.type = a->ts.type;
6f0f47
   if (p != NULL)
6f0f47
-    f->ts.kind = gfc_kind_max (a,p);
6f0f47
-  else
6f0f47
-    f->ts.kind = a->ts.kind;
6f0f47
-
6f0f47
-  if (p != NULL && a->ts.kind != p->ts.kind)
6f0f47
     {
6f0f47
-      if (a->ts.kind == gfc_kind_max (a,p))
6f0f47
-	gfc_convert_type (p, &a->ts, 2);
6f0f47
+      f->ts.kind = gfc_kind_max (a,p);
6f0f47
+      if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
6f0f47
+	f->ts.type = BT_REAL;
6f0f47
       else
6f0f47
-	gfc_convert_type (a, &p->ts, 2);
6f0f47
+	f->ts.type = BT_INTEGER;
6f0f47
+
6f0f47
+      if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (a, &f->ts, 2);
6f0f47
+
6f0f47
+      if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (p, &f->ts, 2);
6f0f47
     }
6f0f47
+  else
6f0f47
+    f->ts = a->ts;
6f0f47
 
6f0f47
   f->value.function.name
6f0f47
     = gfc_get_string ("__modulo_%c%d", gfc_type_letter (f->ts.type),
6f0f47
@@ -2515,9 +2527,26 @@ gfc_resolve_shift (gfc_expr *f, gfc_expr *i, gfc_expr *shift ATTRIBUTE_UNUSED)
6f0f47
 
6f0f47
 
6f0f47
 void
6f0f47
-gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b ATTRIBUTE_UNUSED)
6f0f47
+gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b)
6f0f47
 {
6f0f47
-  f->ts = a->ts;
6f0f47
+  if (b != NULL)
6f0f47
+    {
6f0f47
+      f->ts.kind = gfc_kind_max (a, b);
6f0f47
+      if (a->ts.type == BT_REAL || b->ts.type == BT_REAL)
6f0f47
+	f->ts.type = BT_REAL;
6f0f47
+      else
6f0f47
+	f->ts.type = BT_INTEGER;
6f0f47
+
6f0f47
+      if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (a, &f->ts, 2);
6f0f47
+
6f0f47
+      if (b->ts.kind != f->ts.kind || b->ts.type != f->ts.type)
6f0f47
+	gfc_convert_type (b, &f->ts, 2);
6f0f47
+    }
6f0f47
+  else
6f0f47
+    {
6f0f47
+      f->ts = a->ts;
6f0f47
+    }
6f0f47
   f->value.function.name
6f0f47
     = gfc_get_string ("__sign_%c%d", gfc_type_letter (a->ts.type), a->ts.kind);
6f0f47
 }
6f0f47
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
6f0f47
index d886c2f33ed..4ca2f93f2df 100644
6f0f47
--- a/gcc/fortran/lang.opt
6f0f47
+++ b/gcc/fortran/lang.opt
6f0f47
@@ -505,6 +505,10 @@ fdec-old-init
6f0f47
 Fortran Var(flag_dec_old_init)
6f0f47
 Enable support for old style initializers in derived types.
6f0f47
 
6f0f47
+fdec-promotion
6f0f47
+Fortran Var(flag_dec_promotion)
6f0f47
+Add support for type promotion in intrinsic arguments.
6f0f47
+
6f0f47
 fdec-structure
6f0f47
 Fortran Var(flag_dec_structure)
6f0f47
 Enable support for DEC STRUCTURE/RECORD.
6f0f47
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
6f0f47
index a946c86790a..15079c7e95a 100644
6f0f47
--- a/gcc/fortran/options.c
6f0f47
+++ b/gcc/fortran/options.c
6f0f47
@@ -82,6 +82,7 @@ set_dec_flags (int value)
6f0f47
   SET_BITFLAG (flag_dec_old_init, value, value);
6f0f47
   SET_BITFLAG (flag_dec_override_kind, value, value);
6f0f47
   SET_BITFLAG (flag_dec_non_logical_if, value, value);
6f0f47
+  SET_BITFLAG (flag_dec_promotion, value, value);
6f0f47
 }
6f0f47
 
6f0f47
 /* Finalize DEC flags.  */
6f0f47
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
6f0f47
index 9900572424f..3419e06fec2 100644
6f0f47
--- a/gcc/fortran/simplify.c
6f0f47
+++ b/gcc/fortran/simplify.c
6f0f47
@@ -2333,39 +2333,79 @@ gfc_simplify_digits (gfc_expr *x)
6f0f47
 }
6f0f47
 
6f0f47
 
6f0f47
+/* Simplify function which sets the floating-point value of ar from
6f0f47
+   the value of a independently if a is integer of real.  */
6f0f47
+
6f0f47
+static void
6f0f47
+simplify_int_real_promotion (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar)
6f0f47
+{
6f0f47
+  if (a->ts.type == BT_REAL)
6f0f47
+    {
6f0f47
+      mpfr_init2 (*ar, (a->ts.kind * 8));
6f0f47
+      mpfr_set (*ar, a->value.real, GFC_RND_MODE);
6f0f47
+    }
6f0f47
+  else
6f0f47
+    {
6f0f47
+      mpfr_init2 (*ar, (b->ts.kind * 8));
6f0f47
+      mpfr_set_z (*ar, a->value.integer, GFC_RND_MODE);
6f0f47
+    }
6f0f47
+}
6f0f47
+
6f0f47
+
6f0f47
+/* Simplify function which promotes a and b arguments from integer to real if
6f0f47
+   required in ar and br floating-point values. This function returns true if
6f0f47
+   a or b are reals and false otherwise. */
6f0f47
+
6f0f47
+static bool
6f0f47
+simplify_int_real_promotion2 (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar,
6f0f47
+			      mpfr_t *br)
6f0f47
+{
6f0f47
+  if (a->ts.type != BT_REAL && b->ts.type != BT_REAL)
6f0f47
+    return false;
6f0f47
+
6f0f47
+  simplify_int_real_promotion (a, b, ar);
6f0f47
+  simplify_int_real_promotion (b, a, br);
6f0f47
+
6f0f47
+  return true;
6f0f47
+}
6f0f47
+
6f0f47
+
6f0f47
 gfc_expr *
6f0f47
 gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
6f0f47
 {
6f0f47
   gfc_expr *result;
6f0f47
   int kind;
6f0f47
 
6f0f47
+  mpfr_t xr;
6f0f47
+  mpfr_t yr;
6f0f47
+
6f0f47
   if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
-  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
6f0f47
-  result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
6f0f47
-
6f0f47
-  switch (x->ts.type)
6f0f47
+  if ((x->ts.type != BT_REAL && x->ts.type != BT_INTEGER)
6f0f47
+      || (y->ts.type != BT_REAL && y->ts.type != BT_INTEGER))
6f0f47
     {
6f0f47
-      case BT_INTEGER:
6f0f47
-	if (mpz_cmp (x->value.integer, y->value.integer) > 0)
6f0f47
-	  mpz_sub (result->value.integer, x->value.integer, y->value.integer);
6f0f47
-	else
6f0f47
-	  mpz_set_ui (result->value.integer, 0);
6f0f47
-
6f0f47
-	break;
6f0f47
-
6f0f47
-      case BT_REAL:
6f0f47
-	if (mpfr_cmp (x->value.real, y->value.real) > 0)
6f0f47
-	  mpfr_sub (result->value.real, x->value.real, y->value.real,
6f0f47
-		    GFC_RND_MODE);
6f0f47
-	else
6f0f47
-	  mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6f0f47
+      gfc_internal_error ("gfc_simplify_dim(): Bad arguments");
6f0f47
+      return NULL;
6f0f47
+    }
6f0f47
 
6f0f47
-	break;
6f0f47
+  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
6f0f47
 
6f0f47
-      default:
6f0f47
-	gfc_internal_error ("gfc_simplify_dim(): Bad type");
6f0f47
+  if (simplify_int_real_promotion2 (x, y, &xr, &yr))
6f0f47
+    {
6f0f47
+      result = gfc_get_constant_expr (BT_REAL, kind, &x->where);
6f0f47
+      if (mpfr_cmp (xr, yr) > 0)
6f0f47
+	mpfr_sub (result->value.real, xr, yr, GFC_RND_MODE);
6f0f47
+      else
6f0f47
+	mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
6f0f47
+    }
6f0f47
+  else
6f0f47
+    {
6f0f47
+      result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
6f0f47
+      if (mpz_cmp (x->value.integer, y->value.integer) > 0)
6f0f47
+	mpz_sub (result->value.integer, x->value.integer, y->value.integer);
6f0f47
+      else
6f0f47
+	mpz_set_ui (result->value.integer, 0);
6f0f47
     }
6f0f47
 
6f0f47
   return range_check (result, "DIM");
6f0f47
@@ -4953,6 +4993,76 @@ min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign, bool back_val)
6f0f47
 {
6f0f47
   int ret;
6f0f47
 
6f0f47
+  mpfr_t *arp;
6f0f47
+  mpfr_t *erp;
6f0f47
+  mpfr_t ar;
6f0f47
+  mpfr_t er;
6f0f47
+
6f0f47
+  if (arg->ts.type != extremum->ts.type)
6f0f47
+    {
6f0f47
+      if (arg->ts.type == BT_REAL)
6f0f47
+	{
6f0f47
+	  arp = &arg->value.real;
6f0f47
+	}
6f0f47
+      else
6f0f47
+	{
6f0f47
+	  mpfr_init2 (ar, (arg->ts.kind * 8));
6f0f47
+	  mpfr_set_z (ar, arg->value.integer, GFC_RND_MODE);
6f0f47
+	  arp = &ar;
6f0f47
+	}
6f0f47
+
6f0f47
+      if (extremum->ts.type == BT_REAL)
6f0f47
+	{
6f0f47
+	  erp = &extremum->value.real;
6f0f47
+	}
6f0f47
+      else
6f0f47
+	{
6f0f47
+	  mpfr_init2 (er, (extremum->ts.kind * 8));
6f0f47
+	  mpfr_set_z (er, extremum->value.integer, GFC_RND_MODE);
6f0f47
+	  erp = &er;
6f0f47
+	}
6f0f47
+
6f0f47
+      if (mpfr_nan_p (*erp))
6f0f47
+	{
6f0f47
+	  ret = 1;
6f0f47
+	  extremum->ts.type = arg->ts.type;
6f0f47
+	  extremum->ts.kind = arg->ts.kind;
6f0f47
+	  if (arg->ts.type == BT_INTEGER)
6f0f47
+	    {
6f0f47
+	      mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
6f0f47
+	      mpz_set (extremum->value.integer, arg->value.integer);
6f0f47
+	    }
6f0f47
+	  else
6f0f47
+	    {
6f0f47
+	      mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
6f0f47
+	      mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
6f0f47
+	    }
6f0f47
+	}
6f0f47
+      else if (mpfr_nan_p (*arp))
6f0f47
+	ret = -1;
6f0f47
+      else
6f0f47
+	{
6f0f47
+	  ret = mpfr_cmp (*arp, *erp) * sign;
6f0f47
+	  if (ret > 0)
6f0f47
+	    {
6f0f47
+	      extremum->ts.type = arg->ts.type;
6f0f47
+	      extremum->ts.kind = arg->ts.kind;
6f0f47
+	      if (arg->ts.type == BT_INTEGER)
6f0f47
+		{
6f0f47
+		  mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
6f0f47
+		  mpz_set (extremum->value.integer, arg->value.integer);
6f0f47
+		}
6f0f47
+	      else
6f0f47
+		{
6f0f47
+		  mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
6f0f47
+		  mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
6f0f47
+		}
6f0f47
+	    }
6f0f47
+	}
6f0f47
+
6f0f47
+      return ret;
6f0f47
+    }
6f0f47
+
6f0f47
   switch (arg->ts.type)
6f0f47
     {
6f0f47
       case BT_INTEGER:
6f0f47
@@ -5912,7 +6022,9 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
6f0f47
   gfc_expr *result;
6f0f47
   int kind;
6f0f47
 
6f0f47
-  /* First check p.  */
6f0f47
+  mpfr_t ar;
6f0f47
+  mpfr_t pr;
6f0f47
+
6f0f47
   if (p->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
@@ -5942,16 +6054,24 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
6f0f47
   if (a->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
+  if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
6f0f47
+    {
6f0f47
+      gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
6f0f47
+      return NULL;
6f0f47
+    }
6f0f47
+
6f0f47
   kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
6f0f47
-  result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
6f0f47
 
6f0f47
-  if (a->ts.type == BT_INTEGER)
6f0f47
-    mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
6f0f47
-  else
6f0f47
+  if (simplify_int_real_promotion2 (a, p, &ar, &pr))
6f0f47
     {
6f0f47
+      result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
6f0f47
       gfc_set_model_kind (kind);
6f0f47
-      mpfr_fmod (result->value.real, a->value.real, p->value.real,
6f0f47
-		 GFC_RND_MODE);
6f0f47
+      mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
6f0f47
+    }
6f0f47
+  else
6f0f47
+    {
6f0f47
+      result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
6f0f47
+      mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
6f0f47
     }
6f0f47
 
6f0f47
   return range_check (result, "MOD");
6f0f47
@@ -5964,7 +6084,9 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
6f0f47
   gfc_expr *result;
6f0f47
   int kind;
6f0f47
 
6f0f47
-  /* First check p.  */
6f0f47
+  mpfr_t ar;
6f0f47
+  mpfr_t pr;
6f0f47
+
6f0f47
   if (p->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
@@ -5991,28 +6113,36 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
6f0f47
 	gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
6f0f47
     }
6f0f47
 
6f0f47
+  if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
6f0f47
+    {
6f0f47
+      gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
6f0f47
+      return NULL;
6f0f47
+    }
6f0f47
+
6f0f47
   if (a->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
   kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
6f0f47
-  result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
6f0f47
 
6f0f47
-  if (a->ts.type == BT_INTEGER)
6f0f47
-	mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
6f0f47
-  else
6f0f47
+  if (simplify_int_real_promotion2 (a, p, &ar, &pr))
6f0f47
     {
6f0f47
+      result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
6f0f47
       gfc_set_model_kind (kind);
6f0f47
-      mpfr_fmod (result->value.real, a->value.real, p->value.real,
6f0f47
-                 GFC_RND_MODE);
6f0f47
+      mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
6f0f47
       if (mpfr_cmp_ui (result->value.real, 0) != 0)
6f0f47
-        {
6f0f47
-          if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
6f0f47
-            mpfr_add (result->value.real, result->value.real, p->value.real,
6f0f47
-                      GFC_RND_MODE);
6f0f47
-	    }
6f0f47
-	  else
6f0f47
-        mpfr_copysign (result->value.real, result->value.real,
6f0f47
-                       p->value.real, GFC_RND_MODE);
6f0f47
+	{
6f0f47
+	  if (mpfr_signbit (ar) != mpfr_signbit (pr))
6f0f47
+	    mpfr_add (result->value.real, result->value.real, pr,
6f0f47
+		      GFC_RND_MODE);
6f0f47
+	}
6f0f47
+      else
6f0f47
+	mpfr_copysign (result->value.real, result->value.real, pr,
6f0f47
+		       GFC_RND_MODE);
6f0f47
+    }
6f0f47
+  else
6f0f47
+    {
6f0f47
+      result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
6f0f47
+      mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
6f0f47
     }
6f0f47
 
6f0f47
   return range_check (result, "MODULO");
6f0f47
@@ -7578,27 +7708,41 @@ gfc_expr *
6f0f47
 gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
6f0f47
 {
6f0f47
   gfc_expr *result;
6f0f47
+  bool neg;
6f0f47
 
6f0f47
   if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
6f0f47
     return NULL;
6f0f47
 
6f0f47
   result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
6f0f47
 
6f0f47
+  switch (y->ts.type)
6f0f47
+    {
6f0f47
+      case BT_INTEGER:
6f0f47
+	neg = (mpz_sgn (y->value.integer) < 0);
6f0f47
+	break;
6f0f47
+
6f0f47
+      case BT_REAL:
6f0f47
+	neg = (mpfr_sgn (y->value.real) < 0);
6f0f47
+	break;
6f0f47
+
6f0f47
+      default:
6f0f47
+	gfc_internal_error ("Bad type in gfc_simplify_sign");
6f0f47
+    }
6f0f47
+
6f0f47
   switch (x->ts.type)
6f0f47
     {
6f0f47
       case BT_INTEGER:
6f0f47
 	mpz_abs (result->value.integer, x->value.integer);
6f0f47
-	if (mpz_sgn (y->value.integer) < 0)
6f0f47
+	if (neg)
6f0f47
 	  mpz_neg (result->value.integer, result->value.integer);
6f0f47
 	break;
6f0f47
 
6f0f47
       case BT_REAL:
6f0f47
-	if (flag_sign_zero)
6f0f47
+	if (flag_sign_zero && y->ts.type == BT_REAL)
6f0f47
 	  mpfr_copysign (result->value.real, x->value.real, y->value.real,
6f0f47
-			GFC_RND_MODE);
6f0f47
+			 GFC_RND_MODE);
6f0f47
 	else
6f0f47
-	  mpfr_setsign (result->value.real, x->value.real,
6f0f47
-			mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
6f0f47
+	  mpfr_setsign (result->value.real, x->value.real, neg, GFC_RND_MODE);
6f0f47
 	break;
6f0f47
 
6f0f47
       default:
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..25763852139
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
6f0f47
@@ -0,0 +1,18 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals for mod and modulo where
6f0f47
+! A is a constant array and P is zero.
6f0f47
+!
6f0f47
+! Compilation errors are expected
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program promotion_int_real_array_const
6f0f47
+          real a(2) = mod([12, 34], 0.0)*4    ! { dg-error "shall not be zero" }
6f0f47
+          a = mod([12.0, 34.0], 0)*4          ! { dg-error "shall not be zero" }
6f0f47
+          real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
6f0f47
+          b = modulo([12.0, 34.0], 0)*4       ! { dg-error "shall not be zero" }
6f0f47
+      end program
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..b78a46054f4
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
6f0f47
@@ -0,0 +1,18 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals for mod and modulo where
6f0f47
+! A is a constant array and P is zero.
6f0f47
+!
6f0f47
+! Compilation errors are expected
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program promotion_int_real_array_const
6f0f47
+          real a(2) = mod([12, 34], 0.0)*4    ! { dg-error "shall not be zero" }
6f0f47
+          a = mod([12.0, 34.0], 0)*4          ! { dg-error "shall not be zero" }
6f0f47
+          real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
6f0f47
+          b = modulo([12.0, 34.0], 0)*4       ! { dg-error "shall not be zero" }
6f0f47
+      end program
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..318ab5db97e
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
6f0f47
@@ -0,0 +1,18 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec -fno-dec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals for mod and modulo where
6f0f47
+! A is a constant array and P is zero.
6f0f47
+!
6f0f47
+! Compilation errors are expected
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program promotion_int_real_array_const
6f0f47
+          real a(2) = mod([12, 34], 0.0)*4    ! { dg-error "'a' and 'p' arguments of 'mod'" }
6f0f47
+          a = mod([12.0, 34.0], 0)*4          ! { dg-error "'a' and 'p' arguments of 'mod'" }
6f0f47
+          real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "'a' and 'p' arguments of 'modulo'" }
6f0f47
+          b = modulo([12.0, 34.0], 0)*4       ! { dg-error "'a' and 'p' arguments of 'modulo'" }
6f0f47
+      end program
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..27eb2582bb2
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
6f0f47
@@ -0,0 +1,90 @@
6f0f47
+! { dg-do run }
6f0f47
+! { dg-options "-fdec -finit-real=snan" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real_const
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(4, 3)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_r = MOD(4.0, 3.0)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 2
6f0f47
+        m_r = MOD(4, 3.0)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(4.0, 3)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+
6f0f47
+        md_i = MODULO(4, 3)
6f0f47
+        if (md_i .ne. 1) STOP 5
6f0f47
+        md_r = MODULO(4.0, 3.0)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+        md_r = MODULO(4, 3.0)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 7
6f0f47
+        md_r = MODULO(4.0, 3)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 8
6f0f47
+
6f0f47
+        d_i = DIM(4, 3)
6f0f47
+        if (d_i .ne. 1) STOP 9
6f0f47
+        d_r = DIM(4.0, 3.0)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        d_r = DIM(4.0, 3)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        d_r = DIM(3, 4.0)
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        s_i = SIGN(-4, 3)
6f0f47
+        if (s_i .ne. 4) STOP 13
6f0f47
+        s_r = SIGN(4.0, -3.0)
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
6f0f47
+        s_r = SIGN(4.0, -3)
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
6f0f47
+        s_r = SIGN(-4, 3.0)
6f0f47
+        if (abs(s_r - 4.0) > 1.0D-6) STOP 16
6f0f47
+
6f0f47
+        mx_i = MAX(-4, -3, 2, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 17
6f0f47
+        mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
6f0f47
+        mx_r = MAX(-4, -3.0, 2.0, 1)
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 20
6f0f47
+
6f0f47
+        mn_i = MIN(-4, -3, 2, 1)
6f0f47
+        if (mn_i .ne. -4) STOP 21
6f0f47
+        mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
6f0f47
+        mn_r = MIN(-4, -3.0, 2.0, 1)
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 24
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..bdd017b7280
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
6f0f47
@@ -0,0 +1,90 @@
6f0f47
+! { dg-do run }
6f0f47
+! { dg-options "-fdec-promotion -finit-real=snan" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real_const
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(4, 3)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_r = MOD(4.0, 3.0)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 2
6f0f47
+        m_r = MOD(4, 3.0)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(4.0, 3)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+
6f0f47
+        md_i = MODULO(4, 3)
6f0f47
+        if (md_i .ne. 1) STOP 5
6f0f47
+        md_r = MODULO(4.0, 3.0)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+        md_r = MODULO(4, 3.0)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 7
6f0f47
+        md_r = MODULO(4.0, 3)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 8
6f0f47
+
6f0f47
+        d_i = DIM(4, 3)
6f0f47
+        if (d_i .ne. 1) STOP 9
6f0f47
+        d_r = DIM(4.0, 3.0)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        d_r = DIM(4.0, 3)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        d_r = DIM(3, 4.0)
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        s_i = SIGN(-4, 3)
6f0f47
+        if (s_i .ne. 4) STOP 13
6f0f47
+        s_r = SIGN(4.0, -3.0)
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
6f0f47
+        s_r = SIGN(4.0, -3)
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
6f0f47
+        s_r = SIGN(-4, 3.0)
6f0f47
+        if (abs(s_r - 4.0) > 1.0D-6) STOP 16
6f0f47
+
6f0f47
+        mx_i = MAX(-4, -3, 2, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 17
6f0f47
+        mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
6f0f47
+        mx_r = MAX(-4, -3.0, 2.0, 1)
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 20
6f0f47
+
6f0f47
+        mn_i = MIN(-4, -3, 2, 1)
6f0f47
+        if (mn_i .ne. -4) STOP 21
6f0f47
+        mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
6f0f47
+        mn_r = MIN(-4, -3.0, 2.0, 1)
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 24
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..ce90a5667d6
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
6f0f47
@@ -0,0 +1,92 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec -fno-dec-promotion -finit-real=snan" }
6f0f47
+!
6f0f47
+! Test that there is no promotion between integers and reals in
6f0f47
+! intrinsic operations.
6f0f47
+!
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real_const
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(4, 3)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_r = MOD(4.0, 3.0)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 2
6f0f47
+        m_r = MOD(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+
6f0f47
+        md_i = MODULO(4, 3)
6f0f47
+        if (md_i .ne. 1) STOP 5
6f0f47
+        md_r = MODULO(4.0, 3.0)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+        md_r = MODULO(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 7
6f0f47
+        md_r = MODULO(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 8
6f0f47
+
6f0f47
+        d_i = DIM(4, 3)
6f0f47
+        if (d_i .ne. 1) STOP 9
6f0f47
+        d_r = DIM(4.0, 3.0)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        d_r = DIM(4.0, 3) ! { dg-error "'x' and 'y' arguments" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        d_r = DIM(3, 4.0) ! { dg-error "'x' and 'y' arguments" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        s_i = SIGN(-4, 3)
6f0f47
+        if (s_i .ne. 4) STOP 13
6f0f47
+        s_r = SIGN(4.0, -3.0)
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
6f0f47
+        s_r = SIGN(4.0, -3) ! { dg-error "'b' argument" }
6f0f47
+        if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
6f0f47
+        s_r = SIGN(-4, 3.0) ! { dg-error "'b' argument" }
6f0f47
+        if (abs(s_r - 4.0) > 1.0D-6) STOP 16
6f0f47
+
6f0f47
+        mx_i = MAX(-4, -3, 2, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 17
6f0f47
+        mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
6f0f47
+        mx_r = MAX(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
6f0f47
+        if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 20
6f0f47
+
6f0f47
+        mn_i = MIN(-4, -3, 2, 1)
6f0f47
+        if (mn_i .ne. -4) STOP 21
6f0f47
+        mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
6f0f47
+        mn_r = MIN(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
6f0f47
+        if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 24
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..5c2cd931a4b
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
6f0f47
@@ -0,0 +1,130 @@
6f0f47
+! { dg-do run }
6f0f47
+! { dg-options "-fdec" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        INTEGER a_i/4/
6f0f47
+        INTEGER*4 a2_i/4/
6f0f47
+        INTEGER b_i/3/
6f0f47
+        INTEGER*8 b2_i/3/
6f0f47
+        INTEGER x_i/2/
6f0f47
+        INTEGER y_i/1/
6f0f47
+        REAL a_r/4.0/
6f0f47
+        REAL*4 a2_r/4.0/
6f0f47
+        REAL b_r/3.0/
6f0f47
+        REAL*8 b2_r/3.0/
6f0f47
+        REAL x_r/2.0/
6f0f47
+        REAL y_r/1.0/
6f0f47
+
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        array_nan(4) = 0/l
6f0f47
+
6f0f47
+        m_i = MOD(a_i, b_i)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_i, b2_i)
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_r, b_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_r, b2_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_i, b_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_r, b_i)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_i, b_i)
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_i, b2_i)
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_r, b_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_r, b2_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_i, b_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_r, b_i)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_i, b_i)
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_i, b2_i)
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_r, b_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_r, b2_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_r, b_i)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_i, a_r)
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_i, b_i)
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_i, b2_i)
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_r, -b_r)
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
6f0f47
+        s_r = SIGN(a2_r, -b2_r)
6f0f47
+        if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
6f0f47
+        s_r = SIGN(a_r, -b_i)
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
6f0f47
+        s_r = SIGN(-a_i, b_r)
6f0f47
+        if (abs(s_r - a_r) > 1.0D-6) STOP 24
6f0f47
+
6f0f47
+        mx_i = MAX(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 25
6f0f47
+        mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 26
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 27
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 28
6f0f47
+        mx_r = MAX(-a_i, -b_r, x_r, y_i)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 29
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 30
6f0f47
+
6f0f47
+        mn_i = MIN(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a_i) STOP 31
6f0f47
+        mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a2_i) STOP 32
6f0f47
+        mn_r = MIN(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
6f0f47
+        mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
6f0f47
+        mn_r = MIN(-a_i, -b_r, x_r, y_i)
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 36
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..d64d468f7d1
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
6f0f47
@@ -0,0 +1,130 @@
6f0f47
+! { dg-do run }
6f0f47
+! { dg-options "-fdec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        INTEGER a_i/4/
6f0f47
+        INTEGER*4 a2_i/4/
6f0f47
+        INTEGER b_i/3/
6f0f47
+        INTEGER*8 b2_i/3/
6f0f47
+        INTEGER x_i/2/
6f0f47
+        INTEGER y_i/1/
6f0f47
+        REAL a_r/4.0/
6f0f47
+        REAL*4 a2_r/4.0/
6f0f47
+        REAL b_r/3.0/
6f0f47
+        REAL*8 b2_r/3.0/
6f0f47
+        REAL x_r/2.0/
6f0f47
+        REAL y_r/1.0/
6f0f47
+
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        array_nan(4) = 0/l
6f0f47
+
6f0f47
+        m_i = MOD(a_i, b_i)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_i, b2_i)
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_r, b_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_r, b2_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_i, b_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_r, b_i)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_i, b_i)
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_i, b2_i)
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_r, b_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_r, b2_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_i, b_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_r, b_i)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_i, b_i)
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_i, b2_i)
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_r, b_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_r, b2_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_r, b_i)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_i, a_r)
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_i, b_i)
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_i, b2_i)
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_r, -b_r)
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
6f0f47
+        s_r = SIGN(a2_r, -b2_r)
6f0f47
+        if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
6f0f47
+        s_r = SIGN(a_r, -b_i)
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
6f0f47
+        s_r = SIGN(-a_i, b_r)
6f0f47
+        if (abs(s_r - a_r) > 1.0D-6) STOP 24
6f0f47
+
6f0f47
+        mx_i = MAX(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 25
6f0f47
+        mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 26
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 27
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 28
6f0f47
+        mx_r = MAX(-a_i, -b_r, x_r, y_i)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 29
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 30
6f0f47
+
6f0f47
+        mn_i = MIN(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a_i) STOP 31
6f0f47
+        mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a2_i) STOP 32
6f0f47
+        mn_r = MIN(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
6f0f47
+        mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
6f0f47
+        mn_r = MIN(-a_i, -b_r, x_r, y_i)
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 36
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..0708b666633
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
6f0f47
@@ -0,0 +1,130 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec -fno-dec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        INTEGER a_i/4/
6f0f47
+        INTEGER*4 a2_i/4/
6f0f47
+        INTEGER b_i/3/
6f0f47
+        INTEGER*8 b2_i/3/
6f0f47
+        INTEGER x_i/2/
6f0f47
+        INTEGER y_i/1/
6f0f47
+        REAL a_r/4.0/
6f0f47
+        REAL*4 a2_r/4.0/
6f0f47
+        REAL b_r/3.0/
6f0f47
+        REAL*8 b2_r/3.0/
6f0f47
+        REAL x_r/2.0/
6f0f47
+        REAL y_r/1.0/
6f0f47
+
6f0f47
+        REAL array_nan(4)
6f0f47
+        DATA array_nan(1)/-4.0/
6f0f47
+        DATA array_nan(2)/3.0/
6f0f47
+        DATA array_nan(3)/-2/
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        ! array_nan 4th position value is NAN
6f0f47
+        array_nan(4) = 0/l
6f0f47
+
6f0f47
+        m_i = MOD(a_i, b_i)
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_i, b2_i)
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_r, b_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_r, b2_r)
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_i, b_i)
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_i, b2_i)
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_r, b_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_r, b2_r)
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_i, b_i)
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_i, b2_i)
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_r, b_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_r, b2_r)
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_r, b_i) ! { dg-error "'x' and 'y' arguments" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_i, a_r) ! { dg-error "'x' and 'y' arguments" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_i, b_i)
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_i, b2_i) ! { dg-error "'b' argument" }
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_r, -b_r)
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
6f0f47
+        s_r = SIGN(a2_r, -b2_r) ! { dg-error "'b' argument" }
6f0f47
+        if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
6f0f47
+        s_r = SIGN(a_r, -b_i) ! { dg-error "'b' argument" }
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
6f0f47
+        s_r = SIGN(-a_i, b_r) ! { dg-error "'b' argument" }
6f0f47
+        if (abs(s_r - a_r) > 1.0D-6) STOP 24
6f0f47
+
6f0f47
+        mx_i = MAX(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 25
6f0f47
+        mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mx_i .ne. x_i) STOP 26
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 27
6f0f47
+        mx_r = MAX(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 28
6f0f47
+        mx_r = MAX(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 29
6f0f47
+        mx_i = MAXLOC(array_nan, 1)
6f0f47
+        if (mx_i .ne. 2) STOP 30
6f0f47
+
6f0f47
+        mn_i = MIN(-a_i, -b_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a_i) STOP 31
6f0f47
+        mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
6f0f47
+        if (mn_i .ne. -a2_i) STOP 32
6f0f47
+        mn_r = MIN(-a_r, -b_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
6f0f47
+        mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
6f0f47
+        if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
6f0f47
+        mn_r = MIN(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
6f0f47
+        mn_i = MINLOC(array_nan, 1)
6f0f47
+        if (mn_i .ne. 1) STOP 36
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..efa4f236410
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
6f0f47
@@ -0,0 +1,118 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        LOGICAL a_l
6f0f47
+        LOGICAL*4 a2_l
6f0f47
+        LOGICAL b_l
6f0f47
+        LOGICAL*8 b2_l
6f0f47
+        LOGICAL x_l
6f0f47
+        LOGICAL y_l
6f0f47
+        CHARACTER a_c
6f0f47
+        CHARACTER*4 a2_c
6f0f47
+        CHARACTER b_c
6f0f47
+        CHARACTER*8 b2_c
6f0f47
+        CHARACTER x_c
6f0f47
+        CHARACTER y_c
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(a_l, b_l)                     ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_l, b2_l)                   ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_c, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_c, b2_c)                   ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_l, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_c, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_l, b_l)                 ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_l, b2_l)               ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_c, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_c, b2_c)               ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_l, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_c, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_l, b_l)                     ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_l, b2_l)                   ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_c, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_c, b2_c)                   ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_c, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_l, a_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_l, b_l)                   ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_l, b2_l)                 ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_c, -b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
6f0f47
+        s_r = SIGN(a2_c, -b2_c)                 ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
6f0f47
+        s_r = SIGN(a_c, -b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
6f0f47
+        s_r = SIGN(-a_l, b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - a_c) > 1.0D-6) STOP 24    ! { dg-error "" }
6f0f47
+
6f0f47
+        mx_i = MAX(-a_l, -b_l, x_l, y_l)        ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_l) STOP 25              ! { dg-error "" }
6f0f47
+        mx_i = MAX(-a2_l, -b2_l, x_l, y_l)      ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_l) STOP 26              ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 27   ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 28   ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_l, -b_c, x_c, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 29   ! { dg-error "" }
6f0f47
+
6f0f47
+        mn_i = MIN(-a_l, -b_l, x_l, y_l)        ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a_l) STOP 31             ! { dg-error "" }
6f0f47
+        mn_i = MIN(-a2_l, -b2_l, x_l, y_l)      ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a2_l) STOP 32            ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a2_c, -b2_c, x_c, y_c)      ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a_l, -b_c, x_c, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..d023af5086d
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
6f0f47
@@ -0,0 +1,118 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        LOGICAL a_l
6f0f47
+        LOGICAL*4 a2_l
6f0f47
+        LOGICAL b_l
6f0f47
+        LOGICAL*8 b2_l
6f0f47
+        LOGICAL x_l
6f0f47
+        LOGICAL y_l
6f0f47
+        CHARACTER a_c
6f0f47
+        CHARACTER*4 a2_c
6f0f47
+        CHARACTER b_c
6f0f47
+        CHARACTER*8 b2_c
6f0f47
+        CHARACTER x_c
6f0f47
+        CHARACTER y_c
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(a_l, b_l)                     ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_l, b2_l)                   ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_c, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_c, b2_c)                   ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_l, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_c, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_l, b_l)                 ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_l, b2_l)               ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_c, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_c, b2_c)               ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_l, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_c, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_l, b_l)                     ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_l, b2_l)                   ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_c, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_c, b2_c)                   ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_c, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_l, a_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_l, b_l)                   ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_l, b2_l)                 ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_c, -b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
6f0f47
+        s_r = SIGN(a2_c, -b2_c)                 ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
6f0f47
+        s_r = SIGN(a_c, -b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
6f0f47
+        s_r = SIGN(-a_l, b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - a_c) > 1.0D-6) STOP 24    ! { dg-error "" }
6f0f47
+
6f0f47
+        mx_i = MAX(-a_l, -b_l, x_l, y_l)        ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_l) STOP 25              ! { dg-error "" }
6f0f47
+        mx_i = MAX(-a2_l, -b2_l, x_l, y_l)      ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_l) STOP 26              ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 27   ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 28   ! { dg-error "" }
6f0f47
+        mx_r = MAX(-a_l, -b_c, x_c, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_c) > 1.0D-6) STOP 29   ! { dg-error "" }
6f0f47
+
6f0f47
+        mn_i = MIN(-a_l, -b_l, x_l, y_l)        ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a_l) STOP 31             ! { dg-error "" }
6f0f47
+        mn_i = MIN(-a2_l, -b2_l, x_l, y_l)      ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a2_l) STOP 32            ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a_c, -b_c, x_c, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a2_c, -b2_c, x_c, y_c)      ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
6f0f47
+        mn_r = MIN(-a_l, -b_c, x_c, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..00f8fb88f1b
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
6f0f47
@@ -0,0 +1,118 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        INTEGER a_i/4/
6f0f47
+        INTEGER*4 a2_i/4/
6f0f47
+        CHARACTER b_c
6f0f47
+        CHARACTER*8 b2_c
6f0f47
+        INTEGER x_i/2/
6f0f47
+        CHARACTER y_c
6f0f47
+        REAL a_r/4.0/
6f0f47
+        REAL*4 a2_r/4.0/
6f0f47
+        LOGICAL b_l
6f0f47
+        LOGICAL*8 b2_l
6f0f47
+        REAL x_r/2.0/
6f0f47
+        LOGICAL y_l
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(a_i, b_c)                     ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_i, b2_c)                   ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_r, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_r, b2_l)                   ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_i, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_r, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_i, b_c)                 ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_i, b2_c)               ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_r, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_r, b2_l)               ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_i, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_r, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_i, b_c)                     ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_i, b2_c)                   ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_r, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_r, b2_l)                   ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_r, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_c, a_r)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_i, b_c)                   ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_i, b2_c)                 ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_r, -b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
6f0f47
+        s_r = SIGN(a2_r, -b2_l)                 ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
6f0f47
+        s_r = SIGN(a_r, -b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
6f0f47
+        s_r = SIGN(-a_i, b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - a_r) > 1.0D-6) STOP 24
6f0f47
+
6f0f47
+        mx_i = MAX(-a_i, -b_c, x_i, y_c)        ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_i) STOP 25
6f0f47
+        mx_i = MAX(-a2_i, -b2_c, x_i, y_c)      ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_i) STOP 26
6f0f47
+        mx_r = MAX(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 27
6f0f47
+        mx_r = MAX(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 28
6f0f47
+        mx_r = MAX(-a_i, -b_l, x_r, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 29
6f0f47
+
6f0f47
+        mn_i = MIN(-a_i, -b_c, x_i, y_c)        ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a_i) STOP 31
6f0f47
+        mn_i = MIN(-a2_i, -b2_c, x_i, y_c)      ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a2_i) STOP 32
6f0f47
+        mn_r = MIN(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
6f0f47
+        mn_r = MIN(-a2_r, -b2_l, x_r, y_l)      ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
6f0f47
+        mn_r = MIN(-a_i, -b_l, x_r, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..1d4150d81c0
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
6f0f47
@@ -0,0 +1,118 @@
6f0f47
+! { dg-do compile }
6f0f47
+! { dg-options "-fdec-promotion" }
6f0f47
+!
6f0f47
+! Test promotion between integers and reals in intrinsic operations.
6f0f47
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
6f0f47
+! maxloc.
6f0f47
+!
6f0f47
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
6f0f47
+!             and Jeff Law <law@redhat.com>
6f0f47
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      PROGRAM promotion_int_real
6f0f47
+        REAL l/0.0/
6f0f47
+        INTEGER a_i/4/
6f0f47
+        INTEGER*4 a2_i/4/
6f0f47
+        CHARACTER b_c
6f0f47
+        CHARACTER*8 b2_c
6f0f47
+        INTEGER x_i/2/
6f0f47
+        CHARACTER y_c
6f0f47
+        REAL a_r/4.0/
6f0f47
+        REAL*4 a2_r/4.0/
6f0f47
+        LOGICAL b_l
6f0f47
+        LOGICAL*8 b2_l
6f0f47
+        REAL x_r/2.0/
6f0f47
+        LOGICAL y_l
6f0f47
+
6f0f47
+        INTEGER m_i/0/
6f0f47
+        REAL m_r/0.0/
6f0f47
+
6f0f47
+        INTEGER md_i/0/
6f0f47
+        REAL md_r/0.0/
6f0f47
+
6f0f47
+        INTEGER d_i/0/
6f0f47
+        REAL d_r/0.0/
6f0f47
+
6f0f47
+        INTEGER s_i/0/
6f0f47
+        REAL s_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mn_i/0/
6f0f47
+        REAL mn_r/0.0/
6f0f47
+
6f0f47
+        INTEGER mx_i/0/
6f0f47
+        REAL mx_r/0.0/
6f0f47
+
6f0f47
+        m_i = MOD(a_i, b_c)                     ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 1
6f0f47
+        m_i = MOD(a2_i, b2_c)                   ! { dg-error "" }
6f0f47
+        if (m_i .ne. 1) STOP 2
6f0f47
+        m_r = MOD(a_r, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 3
6f0f47
+        m_r = MOD(a2_r, b2_l)                   ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 4
6f0f47
+        m_r = MOD(a_i, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 5
6f0f47
+        m_r = MOD(a_r, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(m_r - 1.0) > 1.0D-6) STOP 6
6f0f47
+
6f0f47
+        md_i = MODULO(a_i, b_c)                 ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 7
6f0f47
+        md_i = MODULO(a2_i, b2_c)               ! { dg-error "" }
6f0f47
+        if (md_i .ne. 1) STOP 8
6f0f47
+        md_r = MODULO(a_r, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 9
6f0f47
+        md_r = MODULO(a2_r, b2_l)               ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 10
6f0f47
+        md_r = MODULO(a_i, b_l)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 11
6f0f47
+        md_r = MODULO(a_r, b_c)                 ! { dg-error "" }
6f0f47
+        if (abs(md_r - 1.0) > 1.0D-6) STOP 12
6f0f47
+
6f0f47
+        d_i = DIM(a_i, b_c)                     ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 13
6f0f47
+        d_i = DIM(a2_i, b2_c)                   ! { dg-error "" }
6f0f47
+        if (d_i .ne. 1) STOP 14
6f0f47
+        d_r = DIM(a_r, b_l)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 15
6f0f47
+        d_r = DIM(a2_r, b2_l)                   ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 16
6f0f47
+        d_r = DIM(a_r, b_c)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r - 1.0) > 1.0D-6) STOP 17
6f0f47
+        d_r = DIM(b_c, a_r)                     ! { dg-error "" }
6f0f47
+        if (abs(d_r) > 1.0D-6) STOP 18
6f0f47
+
6f0f47
+        s_i = SIGN(-a_i, b_c)                   ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 19
6f0f47
+        s_i = SIGN(-a2_i, b2_c)                 ! { dg-error "" }
6f0f47
+        if (s_i .ne. 4) STOP 20
6f0f47
+        s_r = SIGN(a_r, -b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
6f0f47
+        s_r = SIGN(a2_r, -b2_l)                 ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
6f0f47
+        s_r = SIGN(a_r, -b_c)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
6f0f47
+        s_r = SIGN(-a_i, b_l)                   ! { dg-error "" }
6f0f47
+        if (abs(s_r - a_r) > 1.0D-6) STOP 24
6f0f47
+
6f0f47
+        mx_i = MAX(-a_i, -b_c, x_i, y_c)        ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_i) STOP 25
6f0f47
+        mx_i = MAX(-a2_i, -b2_c, x_i, y_c)      ! { dg-error "" }
6f0f47
+        if (mx_i .ne. x_i) STOP 26
6f0f47
+        mx_r = MAX(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 27
6f0f47
+        mx_r = MAX(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 28
6f0f47
+        mx_r = MAX(-a_i, -b_l, x_r, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mx_r - x_r) > 1.0D-6) STOP 29
6f0f47
+
6f0f47
+        mn_i = MIN(-a_i, -b_c, x_i, y_c)        ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a_i) STOP 31
6f0f47
+        mn_i = MIN(-a2_i, -b2_c, x_i, y_c)      ! { dg-error "" }
6f0f47
+        if (mn_i .ne. -a2_i) STOP 32
6f0f47
+        mn_r = MIN(-a_r, -b_l, x_r, y_l)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
6f0f47
+        mn_r = MIN(-a2_r, -b2_l, x_r, y_l)      ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
6f0f47
+        mn_r = MIN(-a_i, -b_l, x_r, y_c)        ! { dg-error "" }
6f0f47
+        if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
6f0f47
+      END PROGRAM
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..435bf98350c
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
6f0f47
@@ -0,0 +1,40 @@
6f0f47
+!{ dg-do run }
6f0f47
+!{ dg-options "-fdec" }
6f0f47
+!
6f0f47
+! integer types of a smaller kind than expected should be
6f0f47
+! accepted by type specific intrinsic functions
6f0f47
+!
6f0f47
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program test_small_type_promtion
6f0f47
+        implicit none
6f0f47
+        integer(1) :: a = 1
6f0f47
+        integer :: i
6f0f47
+        if (iiabs(-9_1).ne.9) stop 1
6f0f47
+        if (iabs(-9_1).ne.9) stop 2
6f0f47
+        if (iabs(-9_2).ne.9) stop 3
6f0f47
+        if (jiabs(-9_1).ne.9) stop 4
6f0f47
+        if (jiabs(-9_2).ne.9) stop 5
6f0f47
+        if (iishft(1_1, 2).ne.4) stop 6
6f0f47
+        if (jishft(1_1, 2).ne.4) stop 7
6f0f47
+        if (jishft(1_2, 2).ne.4) stop 8
6f0f47
+        if (kishft(1_1, 2).ne.4) stop 9
6f0f47
+        if (kishft(1_2, 2).ne.4) stop 10
6f0f47
+        if (kishft(1_4, 2).ne.4) stop 11
6f0f47
+        if (imod(17_1, 3).ne.2) stop 12
6f0f47
+        if (jmod(17_1, 3).ne.2) stop 13
6f0f47
+        if (jmod(17_2, 3).ne.2) stop 14
6f0f47
+        if (kmod(17_1, 3).ne.2) stop 15
6f0f47
+        if (kmod(17_2, 3).ne.2) stop 16
6f0f47
+        if (kmod(17_4, 3).ne.2) stop 17
6f0f47
+        if (inot(5_1).ne.-6) stop 18
6f0f47
+        if (jnot(5_1).ne.-6) stop 19
6f0f47
+        if (jnot(5_2).ne.-6) stop 20
6f0f47
+        if (knot(5_1).ne.-6) stop 21
6f0f47
+        if (knot(5_2).ne.-6) stop 22
6f0f47
+        if (knot(5_4).ne.-6) stop 23
6f0f47
+        if (isign(-77_1, 1).ne.77) stop 24
6f0f47
+        if (isign(-77_1, -1).ne.-77) stop 25
6f0f47
+        if (isign(-77_2, 1).ne.77) stop 26
6f0f47
+        if (isign(-77_2, -1).ne.-77) stop 27
6f0f47
+      end program
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..7b1697ca665
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
6f0f47
@@ -0,0 +1,40 @@
6f0f47
+!{ dg-do run }
6f0f47
+!{ dg-options "-fdec-intrinsic-ints -fdec-promotion" }
6f0f47
+!
6f0f47
+! integer types of a smaller kind than expected should be
6f0f47
+! accepted by type specific intrinsic functions
6f0f47
+!
6f0f47
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program test_small_type_promtion
6f0f47
+        implicit none
6f0f47
+        integer(1) :: a = 1
6f0f47
+        integer :: i
6f0f47
+        if (iiabs(-9_1).ne.9) stop 1
6f0f47
+        if (iabs(-9_1).ne.9) stop 2
6f0f47
+        if (iabs(-9_2).ne.9) stop 3
6f0f47
+        if (jiabs(-9_1).ne.9) stop 4
6f0f47
+        if (jiabs(-9_2).ne.9) stop 5
6f0f47
+        if (iishft(1_1, 2).ne.4) stop 6
6f0f47
+        if (jishft(1_1, 2).ne.4) stop 7
6f0f47
+        if (jishft(1_2, 2).ne.4) stop 8
6f0f47
+        if (kishft(1_1, 2).ne.4) stop 9
6f0f47
+        if (kishft(1_2, 2).ne.4) stop 10
6f0f47
+        if (kishft(1_4, 2).ne.4) stop 11
6f0f47
+        if (imod(17_1, 3).ne.2) stop 12
6f0f47
+        if (jmod(17_1, 3).ne.2) stop 13
6f0f47
+        if (jmod(17_2, 3).ne.2) stop 14
6f0f47
+        if (kmod(17_1, 3).ne.2) stop 15
6f0f47
+        if (kmod(17_2, 3).ne.2) stop 16
6f0f47
+        if (kmod(17_4, 3).ne.2) stop 17
6f0f47
+        if (inot(5_1).ne.-6) stop 18
6f0f47
+        if (jnot(5_1).ne.-6) stop 19
6f0f47
+        if (jnot(5_2).ne.-6) stop 20
6f0f47
+        if (knot(5_1).ne.-6) stop 21
6f0f47
+        if (knot(5_2).ne.-6) stop 22
6f0f47
+        if (knot(5_4).ne.-6) stop 23
6f0f47
+        if (isign(-77_1, 1).ne.77) stop 24
6f0f47
+        if (isign(-77_1, -1).ne.-77) stop 25
6f0f47
+        if (isign(-77_2, 1).ne.77) stop 26
6f0f47
+        if (isign(-77_2, -1).ne.-77) stop 27
6f0f47
+      end program
6f0f47
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
6f0f47
new file mode 100644
6f0f47
index 00000000000..db8dff6c55d
6f0f47
--- /dev/null
6f0f47
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
6f0f47
@@ -0,0 +1,39 @@
6f0f47
+!{ dg-do compile }
6f0f47
+!{ dg-options "-fdec -fno-dec-promotion" }
6f0f47
+!
6f0f47
+! integer types of a smaller kind than expected should be
6f0f47
+! accepted by type specific intrinsic functions
6f0f47
+!
6f0f47
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
6f0f47
+!
6f0f47
+      program test_small_type_promtion
6f0f47
+        integer(1) :: a = 1
6f0f47
+        integer :: i
6f0f47
+        if (iiabs(-9_1).ne.9) stop 1
6f0f47
+        if (iabs(-9_1).ne.9) stop 2 ! { dg-error "type mismatch in argument" }
6f0f47
+        if (iabs(-9_2).ne.9) stop 3 ! { dg-error "type mismatch in argument" }
6f0f47
+        if (jiabs(-9_1).ne.9) stop 4
6f0f47
+        if (jiabs(-9_2).ne.9) stop 5
6f0f47
+        if (iishft(1_1, 2).ne.4) stop 6
6f0f47
+        if (jishft(1_1, 2).ne.4) stop 7
6f0f47
+        if (jishft(1_2, 2).ne.4) stop 8
6f0f47
+        if (kishft(1_1, 2).ne.4) stop 9
6f0f47
+        if (kishft(1_2, 2).ne.4) stop 10
6f0f47
+        if (kishft(1_4, 2).ne.4) stop 11
6f0f47
+        if (imod(17_1, 3).ne.2) stop 12
6f0f47
+        if (jmod(17_1, 3).ne.2) stop 13
6f0f47
+        if (jmod(17_2, 3).ne.2) stop 14
6f0f47
+        if (kmod(17_1, 3).ne.2) stop 15
6f0f47
+        if (kmod(17_2, 3).ne.2) stop 16
6f0f47
+        if (kmod(17_4, 3).ne.2) stop 17
6f0f47
+        if (inot(5_1).ne.-6) stop 18
6f0f47
+        if (jnot(5_1).ne.-6) stop 19
6f0f47
+        if (jnot(5_2).ne.-6) stop 20
6f0f47
+        if (knot(5_1).ne.-6) stop 21
6f0f47
+        if (knot(5_2).ne.-6) stop 22
6f0f47
+        if (knot(5_4).ne.-6) stop 23
6f0f47
+        if (isign(-77_1, 1).ne.77) stop 24 ! { dg-error "type mismatch in argument" }
6f0f47
+        if (isign(-77_1, -1).ne.-77) stop 25 ! { dg-error "type mismatch in argument" }
6f0f47
+        if (isign(-77_2, 1).ne.77) stop 26 ! { dg-error "type mismatch in argument" }
6f0f47
+        if (isign(-77_2, -1).ne.-77) stop 27 ! { dg-error "type mismatch in argument" }
6f0f47
+      end program
6f0f47
-- 
6f0f47
2.27.0
6f0f47