/* Simplify intrinsic functions at compile-time.
   Copyright (C) 2000-2021 Free Software Foundation, Inc.
   Contributed by Andy Vaught & Katherine Holcomb

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"		/* For BITS_PER_UNIT.  */
#include "gfortran.h"
#include "arith.h"
#include "intrinsic.h"
#include "match.h"
#include "target-memory.h"
#include "constructor.h"
#include "version.h"	/* For version_string.  */

/* Prototypes.  */

static int min_max_choose (gfc_expr *, gfc_expr *, int, bool back_val = false);

gfc_expr gfc_bad_expr;

static gfc_expr *simplify_size (gfc_expr *, gfc_expr *, int);


/* Note that 'simplification' is not just transforming expressions.
   For functions that are not simplified at compile time, range
   checking is done if possible.

   The return convention is that each simplification function returns:

     A new expression node corresponding to the simplified arguments.
     The original arguments are destroyed by the caller, and must not
     be a part of the new expression.

     NULL pointer indicating that no simplification was possible and
     the original expression should remain intact.

     An expression pointer to gfc_bad_expr (a static placeholder)
     indicating that some error has prevented simplification.  The
     error is generated within the function and should be propagated
     upwards

   By the time a simplification function gets control, it has been
   decided that the function call is really supposed to be the
   intrinsic.  No type checking is strictly necessary, since only
   valid types will be passed on.  On the other hand, a simplification
   subroutine may have to look at the type of an argument as part of
   its processing.

   Array arguments are only passed to these subroutines that implement
   the simplification of transformational intrinsics.

   The functions in this file don't have much comment with them, but
   everything is reasonably straight-forward.  The Standard, chapter 13
   is the best comment you'll find for this file anyway.  */

/* Range checks an expression node.  If all goes well, returns the
   node, otherwise returns &gfc_bad_expr and frees the node.  */

static gfc_expr *
range_check (gfc_expr *result, const char *name)
{
  if (result == NULL)
    return &gfc_bad_expr;

  if (result->expr_type != EXPR_CONSTANT)
    return result;

  switch (gfc_range_check (result))
    {
      case ARITH_OK:
	return result;

      case ARITH_OVERFLOW:
	gfc_error ("Result of %s overflows its kind at %L", name,
		   &result->where);
	break;

      case ARITH_UNDERFLOW:
	gfc_error ("Result of %s underflows its kind at %L", name,
		   &result->where);
	break;

      case ARITH_NAN:
	gfc_error ("Result of %s is NaN at %L", name, &result->where);
	break;

      default:
	gfc_error ("Result of %s gives range error for its kind at %L", name,
		   &result->where);
	break;
    }

  gfc_free_expr (result);
  return &gfc_bad_expr;
}


/* A helper function that gets an optional and possibly missing
   kind parameter.  Returns the kind, -1 if something went wrong.  */

static int
get_kind (bt type, gfc_expr *k, const char *name, int default_kind)
{
  int kind;

  if (k == NULL)
    return default_kind;

  if (k->expr_type != EXPR_CONSTANT)
    {
      gfc_error ("KIND parameter of %s at %L must be an initialization "
		 "expression", name, &k->where);
      return -1;
    }

  if (gfc_extract_int (k, &kind)
      || gfc_validate_kind (type, kind, true) < 0)
    {
      gfc_error ("Invalid KIND parameter of %s at %L", name, &k->where);
      return -1;
    }

  return kind;
}


/* Converts an mpz_t signed variable into an unsigned one, assuming
   two's complement representations and a binary width of bitsize.
   The conversion is a no-op unless x is negative; otherwise, it can
   be accomplished by masking out the high bits.  */

static void
convert_mpz_to_unsigned (mpz_t x, int bitsize)
{
  mpz_t mask;

  if (mpz_sgn (x) < 0)
    {
      /* Confirm that no bits above the signed range are unset if we
	 are doing range checking.  */
      if (flag_range_check != 0)
	gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);

      mpz_init_set_ui (mask, 1);
      mpz_mul_2exp (mask, mask, bitsize);
      mpz_sub_ui (mask, mask, 1);

      mpz_and (x, x, mask);

      mpz_clear (mask);
    }
  else
    {
      /* Confirm that no bits above the signed range are set if we
	 are doing range checking.  */
      if (flag_range_check != 0)
	gcc_assert (mpz_scan1 (x, bitsize-1) == ULONG_MAX);
    }
}


/* Converts an mpz_t unsigned variable into a signed one, assuming
   two's complement representations and a binary width of bitsize.
   If the bitsize-1 bit is set, this is taken as a sign bit and
   the number is converted to the corresponding negative number.  */

void
gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
{
  mpz_t mask;

  /* Confirm that no bits above the unsigned range are set if we are
     doing range checking.  */
  if (flag_range_check != 0)
    gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);

  if (mpz_tstbit (x, bitsize - 1) == 1)
    {
      mpz_init_set_ui (mask, 1);
      mpz_mul_2exp (mask, mask, bitsize);
      mpz_sub_ui (mask, mask, 1);

      /* We negate the number by hand, zeroing the high bits, that is
	 make it the corresponding positive number, and then have it
	 negated by GMP, giving the correct representation of the
	 negative number.  */
      mpz_com (x, x);
      mpz_add_ui (x, x, 1);
      mpz_and (x, x, mask);

      mpz_neg (x, x);

      mpz_clear (mask);
    }
}


/* Test that the expression is a constant array, simplifying if
   we are dealing with a parameter array.  */

static bool
is_constant_array_expr (gfc_expr *e)
{
  gfc_constructor *c;
  bool array_OK = true;
  mpz_t size;

  if (e == NULL)
    return true;

  if (e->expr_type == EXPR_VARIABLE && e->rank > 0
      && e->symtree->n.sym->attr.flavor == FL_PARAMETER)
    gfc_simplify_expr (e, 1);

  if (e->expr_type != EXPR_ARRAY || !gfc_is_constant_expr (e))
    return false;

  for (c = gfc_constructor_first (e->value.constructor);
       c; c = gfc_constructor_next (c))
    if (c->expr->expr_type != EXPR_CONSTANT
	  && c->expr->expr_type != EXPR_STRUCTURE)
      {
	array_OK = false;
	break;
      }

  /* Check and expand the constructor.  */
  if (!array_OK && gfc_init_expr_flag && e->rank == 1)
    {
      array_OK = gfc_reduce_init_expr (e);
      /* gfc_reduce_init_expr resets the flag.  */
      gfc_init_expr_flag = true;
    }
  else
    return array_OK;

  /* Recheck to make sure that any EXPR_ARRAYs have gone.  */
  for (c = gfc_constructor_first (e->value.constructor);
       c; c = gfc_constructor_next (c))
    if (c->expr->expr_type != EXPR_CONSTANT
	  && c->expr->expr_type != EXPR_STRUCTURE)
      return false;

  /* Make sure that the array has a valid shape.  */
  if (e->shape == NULL && e->rank == 1)
    {
      if (!gfc_array_size(e, &size))
	return false;
      e->shape = gfc_get_shape (1);
      mpz_init_set (e->shape[0], size);
      mpz_clear (size);
    }

  return array_OK;
}

/* Test for a size zero array.  */
bool
gfc_is_size_zero_array (gfc_expr *array)
{

  if (array->rank == 0)
    return false;

  if (array->expr_type == EXPR_VARIABLE && array->rank > 0
      && array->symtree->n.sym->attr.flavor == FL_PARAMETER
      && array->shape != NULL)
    {
      for (int i = 0; i < array->rank; i++)
	if (mpz_cmp_si (array->shape[i], 0) <= 0)
	  return true;

      return false;
    }

  if (array->expr_type == EXPR_ARRAY)
    return array->value.constructor == NULL;

  return false;
}


/* Initialize a transformational result expression with a given value.  */

static void
init_result_expr (gfc_expr *e, int init, gfc_expr *array)
{
  if (e && e->expr_type == EXPR_ARRAY)
    {
      gfc_constructor *ctor = gfc_constructor_first (e->value.constructor);
      while (ctor)
	{
	  init_result_expr (ctor->expr, init, array);
	  ctor = gfc_constructor_next (ctor);
	}
    }
  else if (e && e->expr_type == EXPR_CONSTANT)
    {
      int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
      HOST_WIDE_INT length;
      gfc_char_t *string;

      switch (e->ts.type)
	{
	  case BT_LOGICAL:
	    e->value.logical = (init ? 1 : 0);
	    break;

	  case BT_INTEGER:
	    if (init == INT_MIN)
	      mpz_set (e->value.integer, gfc_integer_kinds[i].min_int);
	    else if (init == INT_MAX)
	      mpz_set (e->value.integer, gfc_integer_kinds[i].huge);
	    else
	      mpz_set_si (e->value.integer, init);
	    break;

	  case BT_REAL:
	    if (init == INT_MIN)
	      {
		mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
		mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
	      }
	    else if (init == INT_MAX)
	      mpfr_set (e->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
	    else
	      mpfr_set_si (e->value.real, init, GFC_RND_MODE);
	    break;

	  case BT_COMPLEX:
	    mpc_set_si (e->value.complex, init, GFC_MPC_RND_MODE);
	    break;

	  case BT_CHARACTER:
	    if (init == INT_MIN)
	      {
		gfc_expr *len = gfc_simplify_len (array, NULL);
		gfc_extract_hwi (len, &length);
		string = gfc_get_wide_string (length + 1);
		gfc_wide_memset (string, 0, length);
	      }
	    else if (init == INT_MAX)
	      {
		gfc_expr *len = gfc_simplify_len (array, NULL);
		gfc_extract_hwi (len, &length);
		string = gfc_get_wide_string (length + 1);
		gfc_wide_memset (string, 255, length);
	      }
	    else
	      {
		length = 0;
		string = gfc_get_wide_string (1);
	      }

	    string[length] = '\0';
	    e->value.character.length = length;
	    e->value.character.string = string;
	    break;

	  default:
	    gcc_unreachable();
	}
    }
  else
    gcc_unreachable();
}


/* Helper function for gfc_simplify_dot_product() and gfc_simplify_matmul;
   if conj_a is true, the matrix_a is complex conjugated.  */

static gfc_expr *
compute_dot_product (gfc_expr *matrix_a, int stride_a, int offset_a,
		     gfc_expr *matrix_b, int stride_b, int offset_b,
		     bool conj_a)
{
  gfc_expr *result, *a, *b, *c;

  /* Set result to an INTEGER(1) 0 for numeric types and .false. for
     LOGICAL.  Mixed-mode math in the loop will promote result to the
     correct type and kind.  */
  if (matrix_a->ts.type == BT_LOGICAL)
    result = gfc_get_logical_expr (gfc_default_logical_kind, NULL, false);
  else
    result = gfc_get_int_expr (1, NULL, 0);
  result->where = matrix_a->where;

  a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);
  b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
  while (a && b)
    {
      /* Copying of expressions is required as operands are free'd
	 by the gfc_arith routines.  */
      switch (result->ts.type)
	{
	  case BT_LOGICAL:
	    result = gfc_or (result,
			     gfc_and (gfc_copy_expr (a),
				      gfc_copy_expr (b)));
	    break;

	  case BT_INTEGER:
	  case BT_REAL:
	  case BT_COMPLEX:
	    if (conj_a && a->ts.type == BT_COMPLEX)
	      c = gfc_simplify_conjg (a);
	    else
	      c = gfc_copy_expr (a);
	    result = gfc_add (result, gfc_multiply (c, gfc_copy_expr (b)));
	    break;

	  default:
	    gcc_unreachable();
	}

      offset_a += stride_a;
      a = gfc_constructor_lookup_expr (matrix_a->value.constructor, offset_a);

      offset_b += stride_b;
      b = gfc_constructor_lookup_expr (matrix_b->value.constructor, offset_b);
    }

  return result;
}


/* Build a result expression for transformational intrinsics,
   depending on DIM.  */

static gfc_expr *
transformational_result (gfc_expr *array, gfc_expr *dim, bt type,
			 int kind, locus* where)
{
  gfc_expr *result;
  int i, nelem;

  if (!dim || array->rank == 1)
    return gfc_get_constant_expr (type, kind, where);

  result = gfc_get_array_expr (type, kind, where);
  result->shape = gfc_copy_shape_excluding (array->shape, array->rank, dim);
  result->rank = array->rank - 1;

  /* gfc_array_size() would count the number of elements in the constructor,
     we have not built those yet.  */
  nelem = 1;
  for  (i = 0; i < result->rank; ++i)
    nelem *= mpz_get_ui (result->shape[i]);

  for (i = 0; i < nelem; ++i)
    {
      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_get_constant_expr (type, kind, where),
				   NULL);
    }

  return result;
}


typedef gfc_expr* (*transformational_op)(gfc_expr*, gfc_expr*);

/* Wrapper function, implements 'op1 += 1'. Only called if MASK
   of COUNT intrinsic is .TRUE..

   Interface and implementation mimics arith functions as
   gfc_add, gfc_multiply, etc.  */

static gfc_expr *
gfc_count (gfc_expr *op1, gfc_expr *op2)
{
  gfc_expr *result;

  gcc_assert (op1->ts.type == BT_INTEGER);
  gcc_assert (op2->ts.type == BT_LOGICAL);
  gcc_assert (op2->value.logical);

  result = gfc_copy_expr (op1);
  mpz_add_ui (result->value.integer, result->value.integer, 1);

  gfc_free_expr (op1);
  gfc_free_expr (op2);
  return result;
}


/* Transforms an ARRAY with operation OP, according to MASK, to a
   scalar RESULT. E.g. called if

     REAL, PARAMETER :: array(n, m) = ...
     REAL, PARAMETER :: s = SUM(array)

  where OP == gfc_add().  */

static gfc_expr *
simplify_transformation_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
				   transformational_op op)
{
  gfc_expr *a, *m;
  gfc_constructor *array_ctor, *mask_ctor;

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  array_ctor = gfc_constructor_first (array->value.constructor);
  mask_ctor = NULL;
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);

  while (array_ctor)
    {
      a = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);

      /* A constant MASK equals .TRUE. here and can be ignored.  */
      if (mask_ctor)
	{
	  m = mask_ctor->expr;
	  mask_ctor = gfc_constructor_next (mask_ctor);
	  if (!m->value.logical)
	    continue;
	}

      result = op (result, gfc_copy_expr (a));
      if (!result)
	return result;
    }

  return result;
}

/* Transforms an ARRAY with operation OP, according to MASK, to an
   array RESULT. E.g. called if

     REAL, PARAMETER :: array(n, m) = ...
     REAL, PARAMETER :: s(n) = PROD(array, DIM=1)

   where OP == gfc_multiply().
   The result might be post processed using post_op.  */

static gfc_expr *
simplify_transformation_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *dim,
				  gfc_expr *mask, transformational_op op,
				  transformational_op post_op)
{
  mpz_t size;
  int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
  gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
  gfc_constructor *array_ctor, *mask_ctor, *result_ctor;

  int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
      sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
      tmpstride[GFC_MAX_DIMENSIONS];

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  /* Build an indexed table for array element expressions to minimize
     linked-list traversal. Masked elements are set to NULL.  */
  gfc_array_size (array, &size);
  arraysize = mpz_get_ui (size);
  mpz_clear (size);

  arrayvec = XCNEWVEC (gfc_expr*, arraysize);

  array_ctor = gfc_constructor_first (array->value.constructor);
  mask_ctor = NULL;
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);

  for (i = 0; i < arraysize; ++i)
    {
      arrayvec[i] = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);

      if (mask_ctor)
	{
	  if (!mask_ctor->expr->value.logical)
	    arrayvec[i] = NULL;

	  mask_ctor = gfc_constructor_next (mask_ctor);
	}
    }

  /* Same for the result expression.  */
  gfc_array_size (result, &size);
  resultsize = mpz_get_ui (size);
  mpz_clear (size);

  resultvec = XCNEWVEC (gfc_expr*, resultsize);
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      resultvec[i] = result_ctor->expr;
      result_ctor = gfc_constructor_next (result_ctor);
    }

  gfc_extract_int (dim, &dim_index);
  dim_index -= 1;               /* zero-base index */
  dim_extent = 0;
  dim_stride = 0;

  for (i = 0, n = 0; i < array->rank; ++i)
    {
      count[i] = 0;
      tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
      if (i == dim_index)
	{
	  dim_extent = mpz_get_si (array->shape[i]);
	  dim_stride = tmpstride[i];
	  continue;
	}

      extent[n] = mpz_get_si (array->shape[i]);
      sstride[n] = tmpstride[i];
      dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
      n += 1;
    }

  done = resultsize <= 0;
  base = arrayvec;
  dest = resultvec;
  while (!done)
    {
      for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
	if (*src)
	  *dest = op (*dest, gfc_copy_expr (*src));

      if (post_op)
	*dest = post_op (*dest, *dest);

      count[0]++;
      base += sstride[0];
      dest += dstride[0];

      n = 0;
      while (!done && count[n] == extent[n])
	{
	  count[n] = 0;
	  base -= sstride[n] * extent[n];
	  dest -= dstride[n] * extent[n];

	  n++;
	  if (n < result->rank)
	    {
	      /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
		 times, we'd warn for the last iteration, because the
		 array index will have already been incremented to the
		 array sizes, and we can't tell that this must make
		 the test against result->rank false, because ranks
		 must not exceed GFC_MAX_DIMENSIONS.  */
	      GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
	      count[n]++;
	      base += sstride[n];
	      dest += dstride[n];
	      GCC_DIAGNOSTIC_POP
	    }
	  else
	    done = true;
       }
    }

  /* Place updated expression in result constructor.  */
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      result_ctor->expr = resultvec[i];
      result_ctor = gfc_constructor_next (result_ctor);
    }

  free (arrayvec);
  free (resultvec);
  return result;
}


static gfc_expr *
simplify_transformation (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
			 int init_val, transformational_op op)
{
  gfc_expr *result;
  bool size_zero;

  size_zero = gfc_is_size_zero_array (array);

  if (!(is_constant_array_expr (array) || size_zero)
      || !gfc_is_constant_expr (dim))
    return NULL;

  if (mask
      && !is_constant_array_expr (mask)
      && mask->expr_type != EXPR_CONSTANT)
    return NULL;

  result = transformational_result (array, dim, array->ts.type,
				    array->ts.kind, &array->where);
  init_result_expr (result, init_val, array);

  if (size_zero)
    return result;

  return !dim || array->rank == 1 ?
    simplify_transformation_to_scalar (result, array, mask, op) :
    simplify_transformation_to_array (result, array, dim, mask, op, NULL);
}


/********************** Simplification functions *****************************/

gfc_expr *
gfc_simplify_abs (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (e->ts.type)
    {
      case BT_INTEGER:
	result = gfc_get_constant_expr (BT_INTEGER, e->ts.kind, &e->where);
	mpz_abs (result->value.integer, e->value.integer);
	return range_check (result, "IABS");

      case BT_REAL:
	result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
	mpfr_abs (result->value.real, e->value.real, GFC_RND_MODE);
	return range_check (result, "ABS");

      case BT_COMPLEX:
	gfc_set_model_kind (e->ts.kind);
	result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
	mpc_abs (result->value.real, e->value.complex, GFC_RND_MODE);
	return range_check (result, "CABS");

      default:
	gfc_internal_error ("gfc_simplify_abs(): Bad type");
    }
}


static gfc_expr *
simplify_achar_char (gfc_expr *e, gfc_expr *k, const char *name, bool ascii)
{
  gfc_expr *result;
  int kind;
  bool too_large = false;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = get_kind (BT_CHARACTER, k, name, gfc_default_character_kind);
  if (kind == -1)
    return &gfc_bad_expr;

  if (mpz_cmp_si (e->value.integer, 0) < 0)
    {
      gfc_error ("Argument of %s function at %L is negative", name,
		 &e->where);
      return &gfc_bad_expr;
    }

  if (ascii && warn_surprising && mpz_cmp_si (e->value.integer, 127) > 0)
    gfc_warning (OPT_Wsurprising,
		 "Argument of %s function at %L outside of range [0,127]",
		 name, &e->where);

  if (kind == 1 && mpz_cmp_si (e->value.integer, 255) > 0)
    too_large = true;
  else if (kind == 4)
    {
      mpz_t t;
      mpz_init_set_ui (t, 2);
      mpz_pow_ui (t, t, 32);
      mpz_sub_ui (t, t, 1);
      if (mpz_cmp (e->value.integer, t) > 0)
	too_large = true;
      mpz_clear (t);
    }

  if (too_large)
    {
      gfc_error ("Argument of %s function at %L is too large for the "
		 "collating sequence of kind %d", name, &e->where, kind);
      return &gfc_bad_expr;
    }

  result = gfc_get_character_expr (kind, &e->where, NULL, 1);
  result->value.character.string[0] = mpz_get_ui (e->value.integer);

  return result;
}



/* We use the processor's collating sequence, because all
   systems that gfortran currently works on are ASCII.  */

gfc_expr *
gfc_simplify_achar (gfc_expr *e, gfc_expr *k)
{
  return simplify_achar_char (e, k, "ACHAR", true);
}


gfc_expr *
gfc_simplify_acos (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (x->ts.type)
    {
      case BT_REAL:
	if (mpfr_cmp_si (x->value.real, 1) > 0
	    || mpfr_cmp_si (x->value.real, -1) < 0)
	  {
	    gfc_error ("Argument of ACOS at %L must be between -1 and 1",
		       &x->where);
	    return &gfc_bad_expr;
	  }
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpc_acos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_acos(): Bad type");
    }

  return range_check (result, "ACOS");
}

gfc_expr *
gfc_simplify_acosh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (x->ts.type)
    {
      case BT_REAL:
	if (mpfr_cmp_si (x->value.real, 1) < 0)
	  {
	    gfc_error ("Argument of ACOSH at %L must not be less than 1",
		       &x->where);
	    return &gfc_bad_expr;
	  }

	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpfr_acosh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpc_acosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_acosh(): Bad type");
    }

  return range_check (result, "ACOSH");
}

gfc_expr *
gfc_simplify_adjustl (gfc_expr *e)
{
  gfc_expr *result;
  int count, i, len;
  gfc_char_t ch;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  len = e->value.character.length;

  for (count = 0, i = 0; i < len; ++i)
    {
      ch = e->value.character.string[i];
      if (ch != ' ')
	break;
      ++count;
    }

  result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
  for (i = 0; i < len - count; ++i)
    result->value.character.string[i] = e->value.character.string[count + i];

  return result;
}


gfc_expr *
gfc_simplify_adjustr (gfc_expr *e)
{
  gfc_expr *result;
  int count, i, len;
  gfc_char_t ch;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  len = e->value.character.length;

  for (count = 0, i = len - 1; i >= 0; --i)
    {
      ch = e->value.character.string[i];
      if (ch != ' ')
	break;
      ++count;
    }

  result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, len);
  for (i = 0; i < count; ++i)
    result->value.character.string[i] = ' ';

  for (i = count; i < len; ++i)
    result->value.character.string[i] = e->value.character.string[i - count];

  return result;
}


gfc_expr *
gfc_simplify_aimag (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
  mpfr_set (result->value.real, mpc_imagref (e->value.complex), GFC_RND_MODE);

  return range_check (result, "AIMAG");
}


gfc_expr *
gfc_simplify_aint (gfc_expr *e, gfc_expr *k)
{
  gfc_expr *rtrunc, *result;
  int kind;

  kind = get_kind (BT_REAL, k, "AINT", e->ts.kind);
  if (kind == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  rtrunc = gfc_copy_expr (e);
  mpfr_trunc (rtrunc->value.real, e->value.real);

  result = gfc_real2real (rtrunc, kind);

  gfc_free_expr (rtrunc);

  return range_check (result, "AINT");
}


gfc_expr *
gfc_simplify_all (gfc_expr *mask, gfc_expr *dim)
{
  return simplify_transformation (mask, dim, NULL, true, gfc_and);
}


gfc_expr *
gfc_simplify_dint (gfc_expr *e)
{
  gfc_expr *rtrunc, *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  rtrunc = gfc_copy_expr (e);
  mpfr_trunc (rtrunc->value.real, e->value.real);

  result = gfc_real2real (rtrunc, gfc_default_double_kind);

  gfc_free_expr (rtrunc);

  return range_check (result, "DINT");
}


gfc_expr *
gfc_simplify_dreal (gfc_expr *e)
{
  gfc_expr *result = NULL;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
  mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);

  return range_check (result, "DREAL");
}


gfc_expr *
gfc_simplify_anint (gfc_expr *e, gfc_expr *k)
{
  gfc_expr *result;
  int kind;

  kind = get_kind (BT_REAL, k, "ANINT", e->ts.kind);
  if (kind == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (e->ts.type, kind, &e->where);
  mpfr_round (result->value.real, e->value.real);

  return range_check (result, "ANINT");
}


gfc_expr *
gfc_simplify_and (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int kind;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;

  switch (x->ts.type)
    {
      case BT_INTEGER:
	result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
	mpz_and (result->value.integer, x->value.integer, y->value.integer);
	return range_check (result, "AND");

      case BT_LOGICAL:
	return gfc_get_logical_expr (kind, &x->where,
				     x->value.logical && y->value.logical);

      default:
	gcc_unreachable ();
    }
}


gfc_expr *
gfc_simplify_any (gfc_expr *mask, gfc_expr *dim)
{
  return simplify_transformation (mask, dim, NULL, false, gfc_or);
}


gfc_expr *
gfc_simplify_dnint (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &e->where);
  mpfr_round (result->value.real, e->value.real);

  return range_check (result, "DNINT");
}


gfc_expr *
gfc_simplify_asin (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (x->ts.type)
    {
      case BT_REAL:
	if (mpfr_cmp_si (x->value.real, 1) > 0
	    || mpfr_cmp_si (x->value.real, -1) < 0)
	  {
	    gfc_error ("Argument of ASIN at %L must be between -1 and 1",
		       &x->where);
	    return &gfc_bad_expr;
	  }
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpc_asin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_asin(): Bad type");
    }

  return range_check (result, "ASIN");
}


/* Convert radians to degrees, i.e., x * 180 / pi.  */

static void
rad2deg (mpfr_t x)
{
  mpfr_t tmp;

  mpfr_init (tmp);
  mpfr_const_pi (tmp, GFC_RND_MODE);
  mpfr_mul_ui (x, x, 180, GFC_RND_MODE);
  mpfr_div (x, x, tmp, GFC_RND_MODE);
  mpfr_clear (tmp);
}


/* Simplify ACOSD(X) where the returned value has units of degree.  */

gfc_expr *
gfc_simplify_acosd (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  if (mpfr_cmp_si (x->value.real, 1) > 0
      || mpfr_cmp_si (x->value.real, -1) < 0)
    {
      gfc_error ("Argument of ACOSD at %L must be between -1 and 1",
		 &x->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_acos (result->value.real, x->value.real, GFC_RND_MODE);
  rad2deg (result->value.real);

  return range_check (result, "ACOSD");
}


/* Simplify asind (x) where the returned value has units of degree. */

gfc_expr *
gfc_simplify_asind (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  if (mpfr_cmp_si (x->value.real, 1) > 0
      || mpfr_cmp_si (x->value.real, -1) < 0)
    {
      gfc_error ("Argument of ASIND at %L must be between -1 and 1",
		 &x->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_asin (result->value.real, x->value.real, GFC_RND_MODE);
  rad2deg (result->value.real);

  return range_check (result, "ASIND");
}


/* Simplify atand (x) where the returned value has units of degree. */

gfc_expr *
gfc_simplify_atand (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
  rad2deg (result->value.real);

  return range_check (result, "ATAND");
}


gfc_expr *
gfc_simplify_asinh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_asinh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_asinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_asinh(): Bad type");
    }

  return range_check (result, "ASINH");
}


gfc_expr *
gfc_simplify_atan (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_atan (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_atan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_atan(): Bad type");
    }

  return range_check (result, "ATAN");
}


gfc_expr *
gfc_simplify_atanh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (x->ts.type)
    {
      case BT_REAL:
	if (mpfr_cmp_si (x->value.real, 1) >= 0
	    || mpfr_cmp_si (x->value.real, -1) <= 0)
	  {
	    gfc_error ("Argument of ATANH at %L must be inside the range -1 "
		       "to 1", &x->where);
	    return &gfc_bad_expr;
	  }
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpfr_atanh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	mpc_atanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_atanh(): Bad type");
    }

  return range_check (result, "ATANH");
}


gfc_expr *
gfc_simplify_atan2 (gfc_expr *y, gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  if (mpfr_zero_p (y->value.real) && mpfr_zero_p (x->value.real))
    {
      gfc_error ("If first argument of ATAN2 at %L is zero, then the "
		 "second argument must not be zero", &y->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "ATAN2");
}


gfc_expr *
gfc_simplify_bessel_j0 (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_j0 (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_J0");
}


gfc_expr *
gfc_simplify_bessel_j1 (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_j1 (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_J1");
}


gfc_expr *
gfc_simplify_bessel_jn (gfc_expr *order, gfc_expr *x)
{
  gfc_expr *result;
  long n;

  if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
    return NULL;

  n = mpz_get_si (order->value.integer);
  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_jn (result->value.real, n, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_JN");
}


/* Simplify transformational form of JN and YN.  */

static gfc_expr *
gfc_simplify_bessel_n2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x,
			bool jn)
{
  gfc_expr *result;
  gfc_expr *e;
  long n1, n2;
  int i;
  mpfr_t x2rev, last1, last2;

  if (x->expr_type != EXPR_CONSTANT || order1->expr_type != EXPR_CONSTANT
      || order2->expr_type != EXPR_CONSTANT)
    return NULL;

  n1 = mpz_get_si (order1->value.integer);
  n2 = mpz_get_si (order2->value.integer);
  result = gfc_get_array_expr (x->ts.type, x->ts.kind, &x->where);
  result->rank = 1;
  result->shape = gfc_get_shape (1);
  mpz_init_set_ui (result->shape[0], MAX (n2-n1+1, 0));

  if (n2 < n1)
    return result;

  /* Special case: x == 0; it is J0(0.0) == 1, JN(N > 0, 0.0) == 0; and
     YN(N, 0.0) = -Inf.  */

  if (mpfr_cmp_ui (x->value.real, 0.0) == 0)
    {
      if (!jn && flag_range_check)
	{
	  gfc_error ("Result of BESSEL_YN is -INF at %L", &result->where);
 	  gfc_free_expr (result);
	  return &gfc_bad_expr;
	}

      if (jn && n1 == 0)
	{
	  e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	  mpfr_set_ui (e->value.real, 1, GFC_RND_MODE);
	  gfc_constructor_append_expr (&result->value.constructor, e,
				       &x->where);
	  n1++;
	}

      for (i = n1; i <= n2; i++)
	{
	  e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
	  if (jn)
	    mpfr_set_ui (e->value.real, 0, GFC_RND_MODE);
	  else
	    mpfr_set_inf (e->value.real, -1);
	  gfc_constructor_append_expr (&result->value.constructor, e,
				       &x->where);
	}

      return result;
    }

  /* Use the faster but more verbose recurrence algorithm. Bessel functions
     are stable for downward recursion and Neumann functions are stable
     for upward recursion. It is
       x2rev = 2.0/x,
       J(N-1, x) = x2rev * N * J(N, x) - J(N+1, x),
       Y(N+1, x) = x2rev * N * Y(N, x) - Y(N-1, x).
     Cf. http://dlmf.nist.gov/10.74#iv and http://dlmf.nist.gov/10.6#E1  */

  gfc_set_model_kind (x->ts.kind);

  /* Get first recursion anchor.  */

  mpfr_init (last1);
  if (jn)
    mpfr_jn (last1, n2, x->value.real, GFC_RND_MODE);
  else
    mpfr_yn (last1, n1, x->value.real, GFC_RND_MODE);

  e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (e->value.real, last1, GFC_RND_MODE);
  if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
    {
      mpfr_clear (last1);
      gfc_free_expr (e);
      gfc_free_expr (result);
      return &gfc_bad_expr;
    }
  gfc_constructor_append_expr (&result->value.constructor, e, &x->where);

  if (n1 == n2)
    {
      mpfr_clear (last1);
      return result;
    }

  /* Get second recursion anchor.  */

  mpfr_init (last2);
  if (jn)
    mpfr_jn (last2, n2-1, x->value.real, GFC_RND_MODE);
  else
    mpfr_yn (last2, n1+1, x->value.real, GFC_RND_MODE);

  e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (e->value.real, last2, GFC_RND_MODE);
  if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
    {
      mpfr_clear (last1);
      mpfr_clear (last2);
      gfc_free_expr (e);
      gfc_free_expr (result);
      return &gfc_bad_expr;
    }
  if (jn)
    gfc_constructor_insert_expr (&result->value.constructor, e, &x->where, -2);
  else
    gfc_constructor_append_expr (&result->value.constructor, e, &x->where);

  if (n1 + 1 == n2)
    {
      mpfr_clear (last1);
      mpfr_clear (last2);
      return result;
    }

  /* Start actual recursion.  */

  mpfr_init (x2rev);
  mpfr_ui_div (x2rev, 2, x->value.real, GFC_RND_MODE);

  for (i = 2; i <= n2-n1; i++)
    {
      e = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

      /* Special case: For YN, if the previous N gave -INF, set
	 also N+1 to -INF.  */
      if (!jn && !flag_range_check && mpfr_inf_p (last2))
	{
	  mpfr_set_inf (e->value.real, -1);
	  gfc_constructor_append_expr (&result->value.constructor, e,
				       &x->where);
	  continue;
	}

      mpfr_mul_si (e->value.real, x2rev, jn ? (n2-i+1) : (n1+i-1),
		   GFC_RND_MODE);
      mpfr_mul (e->value.real, e->value.real, last2, GFC_RND_MODE);
      mpfr_sub (e->value.real, e->value.real, last1, GFC_RND_MODE);

      if (range_check (e, jn ? "BESSEL_JN" : "BESSEL_YN") == &gfc_bad_expr)
	{
	  /* Range_check frees "e" in that case.  */
	  e = NULL;
	  goto error;
	}

      if (jn)
	gfc_constructor_insert_expr (&result->value.constructor, e, &x->where,
				     -i-1);
      else
	gfc_constructor_append_expr (&result->value.constructor, e, &x->where);

      mpfr_set (last1, last2, GFC_RND_MODE);
      mpfr_set (last2, e->value.real, GFC_RND_MODE);
    }

  mpfr_clear (last1);
  mpfr_clear (last2);
  mpfr_clear (x2rev);
  return result;

error:
  mpfr_clear (last1);
  mpfr_clear (last2);
  mpfr_clear (x2rev);
  gfc_free_expr (e);
  gfc_free_expr (result);
  return &gfc_bad_expr;
}


gfc_expr *
gfc_simplify_bessel_jn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
{
  return gfc_simplify_bessel_n2 (order1, order2, x, true);
}


gfc_expr *
gfc_simplify_bessel_y0 (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_y0 (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_Y0");
}


gfc_expr *
gfc_simplify_bessel_y1 (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_y1 (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_Y1");
}


gfc_expr *
gfc_simplify_bessel_yn (gfc_expr *order, gfc_expr *x)
{
  gfc_expr *result;
  long n;

  if (x->expr_type != EXPR_CONSTANT || order->expr_type != EXPR_CONSTANT)
    return NULL;

  n = mpz_get_si (order->value.integer);
  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_yn (result->value.real, n, x->value.real, GFC_RND_MODE);

  return range_check (result, "BESSEL_YN");
}


gfc_expr *
gfc_simplify_bessel_yn2 (gfc_expr *order1, gfc_expr *order2, gfc_expr *x)
{
  return gfc_simplify_bessel_n2 (order1, order2, x, false);
}


gfc_expr *
gfc_simplify_bit_size (gfc_expr *e)
{
  int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  return gfc_get_int_expr (e->ts.kind, &e->where,
			   gfc_integer_kinds[i].bit_size);
}


gfc_expr *
gfc_simplify_btest (gfc_expr *e, gfc_expr *bit)
{
  int b;

  if (e->expr_type != EXPR_CONSTANT || bit->expr_type != EXPR_CONSTANT)
    return NULL;

  if (gfc_extract_int (bit, &b) || b < 0)
    return gfc_get_logical_expr (gfc_default_logical_kind, &e->where, false);

  return gfc_get_logical_expr (gfc_default_logical_kind, &e->where,
			       mpz_tstbit (e->value.integer, b));
}


static int
compare_bitwise (gfc_expr *i, gfc_expr *j)
{
  mpz_t x, y;
  int k, res;

  gcc_assert (i->ts.type == BT_INTEGER);
  gcc_assert (j->ts.type == BT_INTEGER);

  mpz_init_set (x, i->value.integer);
  k = gfc_validate_kind (i->ts.type, i->ts.kind, false);
  convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);

  mpz_init_set (y, j->value.integer);
  k = gfc_validate_kind (j->ts.type, j->ts.kind, false);
  convert_mpz_to_unsigned (y, gfc_integer_kinds[k].bit_size);

  res = mpz_cmp (x, y);
  mpz_clear (x);
  mpz_clear (y);
  return res;
}


gfc_expr *
gfc_simplify_bge (gfc_expr *i, gfc_expr *j)
{
  if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
			       compare_bitwise (i, j) >= 0);
}


gfc_expr *
gfc_simplify_bgt (gfc_expr *i, gfc_expr *j)
{
  if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
			       compare_bitwise (i, j) > 0);
}


gfc_expr *
gfc_simplify_ble (gfc_expr *i, gfc_expr *j)
{
  if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
			       compare_bitwise (i, j) <= 0);
}


gfc_expr *
gfc_simplify_blt (gfc_expr *i, gfc_expr *j)
{
  if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &i->where,
			       compare_bitwise (i, j) < 0);
}


gfc_expr *
gfc_simplify_ceiling (gfc_expr *e, gfc_expr *k)
{
  gfc_expr *ceil, *result;
  int kind;

  kind = get_kind (BT_INTEGER, k, "CEILING", gfc_default_integer_kind);
  if (kind == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  ceil = gfc_copy_expr (e);
  mpfr_ceil (ceil->value.real, e->value.real);

  result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
  gfc_mpfr_to_mpz (result->value.integer, ceil->value.real, &e->where);

  gfc_free_expr (ceil);

  return range_check (result, "CEILING");
}


gfc_expr *
gfc_simplify_char (gfc_expr *e, gfc_expr *k)
{
  return simplify_achar_char (e, k, "CHAR", false);
}


/* Common subroutine for simplifying CMPLX, COMPLEX and DCMPLX.  */

static gfc_expr *
simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT
      || (y != NULL && y->expr_type != EXPR_CONSTANT))
    return NULL;

  result = gfc_get_constant_expr (BT_COMPLEX, kind, &x->where);

  switch (x->ts.type)
    {
      case BT_INTEGER:
	mpc_set_z (result->value.complex, x->value.integer, GFC_MPC_RND_MODE);
	break;

      case BT_REAL:
	mpc_set_fr (result->value.complex, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_set (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (x)");
    }

  if (!y)
    return range_check (result, name);

  switch (y->ts.type)
    {
      case BT_INTEGER:
	mpfr_set_z (mpc_imagref (result->value.complex),
		    y->value.integer, GFC_RND_MODE);
	break;

      case BT_REAL:
	mpfr_set (mpc_imagref (result->value.complex),
		  y->value.real, GFC_RND_MODE);
	break;

      default:
	gfc_internal_error ("gfc_simplify_dcmplx(): Bad type (y)");
    }

  return range_check (result, name);
}


gfc_expr *
gfc_simplify_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *k)
{
  int kind;

  kind = get_kind (BT_REAL, k, "CMPLX", gfc_default_complex_kind);
  if (kind == -1)
    return &gfc_bad_expr;

  return simplify_cmplx ("CMPLX", x, y, kind);
}


gfc_expr *
gfc_simplify_complex (gfc_expr *x, gfc_expr *y)
{
  int kind;

  if (x->ts.type == BT_INTEGER && y->ts.type == BT_INTEGER)
    kind = gfc_default_complex_kind;
  else if (x->ts.type == BT_REAL || y->ts.type == BT_INTEGER)
    kind = x->ts.kind;
  else if (x->ts.type == BT_INTEGER || y->ts.type == BT_REAL)
    kind = y->ts.kind;
  else if (x->ts.type == BT_REAL && y->ts.type == BT_REAL)
    kind = (x->ts.kind > y->ts.kind) ? x->ts.kind : y->ts.kind;
  else
    gcc_unreachable ();

  return simplify_cmplx ("COMPLEX", x, y, kind);
}


gfc_expr *
gfc_simplify_conjg (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_copy_expr (e);
  mpc_conj (result->value.complex, result->value.complex, GFC_MPC_RND_MODE);

  return range_check (result, "CONJG");
}


/* Simplify atan2d (x) where the unit is degree.  */

gfc_expr *
gfc_simplify_atan2d (gfc_expr *y, gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  if (mpfr_zero_p (y->value.real) && mpfr_zero_p (x->value.real))
    {
      gfc_error ("If first argument of ATAN2D at %L is zero, then the "
		 "second argument must not be zero", &y->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_atan2 (result->value.real, y->value.real, x->value.real, GFC_RND_MODE);
  rad2deg (result->value.real);

  return range_check (result, "ATAN2D");
}


gfc_expr *
gfc_simplify_cos (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_cos (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	gfc_set_model_kind (x->ts.kind);
	mpc_cos (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_cos(): Bad type");
    }

  return range_check (result, "COS");
}


static void
deg2rad (mpfr_t x)
{
  mpfr_t d2r;

  mpfr_init (d2r);
  mpfr_const_pi (d2r, GFC_RND_MODE);
  mpfr_div_ui (d2r, d2r, 180, GFC_RND_MODE);
  mpfr_mul (x, x, d2r, GFC_RND_MODE);
  mpfr_clear (d2r);
}


/* Simplification routines for SIND, COSD, TAND.  */
#include "trigd_fe.inc"


/* Simplify COSD(X) where X has the unit of degree.  */

gfc_expr *
gfc_simplify_cosd (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
  simplify_cosd (result->value.real);

  return range_check (result, "COSD");
}


/* Simplify SIND(X) where X has the unit of degree.  */

gfc_expr *
gfc_simplify_sind (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
  simplify_sind (result->value.real);

  return range_check (result, "SIND");
}


/* Simplify TAND(X) where X has the unit of degree.  */

gfc_expr *
gfc_simplify_tand (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
  simplify_tand (result->value.real);

  return range_check (result, "TAND");
}


/* Simplify COTAND(X) where X has the unit of degree.  */

gfc_expr *
gfc_simplify_cotand (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  /* Implement COTAND = -TAND(x+90).
     TAND offers correct exact values for multiples of 30 degrees.
     This implementation is also compatible with the behavior of some legacy
     compilers.  Keep this consistent with gfc_conv_intrinsic_cotand.  */
  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
  mpfr_add_ui (result->value.real, result->value.real, 90, GFC_RND_MODE);
  simplify_tand (result->value.real);
  mpfr_neg (result->value.real, result->value.real, GFC_RND_MODE);

  return range_check (result, "COTAND");
}


gfc_expr *
gfc_simplify_cosh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_cosh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_cosh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gcc_unreachable ();
    }

  return range_check (result, "COSH");
}


gfc_expr *
gfc_simplify_count (gfc_expr *mask, gfc_expr *dim, gfc_expr *kind)
{
  gfc_expr *result;
  bool size_zero;

  size_zero = gfc_is_size_zero_array (mask);

  if (!(is_constant_array_expr (mask) || size_zero)
      || !gfc_is_constant_expr (dim)
      || !gfc_is_constant_expr (kind))
    return NULL;

  result = transformational_result (mask, dim,
				    BT_INTEGER,
				    get_kind (BT_INTEGER, kind, "COUNT",
					      gfc_default_integer_kind),
				    &mask->where);

  init_result_expr (result, 0, NULL);

  if (size_zero)
    return result;

  /* Passing MASK twice, once as data array, once as mask.
     Whenever gfc_count is called, '1' is added to the result.  */
  return !dim || mask->rank == 1 ?
    simplify_transformation_to_scalar (result, mask, mask, gfc_count) :
    simplify_transformation_to_array (result, mask, dim, mask, gfc_count, NULL);
}

/* Simplification routine for cshift. This works by copying the array
   expressions into a one-dimensional array, shuffling the values into another
   one-dimensional array and creating the new array expression from this.  The
   shuffling part is basically taken from the library routine.  */

gfc_expr *
gfc_simplify_cshift (gfc_expr *array, gfc_expr *shift, gfc_expr *dim)
{
  gfc_expr *result;
  int which;
  gfc_expr **arrayvec, **resultvec;
  gfc_expr **rptr, **sptr;
  mpz_t size;
  size_t arraysize, shiftsize, i;
  gfc_constructor *array_ctor, *shift_ctor;
  ssize_t *shiftvec, *hptr;
  ssize_t shift_val, len;
  ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
    hs_ex[GFC_MAX_DIMENSIONS + 1],
    hstride[GFC_MAX_DIMENSIONS], sstride[GFC_MAX_DIMENSIONS],
    a_extent[GFC_MAX_DIMENSIONS], a_stride[GFC_MAX_DIMENSIONS],
    h_extent[GFC_MAX_DIMENSIONS],
    ss_ex[GFC_MAX_DIMENSIONS + 1];
  ssize_t rsoffset;
  int d, n;
  bool continue_loop;
  gfc_expr **src, **dest;

  if (!is_constant_array_expr (array))
    return NULL;

  if (shift->rank > 0)
    gfc_simplify_expr (shift, 1);

  if (!gfc_is_constant_expr (shift))
    return NULL;

  /* Make dim zero-based.  */
  if (dim)
    {
      if (!gfc_is_constant_expr (dim))
	return NULL;
      which = mpz_get_si (dim->value.integer) - 1;
    }
  else
    which = 0;

  gfc_array_size (array, &size);
  arraysize = mpz_get_ui (size);
  mpz_clear (size);

  result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
  result->shape = gfc_copy_shape (array->shape, array->rank);
  result->rank = array->rank;
  result->ts.u.derived = array->ts.u.derived;

  if (arraysize == 0)
    return result;

  arrayvec = XCNEWVEC (gfc_expr *, arraysize);
  array_ctor = gfc_constructor_first (array->value.constructor);
  for (i = 0; i < arraysize; i++)
    {
      arrayvec[i] = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);
    }

  resultvec = XCNEWVEC (gfc_expr *, arraysize);

  extent[0] = 1;
  count[0] = 0;

  for (d=0; d < array->rank; d++)
    {
      a_extent[d] = mpz_get_si (array->shape[d]);
      a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
    }

  if (shift->rank > 0)
    {
      gfc_array_size (shift, &size);
      shiftsize = mpz_get_ui (size);
      mpz_clear (size);
      shiftvec = XCNEWVEC (ssize_t, shiftsize);
      shift_ctor = gfc_constructor_first (shift->value.constructor);
      for (d = 0; d < shift->rank; d++)
	{
	  h_extent[d] = mpz_get_si (shift->shape[d]);
	  hstride[d] = d == 0 ? 1 : hstride[d-1] * h_extent[d-1];
	}
    }
  else
    shiftvec = NULL;

  /* Shut up compiler */
  len = 1;
  rsoffset = 1;

  n = 0;
  for (d=0; d < array->rank; d++)
    {
      if (d == which)
	{
	  rsoffset = a_stride[d];
	  len = a_extent[d];
	}
      else
	{
	  count[n] = 0;
	  extent[n] = a_extent[d];
	  sstride[n] = a_stride[d];
	  ss_ex[n] = sstride[n] * extent[n];
	  if (shiftvec)
	    hs_ex[n] = hstride[n] * extent[n];
	  n++;
	}
    }
  ss_ex[n] = 0;
  hs_ex[n] = 0;

  if (shiftvec)
    {
      for (i = 0; i < shiftsize; i++)
	{
	  ssize_t val;
	  val = mpz_get_si (shift_ctor->expr->value.integer);
	  val = val % len;
	  if (val < 0)
	    val += len;
	  shiftvec[i] = val;
	  shift_ctor = gfc_constructor_next (shift_ctor);
	}
      shift_val = 0;
    }
  else
    {
      shift_val = mpz_get_si (shift->value.integer);
      shift_val = shift_val % len;
      if (shift_val < 0)
	shift_val += len;
    }

  continue_loop = true;
  d = array->rank;
  rptr = resultvec;
  sptr = arrayvec;
  hptr = shiftvec;

  while (continue_loop)
    {
      ssize_t sh;
      if (shiftvec)
	sh = *hptr;
      else
	sh = shift_val;

      src = &sptr[sh * rsoffset];
      dest = rptr;
      for (n = 0; n < len - sh; n++)
	{
	  *dest = *src;
	  dest += rsoffset;
	  src += rsoffset;
	}
      src = sptr;
      for ( n = 0; n < sh; n++)
	{
	  *dest = *src;
	  dest += rsoffset;
	  src += rsoffset;
	}
      rptr += sstride[0];
      sptr += sstride[0];
      if (shiftvec)
	hptr += hstride[0];
      count[0]++;
      n = 0;
      while (count[n] == extent[n])
	{
	  count[n] = 0;
	  rptr -= ss_ex[n];
	  sptr -= ss_ex[n];
	  if (shiftvec)
	    hptr -= hs_ex[n];
	  n++;
	  if (n >= d - 1)
	    {
	      continue_loop = false;
	      break;
	    }
	  else
	    {
	      count[n]++;
	      rptr += sstride[n];
	      sptr += sstride[n];
	      if (shiftvec)
		hptr += hstride[n];
	    }
	}
    }

  for (i = 0; i < arraysize; i++)
    {
      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_copy_expr (resultvec[i]),
				   NULL);
    }
  return result;
}


gfc_expr *
gfc_simplify_dcmplx (gfc_expr *x, gfc_expr *y)
{
  return simplify_cmplx ("DCMPLX", x, y, gfc_default_double_kind);
}


gfc_expr *
gfc_simplify_dble (gfc_expr *e)
{
  gfc_expr *result = NULL;
  int tmp1, tmp2;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
     warnings.  */
  tmp1 = warn_conversion;
  tmp2 = warn_conversion_extra;
  warn_conversion = warn_conversion_extra = 0;

  result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind);

  warn_conversion = tmp1;
  warn_conversion_extra = tmp2;

  if (result == &gfc_bad_expr)
    return &gfc_bad_expr;

  return range_check (result, "DBLE");
}


gfc_expr *
gfc_simplify_digits (gfc_expr *x)
{
  int i, digits;

  i = gfc_validate_kind (x->ts.type, x->ts.kind, false);

  switch (x->ts.type)
    {
      case BT_INTEGER:
	digits = gfc_integer_kinds[i].digits;
	break;

      case BT_REAL:
      case BT_COMPLEX:
	digits = gfc_real_kinds[i].digits;
	break;

      default:
	gcc_unreachable ();
    }

  return gfc_get_int_expr (gfc_default_integer_kind, NULL, digits);
}


gfc_expr *
gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int kind;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
  result = gfc_get_constant_expr (x->ts.type, kind, &x->where);

  switch (x->ts.type)
    {
      case BT_INTEGER:
	if (mpz_cmp (x->value.integer, y->value.integer) > 0)
	  mpz_sub (result->value.integer, x->value.integer, y->value.integer);
	else
	  mpz_set_ui (result->value.integer, 0);

	break;

      case BT_REAL:
	if (mpfr_cmp (x->value.real, y->value.real) > 0)
	  mpfr_sub (result->value.real, x->value.real, y->value.real,
		    GFC_RND_MODE);
	else
	  mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);

	break;

      default:
	gfc_internal_error ("gfc_simplify_dim(): Bad type");
    }

  return range_check (result, "DIM");
}


gfc_expr*
gfc_simplify_dot_product (gfc_expr *vector_a, gfc_expr *vector_b)
{
  /* If vector_a is a zero-sized array, the result is 0 for INTEGER,
     REAL, and COMPLEX types and .false. for LOGICAL.  */
  if (vector_a->shape && mpz_get_si (vector_a->shape[0]) == 0)
    {
      if (vector_a->ts.type == BT_LOGICAL)
	return gfc_get_logical_expr (gfc_default_logical_kind, NULL, false);
      else
	return gfc_get_int_expr (gfc_default_integer_kind, NULL, 0);
    }

  if (!is_constant_array_expr (vector_a)
      || !is_constant_array_expr (vector_b))
    return NULL;

  return compute_dot_product (vector_a, 1, 0, vector_b, 1, 0, true);
}


gfc_expr *
gfc_simplify_dprod (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *a1, *a2, *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  a1 = gfc_real2real (x, gfc_default_double_kind);
  a2 = gfc_real2real (y, gfc_default_double_kind);

  result = gfc_get_constant_expr (BT_REAL, gfc_default_double_kind, &x->where);
  mpfr_mul (result->value.real, a1->value.real, a2->value.real, GFC_RND_MODE);

  gfc_free_expr (a2);
  gfc_free_expr (a1);

  return range_check (result, "DPROD");
}


static gfc_expr *
simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg,
		      bool right)
{
  gfc_expr *result;
  int i, k, size, shift;

  if (arg1->expr_type != EXPR_CONSTANT || arg2->expr_type != EXPR_CONSTANT
      || shiftarg->expr_type != EXPR_CONSTANT)
    return NULL;

  k = gfc_validate_kind (BT_INTEGER, arg1->ts.kind, false);
  size = gfc_integer_kinds[k].bit_size;

  gfc_extract_int (shiftarg, &shift);

  /* DSHIFTR(I,J,SHIFT) = DSHIFTL(I,J,SIZE-SHIFT).  */
  if (right)
    shift = size - shift;

  result = gfc_get_constant_expr (BT_INTEGER, arg1->ts.kind, &arg1->where);
  mpz_set_ui (result->value.integer, 0);

  for (i = 0; i < shift; i++)
    if (mpz_tstbit (arg2->value.integer, size - shift + i))
      mpz_setbit (result->value.integer, i);

  for (i = 0; i < size - shift; i++)
    if (mpz_tstbit (arg1->value.integer, i))
      mpz_setbit (result->value.integer, shift + i);

  /* Convert to a signed value.  */
  gfc_convert_mpz_to_signed (result->value.integer, size);

  return result;
}


gfc_expr *
gfc_simplify_dshiftr (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
{
  return simplify_dshift (arg1, arg2, shiftarg, true);
}


gfc_expr *
gfc_simplify_dshiftl (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg)
{
  return simplify_dshift (arg1, arg2, shiftarg, false);
}


gfc_expr *
gfc_simplify_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
		   gfc_expr *dim)
{
  bool temp_boundary;
  gfc_expr *bnd;
  gfc_expr *result;
  int which;
  gfc_expr **arrayvec, **resultvec;
  gfc_expr **rptr, **sptr;
  mpz_t size;
  size_t arraysize, i;
  gfc_constructor *array_ctor, *shift_ctor, *bnd_ctor;
  ssize_t shift_val, len;
  ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
    sstride[GFC_MAX_DIMENSIONS], a_extent[GFC_MAX_DIMENSIONS],
    a_stride[GFC_MAX_DIMENSIONS], ss_ex[GFC_MAX_DIMENSIONS + 1];
  ssize_t rsoffset;
  int d, n;
  bool continue_loop;
  gfc_expr **src, **dest;
  size_t s_len;

  if (!is_constant_array_expr (array))
    return NULL;

  if (shift->rank > 0)
    gfc_simplify_expr (shift, 1);

  if (!gfc_is_constant_expr (shift))
    return NULL;

  if (boundary)
    {
      if (boundary->rank > 0)
	gfc_simplify_expr (boundary, 1);

      if (!gfc_is_constant_expr (boundary))
	  return NULL;
    }

  if (dim)
    {
      if (!gfc_is_constant_expr (dim))
	return NULL;
      which = mpz_get_si (dim->value.integer) - 1;
    }
  else
    which = 0;

  s_len = 0;
  if (boundary == NULL)
    {
      temp_boundary = true;
      switch (array->ts.type)
	{

	case BT_INTEGER:
	  bnd = gfc_get_int_expr (array->ts.kind, NULL, 0);
	  break;

	case BT_LOGICAL:
	  bnd = gfc_get_logical_expr (array->ts.kind, NULL, 0);
	  break;

	case BT_REAL:
	  bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
	  mpfr_set_ui (bnd->value.real, 0, GFC_RND_MODE);
	  break;

	case BT_COMPLEX:
	  bnd = gfc_get_constant_expr (array->ts.type, array->ts.kind, &gfc_current_locus);
	  mpc_set_ui (bnd->value.complex, 0, GFC_RND_MODE);
	  break;

	case BT_CHARACTER:
	  s_len = mpz_get_ui (array->ts.u.cl->length->value.integer);
	  bnd = gfc_get_character_expr (array->ts.kind, &gfc_current_locus, NULL, s_len);
	  break;

	default:
	  gcc_unreachable();

	}
    }
  else
    {
      temp_boundary = false;
      bnd = boundary;
    }

  gfc_array_size (array, &size);
  arraysize = mpz_get_ui (size);
  mpz_clear (size);

  result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
  result->shape = gfc_copy_shape (array->shape, array->rank);
  result->rank = array->rank;
  result->ts = array->ts;

  if (arraysize == 0)
    goto final;

  arrayvec = XCNEWVEC (gfc_expr *, arraysize);
  array_ctor = gfc_constructor_first (array->value.constructor);
  for (i = 0; i < arraysize; i++)
    {
      arrayvec[i] = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);
    }

  resultvec = XCNEWVEC (gfc_expr *, arraysize);

  extent[0] = 1;
  count[0] = 0;

  for (d=0; d < array->rank; d++)
    {
      a_extent[d] = mpz_get_si (array->shape[d]);
      a_stride[d] = d == 0 ? 1 : a_stride[d-1] * a_extent[d-1];
    }

  if (shift->rank > 0)
    {
      shift_ctor = gfc_constructor_first (shift->value.constructor);
      shift_val = 0;
    }
  else
    {
      shift_ctor = NULL;
      shift_val = mpz_get_si (shift->value.integer);
    }

  if (bnd->rank > 0)
    bnd_ctor = gfc_constructor_first (bnd->value.constructor);
  else
    bnd_ctor = NULL;

  /* Shut up compiler */
  len = 1;
  rsoffset = 1;

  n = 0;
  for (d=0; d < array->rank; d++)
    {
      if (d == which)
	{
	  rsoffset = a_stride[d];
	  len = a_extent[d];
	}
      else
	{
	  count[n] = 0;
	  extent[n] = a_extent[d];
	  sstride[n] = a_stride[d];
	  ss_ex[n] = sstride[n] * extent[n];
	  n++;
	}
    }
  ss_ex[n] = 0;

  continue_loop = true;
  d = array->rank;
  rptr = resultvec;
  sptr = arrayvec;

  while (continue_loop)
    {
      ssize_t sh, delta;

      if (shift_ctor)
	sh = mpz_get_si (shift_ctor->expr->value.integer);
      else
	sh = shift_val;

      if (( sh >= 0 ? sh : -sh ) > len)
	{
	  delta = len;
	  sh = len;
	}
      else
	delta = (sh >= 0) ? sh: -sh;

      if (sh > 0)
        {
          src = &sptr[delta * rsoffset];
          dest = rptr;
        }
      else
        {
          src = sptr;
          dest = &rptr[delta * rsoffset];
        }

      for (n = 0; n < len - delta; n++)
	{
	  *dest = *src;
	  dest += rsoffset;
	  src += rsoffset;
	}

      if (sh < 0)
        dest = rptr;

      n = delta;

      if (bnd_ctor)
	{
	  while (n--)
	    {
	      *dest = gfc_copy_expr (bnd_ctor->expr);
	      dest += rsoffset;
	    }
	}
      else
	{
	  while (n--)
	    {
	      *dest = gfc_copy_expr (bnd);
	      dest += rsoffset;
	    }
	}
      rptr += sstride[0];
      sptr += sstride[0];
      if (shift_ctor)
	shift_ctor =  gfc_constructor_next (shift_ctor);

      if (bnd_ctor)
	bnd_ctor = gfc_constructor_next (bnd_ctor);

      count[0]++;
      n = 0;
      while (count[n] == extent[n])
	{
	  count[n] = 0;
	  rptr -= ss_ex[n];
	  sptr -= ss_ex[n];
	  n++;
	  if (n >= d - 1)
	    {
	      continue_loop = false;
	      break;
	    }
	  else
	    {
	      count[n]++;
	      rptr += sstride[n];
	      sptr += sstride[n];
	    }
	}
    }

  for (i = 0; i < arraysize; i++)
    {
      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_copy_expr (resultvec[i]),
				   NULL);
    }

 final:
  if (temp_boundary)
    gfc_free_expr (bnd);

  return result;
}

gfc_expr *
gfc_simplify_erf (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_erf (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "ERF");
}


gfc_expr *
gfc_simplify_erfc (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_erfc (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "ERFC");
}


/* Helper functions to simplify ERFC_SCALED(x) = ERFC(x) * EXP(X**2).  */

#define MAX_ITER 200
#define ARG_LIMIT 12

/* Calculate ERFC_SCALED directly by its definition:

     ERFC_SCALED(x) = ERFC(x) * EXP(X**2)

   using a large precision for intermediate results.  This is used for all
   but large values of the argument.  */
static void
fullprec_erfc_scaled (mpfr_t res, mpfr_t arg)
{
  mpfr_prec_t prec;
  mpfr_t a, b;

  prec = mpfr_get_default_prec ();
  mpfr_set_default_prec (10 * prec);

  mpfr_init (a);
  mpfr_init (b);

  mpfr_set (a, arg, GFC_RND_MODE);
  mpfr_sqr (b, a, GFC_RND_MODE);
  mpfr_exp (b, b, GFC_RND_MODE);
  mpfr_erfc (a, a, GFC_RND_MODE);
  mpfr_mul (a, a, b, GFC_RND_MODE);

  mpfr_set (res, a, GFC_RND_MODE);
  mpfr_set_default_prec (prec);

  mpfr_clear (a);
  mpfr_clear (b);
}

/* Calculate ERFC_SCALED using a power series expansion in 1/arg:

    ERFC_SCALED(x) = 1 / (x * sqrt(pi))
                     * (1 + Sum_n (-1)**n * (1 * 3 * 5 * ... * (2n-1))
                                          / (2 * x**2)**n)

  This is used for large values of the argument.  Intermediate calculations
  are performed with twice the precision.  We don't do a fixed number of
  iterations of the sum, but stop when it has converged to the required
  precision.  */
static void
asympt_erfc_scaled (mpfr_t res, mpfr_t arg)
{
  mpfr_t sum, x, u, v, w, oldsum, sumtrunc;
  mpz_t num;
  mpfr_prec_t prec;
  unsigned i;

  prec = mpfr_get_default_prec ();
  mpfr_set_default_prec (2 * prec);

  mpfr_init (sum);
  mpfr_init (x);
  mpfr_init (u);
  mpfr_init (v);
  mpfr_init (w);
  mpz_init (num);

  mpfr_init (oldsum);
  mpfr_init (sumtrunc);
  mpfr_set_prec (oldsum, prec);
  mpfr_set_prec (sumtrunc, prec);

  mpfr_set (x, arg, GFC_RND_MODE);
  mpfr_set_ui (sum, 1, GFC_RND_MODE);
  mpz_set_ui (num, 1);

  mpfr_set (u, x, GFC_RND_MODE);
  mpfr_sqr (u, u, GFC_RND_MODE);
  mpfr_mul_ui (u, u, 2, GFC_RND_MODE);
  mpfr_pow_si (u, u, -1, GFC_RND_MODE);

  for (i = 1; i < MAX_ITER; i++)
  {
    mpfr_set (oldsum, sum, GFC_RND_MODE);

    mpz_mul_ui (num, num, 2 * i - 1);
    mpz_neg (num, num);

    mpfr_set (w, u, GFC_RND_MODE);
    mpfr_pow_ui (w, w, i, GFC_RND_MODE);

    mpfr_set_z (v, num, GFC_RND_MODE);
    mpfr_mul (v, v, w, GFC_RND_MODE);

    mpfr_add (sum, sum, v, GFC_RND_MODE);

    mpfr_set (sumtrunc, sum, GFC_RND_MODE);
    if (mpfr_cmp (sumtrunc, oldsum) == 0)
      break;
  }

  /* We should have converged by now; otherwise, ARG_LIMIT is probably
     set too low.  */
  gcc_assert (i < MAX_ITER);

  /* Divide by x * sqrt(Pi).  */
  mpfr_const_pi (u, GFC_RND_MODE);
  mpfr_sqrt (u, u, GFC_RND_MODE);
  mpfr_mul (u, u, x, GFC_RND_MODE);
  mpfr_div (sum, sum, u, GFC_RND_MODE);

  mpfr_set (res, sum, GFC_RND_MODE);
  mpfr_set_default_prec (prec);

  mpfr_clears (sum, x, u, v, w, oldsum, sumtrunc, NULL);
  mpz_clear (num);
}


gfc_expr *
gfc_simplify_erfc_scaled (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  if (mpfr_cmp_d (x->value.real, ARG_LIMIT) >= 0)
    asympt_erfc_scaled (result->value.real, x->value.real);
  else
    fullprec_erfc_scaled (result->value.real, x->value.real);

  return range_check (result, "ERFC_SCALED");
}

#undef MAX_ITER
#undef ARG_LIMIT


gfc_expr *
gfc_simplify_epsilon (gfc_expr *e)
{
  gfc_expr *result;
  int i;

  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);

  result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
  mpfr_set (result->value.real, gfc_real_kinds[i].epsilon, GFC_RND_MODE);

  return range_check (result, "EPSILON");
}


gfc_expr *
gfc_simplify_exp (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_exp (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	gfc_set_model_kind (x->ts.kind);
	mpc_exp (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_exp(): Bad type");
    }

  return range_check (result, "EXP");
}


gfc_expr *
gfc_simplify_exponent (gfc_expr *x)
{
  long int val;
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				  &x->where);

  /* EXPONENT(inf) = EXPONENT(nan) = HUGE(0) */
  if (mpfr_inf_p (x->value.real) || mpfr_nan_p (x->value.real))
    {
      int i = gfc_validate_kind (BT_INTEGER, gfc_default_integer_kind, false);
      mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
      return result;
    }

  /* EXPONENT(+/- 0.0) = 0  */
  if (mpfr_zero_p (x->value.real))
    {
      mpz_set_ui (result->value.integer, 0);
      return result;
    }

  gfc_set_model (x->value.real);

  val = (long int) mpfr_get_exp (x->value.real);
  mpz_set_si (result->value.integer, val);

  return range_check (result, "EXPONENT");
}


gfc_expr *
gfc_simplify_failed_or_stopped_images (gfc_expr *team ATTRIBUTE_UNUSED,
				       gfc_expr *kind)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_current_locus = *gfc_current_intrinsic_where;
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return &gfc_bad_expr;
    }

  if (flag_coarray == GFC_FCOARRAY_SINGLE)
    {
      gfc_expr *result;
      int actual_kind;
      if (kind)
	gfc_extract_int (kind, &actual_kind);
      else
	actual_kind = gfc_default_integer_kind;

      result = gfc_get_array_expr (BT_INTEGER, actual_kind, &gfc_current_locus);
      result->rank = 1;
      return result;
    }

  /* For fcoarray = lib no simplification is possible, because it is not known
     what images failed or are stopped at compile time.  */
  return NULL;
}


gfc_expr *
gfc_simplify_get_team (gfc_expr *level ATTRIBUTE_UNUSED)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_current_locus = *gfc_current_intrinsic_where;
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return &gfc_bad_expr;
    }

  if (flag_coarray == GFC_FCOARRAY_SINGLE)
    {
      gfc_expr *result;
      result = gfc_get_array_expr (BT_INTEGER, gfc_default_integer_kind, &gfc_current_locus);
      result->rank = 0;
      return result;
    }

  /* For fcoarray = lib no simplification is possible, because it is not known
     what images failed or are stopped at compile time.  */
  return NULL;
}


gfc_expr *
gfc_simplify_float (gfc_expr *a)
{
  gfc_expr *result;

  if (a->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_int2real (a, gfc_default_real_kind);

  return range_check (result, "FLOAT");
}


static bool
is_last_ref_vtab (gfc_expr *e)
{
  gfc_ref *ref;
  gfc_component *comp = NULL;

  if (e->expr_type != EXPR_VARIABLE)
    return false;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT)
      comp = ref->u.c.component;

  if (!e->ref || !comp)
    return e->symtree->n.sym->attr.vtab;

  if (comp->name[0] == '_' && strcmp (comp->name, "_vptr") == 0)
    return true;

  return false;
}


gfc_expr *
gfc_simplify_extends_type_of (gfc_expr *a, gfc_expr *mold)
{
  /* Avoid simplification of resolved symbols.  */
  if (is_last_ref_vtab (a) || is_last_ref_vtab (mold))
    return NULL;

  if (a->ts.type == BT_DERIVED && mold->ts.type == BT_DERIVED)
    return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
				 gfc_type_is_extension_of (mold->ts.u.derived,
							   a->ts.u.derived));

  if (UNLIMITED_POLY (a) || UNLIMITED_POLY (mold))
    return NULL;

  /* Return .false. if the dynamic type can never be an extension.  */
  if ((a->ts.type == BT_CLASS && mold->ts.type == BT_CLASS
       && !gfc_type_is_extension_of
			(mold->ts.u.derived->components->ts.u.derived,
			 a->ts.u.derived->components->ts.u.derived)
       && !gfc_type_is_extension_of
			(a->ts.u.derived->components->ts.u.derived,
			 mold->ts.u.derived->components->ts.u.derived))
      || (a->ts.type == BT_DERIVED && mold->ts.type == BT_CLASS
	  && !gfc_type_is_extension_of
			(mold->ts.u.derived->components->ts.u.derived,
			 a->ts.u.derived))
      || (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
	  && !gfc_type_is_extension_of
			(mold->ts.u.derived,
			 a->ts.u.derived->components->ts.u.derived)
	  && !gfc_type_is_extension_of
			(a->ts.u.derived->components->ts.u.derived,
			 mold->ts.u.derived)))
    return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);

  /* Return .true. if the dynamic type is guaranteed to be an extension.  */
  if (a->ts.type == BT_CLASS && mold->ts.type == BT_DERIVED
      && gfc_type_is_extension_of (mold->ts.u.derived,
				   a->ts.u.derived->components->ts.u.derived))
    return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, true);

  return NULL;
}


gfc_expr *
gfc_simplify_same_type_as (gfc_expr *a, gfc_expr *b)
{
  /* Avoid simplification of resolved symbols.  */
  if (is_last_ref_vtab (a) || is_last_ref_vtab (b))
    return NULL;

  /* Return .false. if the dynamic type can never be the
     same.  */
  if (((a->ts.type == BT_CLASS && gfc_expr_attr (a).class_ok)
       || (b->ts.type == BT_CLASS && gfc_expr_attr (b).class_ok))
      && !gfc_type_compatible (&a->ts, &b->ts)
      && !gfc_type_compatible (&b->ts, &a->ts))
    return gfc_get_logical_expr (gfc_default_logical_kind, &a->where, false);

  if (a->ts.type != BT_DERIVED || b->ts.type != BT_DERIVED)
     return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
			       gfc_compare_derived_types (a->ts.u.derived,
							  b->ts.u.derived));
}


gfc_expr *
gfc_simplify_floor (gfc_expr *e, gfc_expr *k)
{
  gfc_expr *result;
  mpfr_t floor;
  int kind;

  kind = get_kind (BT_INTEGER, k, "FLOOR", gfc_default_integer_kind);
  if (kind == -1)
    gfc_internal_error ("gfc_simplify_floor(): Bad kind");

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  mpfr_init2 (floor, mpfr_get_prec (e->value.real));
  mpfr_floor (floor, e->value.real);

  result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
  gfc_mpfr_to_mpz (result->value.integer, floor, &e->where);

  mpfr_clear (floor);

  return range_check (result, "FLOOR");
}


gfc_expr *
gfc_simplify_fraction (gfc_expr *x)
{
  gfc_expr *result;
  mpfr_exp_t e;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

  /* FRACTION(inf) = NaN.  */
  if (mpfr_inf_p (x->value.real))
    {
      mpfr_set_nan (result->value.real);
      return result;
    }

  /* mpfr_frexp() correctly handles zeros and NaNs.  */
  mpfr_frexp (&e, result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "FRACTION");
}


gfc_expr *
gfc_simplify_gamma (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_gamma (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "GAMMA");
}


gfc_expr *
gfc_simplify_huge (gfc_expr *e)
{
  gfc_expr *result;
  int i;

  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);

  switch (e->ts.type)
    {
      case BT_INTEGER:
	mpz_set (result->value.integer, gfc_integer_kinds[i].huge);
	break;

      case BT_REAL:
	mpfr_set (result->value.real, gfc_real_kinds[i].huge, GFC_RND_MODE);
	break;

      default:
	gcc_unreachable ();
    }

  return result;
}


gfc_expr *
gfc_simplify_hypot (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_hypot (result->value.real, x->value.real, y->value.real, GFC_RND_MODE);
  return range_check (result, "HYPOT");
}


/* We use the processor's collating sequence, because all
   systems that gfortran currently works on are ASCII.  */

gfc_expr *
gfc_simplify_iachar (gfc_expr *e, gfc_expr *kind)
{
  gfc_expr *result;
  gfc_char_t index;
  int k;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  if (e->value.character.length != 1)
    {
      gfc_error ("Argument of IACHAR at %L must be of length one", &e->where);
      return &gfc_bad_expr;
    }

  index = e->value.character.string[0];

  if (warn_surprising && index > 127)
    gfc_warning (OPT_Wsurprising,
		 "Argument of IACHAR function at %L outside of range 0..127",
		 &e->where);

  k = get_kind (BT_INTEGER, kind, "IACHAR", gfc_default_integer_kind);
  if (k == -1)
    return &gfc_bad_expr;

  result = gfc_get_int_expr (k, &e->where, index);

  return range_check (result, "IACHAR");
}


static gfc_expr *
do_bit_and (gfc_expr *result, gfc_expr *e)
{
  gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_INTEGER
	      && result->expr_type == EXPR_CONSTANT);

  mpz_and (result->value.integer, result->value.integer, e->value.integer);
  return result;
}


gfc_expr *
gfc_simplify_iall (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, -1, do_bit_and);
}


static gfc_expr *
do_bit_ior (gfc_expr *result, gfc_expr *e)
{
  gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_INTEGER
	      && result->expr_type == EXPR_CONSTANT);

  mpz_ior (result->value.integer, result->value.integer, e->value.integer);
  return result;
}


gfc_expr *
gfc_simplify_iany (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, 0, do_bit_ior);
}


gfc_expr *
gfc_simplify_iand (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
  mpz_and (result->value.integer, x->value.integer, y->value.integer);

  return range_check (result, "IAND");
}


gfc_expr *
gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int k, pos;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  gfc_extract_int (y, &pos);

  k = gfc_validate_kind (x->ts.type, x->ts.kind, false);

  result = gfc_copy_expr (x);

  convert_mpz_to_unsigned (result->value.integer,
			   gfc_integer_kinds[k].bit_size);

  mpz_clrbit (result->value.integer, pos);

  gfc_convert_mpz_to_signed (result->value.integer,
			 gfc_integer_kinds[k].bit_size);

  return result;
}


gfc_expr *
gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z)
{
  gfc_expr *result;
  int pos, len;
  int i, k, bitsize;
  int *bits;

  if (x->expr_type != EXPR_CONSTANT
      || y->expr_type != EXPR_CONSTANT
      || z->expr_type != EXPR_CONSTANT)
    return NULL;

  gfc_extract_int (y, &pos);
  gfc_extract_int (z, &len);

  k = gfc_validate_kind (BT_INTEGER, x->ts.kind, false);

  bitsize = gfc_integer_kinds[k].bit_size;

  if (pos + len > bitsize)
    {
      gfc_error ("Sum of second and third arguments of IBITS exceeds "
		 "bit size at %L", &y->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  convert_mpz_to_unsigned (result->value.integer,
			   gfc_integer_kinds[k].bit_size);

  bits = XCNEWVEC (int, bitsize);

  for (i = 0; i < bitsize; i++)
    bits[i] = 0;

  for (i = 0; i < len; i++)
    bits[i] = mpz_tstbit (x->value.integer, i + pos);

  for (i = 0; i < bitsize; i++)
    {
      if (bits[i] == 0)
	mpz_clrbit (result->value.integer, i);
      else if (bits[i] == 1)
	mpz_setbit (result->value.integer, i);
      else
	gfc_internal_error ("IBITS: Bad bit");
    }

  free (bits);

  gfc_convert_mpz_to_signed (result->value.integer,
			 gfc_integer_kinds[k].bit_size);

  return result;
}


gfc_expr *
gfc_simplify_ibset (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int k, pos;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  gfc_extract_int (y, &pos);

  k = gfc_validate_kind (x->ts.type, x->ts.kind, false);

  result = gfc_copy_expr (x);

  convert_mpz_to_unsigned (result->value.integer,
			   gfc_integer_kinds[k].bit_size);

  mpz_setbit (result->value.integer, pos);

  gfc_convert_mpz_to_signed (result->value.integer,
			 gfc_integer_kinds[k].bit_size);

  return result;
}


gfc_expr *
gfc_simplify_ichar (gfc_expr *e, gfc_expr *kind)
{
  gfc_expr *result;
  gfc_char_t index;
  int k;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  if (e->value.character.length != 1)
    {
      gfc_error ("Argument of ICHAR at %L must be of length one", &e->where);
      return &gfc_bad_expr;
    }

  index = e->value.character.string[0];

  k = get_kind (BT_INTEGER, kind, "ICHAR", gfc_default_integer_kind);
  if (k == -1)
    return &gfc_bad_expr;

  result = gfc_get_int_expr (k, &e->where, index);

  return range_check (result, "ICHAR");
}


gfc_expr *
gfc_simplify_ieor (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
  mpz_xor (result->value.integer, x->value.integer, y->value.integer);

  return range_check (result, "IEOR");
}


gfc_expr *
gfc_simplify_index (gfc_expr *x, gfc_expr *y, gfc_expr *b, gfc_expr *kind)
{
  gfc_expr *result;
  int back, len, lensub;
  int i, j, k, count, index = 0, start;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT
      || ( b != NULL && b->expr_type !=  EXPR_CONSTANT))
    return NULL;

  if (b != NULL && b->value.logical != 0)
    back = 1;
  else
    back = 0;

  k = get_kind (BT_INTEGER, kind, "INDEX", gfc_default_integer_kind);
  if (k == -1)
    return &gfc_bad_expr;

  result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);

  len = x->value.character.length;
  lensub = y->value.character.length;

  if (len < lensub)
    {
      mpz_set_si (result->value.integer, 0);
      return result;
    }

  if (back == 0)
    {
      if (lensub == 0)
	{
	  mpz_set_si (result->value.integer, 1);
	  return result;
	}
      else if (lensub == 1)
	{
	  for (i = 0; i < len; i++)
	    {
	      for (j = 0; j < lensub; j++)
		{
		  if (y->value.character.string[j]
		      == x->value.character.string[i])
		    {
		      index = i + 1;
		      goto done;
		    }
		}
	    }
	}
      else
	{
	  for (i = 0; i < len; i++)
	    {
	      for (j = 0; j < lensub; j++)
		{
		  if (y->value.character.string[j]
		      == x->value.character.string[i])
		    {
		      start = i;
		      count = 0;

		      for (k = 0; k < lensub; k++)
			{
			  if (y->value.character.string[k]
			      == x->value.character.string[k + start])
			    count++;
			}

		      if (count == lensub)
			{
			  index = start + 1;
			  goto done;
			}
		    }
		}
	    }
	}

    }
  else
    {
      if (lensub == 0)
	{
	  mpz_set_si (result->value.integer, len + 1);
	  return result;
	}
      else if (lensub == 1)
	{
	  for (i = 0; i < len; i++)
	    {
	      for (j = 0; j < lensub; j++)
		{
		  if (y->value.character.string[j]
		      == x->value.character.string[len - i])
		    {
		      index = len - i + 1;
		      goto done;
		    }
		}
	    }
	}
      else
	{
	  for (i = 0; i < len; i++)
	    {
	      for (j = 0; j < lensub; j++)
		{
		  if (y->value.character.string[j]
		      == x->value.character.string[len - i])
		    {
		      start = len - i;
		      if (start <= len - lensub)
			{
			  count = 0;
			  for (k = 0; k < lensub; k++)
			    if (y->value.character.string[k]
			        == x->value.character.string[k + start])
			      count++;

			  if (count == lensub)
			    {
			      index = start + 1;
			      goto done;
			    }
			}
		      else
			{
			  continue;
			}
		    }
		}
	    }
	}
    }

done:
  mpz_set_si (result->value.integer, index);
  return range_check (result, "INDEX");
}


static gfc_expr *
simplify_intconv (gfc_expr *e, int kind, const char *name)
{
  gfc_expr *result = NULL;
  int tmp1, tmp2;

  /* Convert BOZ to integer, and return without range checking.  */
  if (e->ts.type == BT_BOZ)
    {
      if (!gfc_boz2int (e, kind))
	return NULL;
      result = gfc_copy_expr (e);
      return result;
    }

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
     warnings.  */
  tmp1 = warn_conversion;
  tmp2 = warn_conversion_extra;
  warn_conversion = warn_conversion_extra = 0;

  result = gfc_convert_constant (e, BT_INTEGER, kind);

  warn_conversion = tmp1;
  warn_conversion_extra = tmp2;

  if (result == &gfc_bad_expr)
    return &gfc_bad_expr;

  return range_check (result, name);
}


gfc_expr *
gfc_simplify_int (gfc_expr *e, gfc_expr *k)
{
  int kind;

  kind = get_kind (BT_INTEGER, k, "INT", gfc_default_integer_kind);
  if (kind == -1)
    return &gfc_bad_expr;

  return simplify_intconv (e, kind, "INT");
}

gfc_expr *
gfc_simplify_int2 (gfc_expr *e)
{
  return simplify_intconv (e, 2, "INT2");
}


gfc_expr *
gfc_simplify_int8 (gfc_expr *e)
{
  return simplify_intconv (e, 8, "INT8");
}


gfc_expr *
gfc_simplify_long (gfc_expr *e)
{
  return simplify_intconv (e, 4, "LONG");
}


gfc_expr *
gfc_simplify_ifix (gfc_expr *e)
{
  gfc_expr *rtrunc, *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  rtrunc = gfc_copy_expr (e);
  mpfr_trunc (rtrunc->value.real, e->value.real);

  result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				  &e->where);
  gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);

  gfc_free_expr (rtrunc);

  return range_check (result, "IFIX");
}


gfc_expr *
gfc_simplify_idint (gfc_expr *e)
{
  gfc_expr *rtrunc, *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  rtrunc = gfc_copy_expr (e);
  mpfr_trunc (rtrunc->value.real, e->value.real);

  result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				  &e->where);
  gfc_mpfr_to_mpz (result->value.integer, rtrunc->value.real, &e->where);

  gfc_free_expr (rtrunc);

  return range_check (result, "IDINT");
}


gfc_expr *
gfc_simplify_ior (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, x->ts.kind, &x->where);
  mpz_ior (result->value.integer, x->value.integer, y->value.integer);

  return range_check (result, "IOR");
}


static gfc_expr *
do_bit_xor (gfc_expr *result, gfc_expr *e)
{
  gcc_assert (e->ts.type == BT_INTEGER && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_INTEGER
	      && result->expr_type == EXPR_CONSTANT);

  mpz_xor (result->value.integer, result->value.integer, e->value.integer);
  return result;
}


gfc_expr *
gfc_simplify_iparity (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, 0, do_bit_xor);
}


gfc_expr *
gfc_simplify_is_iostat_end (gfc_expr *x)
{
  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
			       mpz_cmp_si (x->value.integer,
					   LIBERROR_END) == 0);
}


gfc_expr *
gfc_simplify_is_iostat_eor (gfc_expr *x)
{
  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
			       mpz_cmp_si (x->value.integer,
					   LIBERROR_EOR) == 0);
}


gfc_expr *
gfc_simplify_isnan (gfc_expr *x)
{
  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &x->where,
			       mpfr_nan_p (x->value.real));
}


/* Performs a shift on its first argument.  Depending on the last
   argument, the shift can be arithmetic, i.e. with filling from the
   left like in the SHIFTA intrinsic.  */
static gfc_expr *
simplify_shift (gfc_expr *e, gfc_expr *s, const char *name,
		bool arithmetic, int direction)
{
  gfc_expr *result;
  int ashift, *bits, i, k, bitsize, shift;

  if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
    return NULL;

  gfc_extract_int (s, &shift);

  k = gfc_validate_kind (BT_INTEGER, e->ts.kind, false);
  bitsize = gfc_integer_kinds[k].bit_size;

  result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);

  if (shift == 0)
    {
      mpz_set (result->value.integer, e->value.integer);
      return result;
    }

  if (direction > 0 && shift < 0)
    {
      /* Left shift, as in SHIFTL.  */
      gfc_error ("Second argument of %s is negative at %L", name, &e->where);
      return &gfc_bad_expr;
    }
  else if (direction < 0)
    {
      /* Right shift, as in SHIFTR or SHIFTA.  */
      if (shift < 0)
	{
	  gfc_error ("Second argument of %s is negative at %L",
		     name, &e->where);
	  return &gfc_bad_expr;
	}

      shift = -shift;
    }

  ashift = (shift >= 0 ? shift : -shift);

  if (ashift > bitsize)
    {
      gfc_error ("Magnitude of second argument of %s exceeds bit size "
		 "at %L", name, &e->where);
      return &gfc_bad_expr;
    }

  bits = XCNEWVEC (int, bitsize);

  for (i = 0; i < bitsize; i++)
    bits[i] = mpz_tstbit (e->value.integer, i);

  if (shift > 0)
    {
      /* Left shift.  */
      for (i = 0; i < shift; i++)
	mpz_clrbit (result->value.integer, i);

      for (i = 0; i < bitsize - shift; i++)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i + shift);
	  else
	    mpz_setbit (result->value.integer, i + shift);
	}
    }
  else
    {
      /* Right shift.  */
      if (arithmetic && bits[bitsize - 1])
	for (i = bitsize - 1; i >= bitsize - ashift; i--)
	  mpz_setbit (result->value.integer, i);
      else
	for (i = bitsize - 1; i >= bitsize - ashift; i--)
	  mpz_clrbit (result->value.integer, i);

      for (i = bitsize - 1; i >= ashift; i--)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i - ashift);
	  else
	    mpz_setbit (result->value.integer, i - ashift);
	}
    }

  gfc_convert_mpz_to_signed (result->value.integer, bitsize);
  free (bits);

  return result;
}


gfc_expr *
gfc_simplify_ishft (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "ISHFT", false, 0);
}


gfc_expr *
gfc_simplify_lshift (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "LSHIFT", false, 1);
}


gfc_expr *
gfc_simplify_rshift (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "RSHIFT", true, -1);
}


gfc_expr *
gfc_simplify_shifta (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "SHIFTA", true, -1);
}


gfc_expr *
gfc_simplify_shiftl (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "SHIFTL", false, 1);
}


gfc_expr *
gfc_simplify_shiftr (gfc_expr *e, gfc_expr *s)
{
  return simplify_shift (e, s, "SHIFTR", false, -1);
}


gfc_expr *
gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
{
  gfc_expr *result;
  int shift, ashift, isize, ssize, delta, k;
  int i, *bits;

  if (e->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
    return NULL;

  gfc_extract_int (s, &shift);

  k = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  isize = gfc_integer_kinds[k].bit_size;

  if (sz != NULL)
    {
      if (sz->expr_type != EXPR_CONSTANT)
	return NULL;

      gfc_extract_int (sz, &ssize);
    }
  else
    ssize = isize;

  if (shift >= 0)
    ashift = shift;
  else
    ashift = -shift;

  if (ashift > ssize)
    {
      if (sz == NULL)
	gfc_error ("Magnitude of second argument of ISHFTC exceeds "
		   "BIT_SIZE of first argument at %C");
      else
	gfc_error ("Absolute value of SHIFT shall be less than or equal "
		   "to SIZE at %C");
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);

  mpz_set (result->value.integer, e->value.integer);

  if (shift == 0)
    return result;

  convert_mpz_to_unsigned (result->value.integer, isize);

  bits = XCNEWVEC (int, ssize);

  for (i = 0; i < ssize; i++)
    bits[i] = mpz_tstbit (e->value.integer, i);

  delta = ssize - ashift;

  if (shift > 0)
    {
      for (i = 0; i < delta; i++)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i + shift);
	  else
	    mpz_setbit (result->value.integer, i + shift);
	}

      for (i = delta; i < ssize; i++)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i - delta);
	  else
	    mpz_setbit (result->value.integer, i - delta);
	}
    }
  else
    {
      for (i = 0; i < ashift; i++)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i + delta);
	  else
	    mpz_setbit (result->value.integer, i + delta);
	}

      for (i = ashift; i < ssize; i++)
	{
	  if (bits[i] == 0)
	    mpz_clrbit (result->value.integer, i + shift);
	  else
	    mpz_setbit (result->value.integer, i + shift);
	}
    }

  gfc_convert_mpz_to_signed (result->value.integer, isize);

  free (bits);
  return result;
}


gfc_expr *
gfc_simplify_kind (gfc_expr *e)
{
  return gfc_get_int_expr (gfc_default_integer_kind, NULL, e->ts.kind);
}


static gfc_expr *
simplify_bound_dim (gfc_expr *array, gfc_expr *kind, int d, int upper,
		    gfc_array_spec *as, gfc_ref *ref, bool coarray)
{
  gfc_expr *l, *u, *result;
  int k;

  k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
		gfc_default_integer_kind);
  if (k == -1)
    return &gfc_bad_expr;

  result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);

  /* For non-variables, LBOUND(expr, DIM=n) = 1 and
     UBOUND(expr, DIM=n) = SIZE(expr, DIM=n).  */
  if (!coarray && array->expr_type != EXPR_VARIABLE)
    {
      if (upper)
	{
	  gfc_expr* dim = result;
	  mpz_set_si (dim->value.integer, d);

	  result = simplify_size (array, dim, k);
	  gfc_free_expr (dim);
	  if (!result)
	    goto returnNull;
	}
      else
	mpz_set_si (result->value.integer, 1);

      goto done;
    }

  /* Otherwise, we have a variable expression.  */
  gcc_assert (array->expr_type == EXPR_VARIABLE);
  gcc_assert (as);

  if (!gfc_resolve_array_spec (as, 0))
    return NULL;

  /* The last dimension of an assumed-size array is special.  */
  if ((!coarray && d == as->rank && as->type == AS_ASSUMED_SIZE && !upper)
      || (coarray && d == as->rank + as->corank
	  && (!upper || flag_coarray == GFC_FCOARRAY_SINGLE)))
    {
      if (as->lower[d-1] && as->lower[d-1]->expr_type == EXPR_CONSTANT)
	{
	  gfc_free_expr (result);
	  return gfc_copy_expr (as->lower[d-1]);
	}

      goto returnNull;
    }

  result = gfc_get_constant_expr (BT_INTEGER, k, &array->where);

  /* Then, we need to know the extent of the given dimension.  */
  if (coarray || (ref->u.ar.type == AR_FULL && !ref->next))
    {
      gfc_expr *declared_bound;
      int empty_bound;
      bool constant_lbound, constant_ubound;

      l = as->lower[d-1];
      u = as->upper[d-1];

      gcc_assert (l != NULL);

      constant_lbound = l->expr_type == EXPR_CONSTANT;
      constant_ubound = u && u->expr_type == EXPR_CONSTANT;

      empty_bound = upper ? 0 : 1;
      declared_bound = upper ? u : l;

      if ((!upper && !constant_lbound)
	  || (upper && !constant_ubound))
	goto returnNull;

      if (!coarray)
	{
	  /* For {L,U}BOUND, the value depends on whether the array
	     is empty.  We can nevertheless simplify if the declared bound
	     has the same value as that of an empty array, in which case
	     the result isn't dependent on the array emptyness.  */
	  if (mpz_cmp_si (declared_bound->value.integer, empty_bound) == 0)
	    mpz_set_si (result->value.integer, empty_bound);
	  else if (!constant_lbound || !constant_ubound)
	    /* Array emptyness can't be determined, we can't simplify.  */
	    goto returnNull;
	  else if (mpz_cmp (l->value.integer, u->value.integer) > 0)
	    mpz_set_si (result->value.integer, empty_bound);
	  else
	    mpz_set (result->value.integer, declared_bound->value.integer);
	}
      else
	mpz_set (result->value.integer, declared_bound->value.integer);
    }
  else
    {
      if (upper)
	{
	  int d2 = 0, cnt = 0;
	  for (int idx = 0; idx < ref->u.ar.dimen; ++idx)
	    {
	      if (ref->u.ar.dimen_type[idx] == DIMEN_ELEMENT)
		d2++;
	      else if (cnt < d - 1)
		cnt++;
	      else
		break;
	    }
	  if (!gfc_ref_dimen_size (&ref->u.ar, d2 + d - 1, &result->value.integer, NULL))
	    goto returnNull;
	}
      else
	mpz_set_si (result->value.integer, (long int) 1);
    }

done:
  return range_check (result, upper ? "UBOUND" : "LBOUND");

returnNull:
  gfc_free_expr (result);
  return NULL;
}


static gfc_expr *
simplify_bound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
{
  gfc_ref *ref;
  gfc_array_spec *as;
  ar_type type = AR_UNKNOWN;
  int d;

  if (array->ts.type == BT_CLASS)
    return NULL;

  if (array->expr_type != EXPR_VARIABLE)
    {
      as = NULL;
      ref = NULL;
      goto done;
    }

  /* Do not attempt to resolve if error has already been issued.  */
  if (array->symtree->n.sym->error)
    return NULL;

  /* Follow any component references.  */
  as = array->symtree->n.sym->as;
  for (ref = array->ref; ref; ref = ref->next)
    {
      switch (ref->type)
	{
	case REF_ARRAY:
	  type = ref->u.ar.type;
	  switch (ref->u.ar.type)
	    {
	    case AR_ELEMENT:
	      as = NULL;
	      continue;

	    case AR_FULL:
	      /* We're done because 'as' has already been set in the
		 previous iteration.  */
	      goto done;

	    case AR_UNKNOWN:
	      return NULL;

	    case AR_SECTION:
	      as = ref->u.ar.as;
	      goto done;
	    }

	  gcc_unreachable ();

	case REF_COMPONENT:
	  as = ref->u.c.component->as;
	  continue;

	case REF_SUBSTRING:
	case REF_INQUIRY:
	  continue;
	}
    }

  gcc_unreachable ();

 done:

  if (as && (as->type == AS_DEFERRED || as->type == AS_ASSUMED_RANK
	     || (as->type == AS_ASSUMED_SHAPE && upper)))
    return NULL;

  gcc_assert (!as
	      || (as->type != AS_DEFERRED
		  && array->expr_type == EXPR_VARIABLE
		  && !gfc_expr_attr (array).allocatable
		  && !gfc_expr_attr (array).pointer));

  if (dim == NULL)
    {
      /* Multi-dimensional bounds.  */
      gfc_expr *bounds[GFC_MAX_DIMENSIONS];
      gfc_expr *e;
      int k;

      /* UBOUND(ARRAY) is not valid for an assumed-size array.  */
      if (upper && type == AR_FULL && as && as->type == AS_ASSUMED_SIZE)
	{
	  /* An error message will be emitted in
	     check_assumed_size_reference (resolve.c).  */
	  return &gfc_bad_expr;
	}

      /* Simplify the bounds for each dimension.  */
      for (d = 0; d < array->rank; d++)
	{
	  bounds[d] = simplify_bound_dim (array, kind, d + 1, upper, as, ref,
					  false);
	  if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
	    {
	      int j;

	      for (j = 0; j < d; j++)
		gfc_free_expr (bounds[j]);

	      if (gfc_seen_div0)
		return &gfc_bad_expr;
	      else
		return bounds[d];
	    }
	}

      /* Allocate the result expression.  */
      k = get_kind (BT_INTEGER, kind, upper ? "UBOUND" : "LBOUND",
		    gfc_default_integer_kind);
      if (k == -1)
	return &gfc_bad_expr;

      e = gfc_get_array_expr (BT_INTEGER, k, &array->where);

      /* The result is a rank 1 array; its size is the rank of the first
	 argument to {L,U}BOUND.  */
      e->rank = 1;
      e->shape = gfc_get_shape (1);
      mpz_init_set_ui (e->shape[0], array->rank);

      /* Create the constructor for this array.  */
      for (d = 0; d < array->rank; d++)
	gfc_constructor_append_expr (&e->value.constructor,
				     bounds[d], &e->where);

      return e;
    }
  else
    {
      /* A DIM argument is specified.  */
      if (dim->expr_type != EXPR_CONSTANT)
	return NULL;

      d = mpz_get_si (dim->value.integer);

      if ((d < 1 || d > array->rank)
	  || (d == array->rank && as && as->type == AS_ASSUMED_SIZE && upper))
	{
	  gfc_error ("DIM argument at %L is out of bounds", &dim->where);
	  return &gfc_bad_expr;
	}

      if (as && as->type == AS_ASSUMED_RANK)
	return NULL;

      return simplify_bound_dim (array, kind, d, upper, as, ref, false);
    }
}


static gfc_expr *
simplify_cobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind, int upper)
{
  gfc_ref *ref;
  gfc_array_spec *as;
  int d;

  if (array->expr_type != EXPR_VARIABLE)
    return NULL;

  /* Follow any component references.  */
  as = (array->ts.type == BT_CLASS && array->ts.u.derived->components)
       ? array->ts.u.derived->components->as
       : array->symtree->n.sym->as;
  for (ref = array->ref; ref; ref = ref->next)
    {
      switch (ref->type)
	{
	case REF_ARRAY:
	  switch (ref->u.ar.type)
	    {
	    case AR_ELEMENT:
	      if (ref->u.ar.as->corank > 0)
		{
		  gcc_assert (as == ref->u.ar.as);
		  goto done;
		}
	      as = NULL;
	      continue;

	    case AR_FULL:
	      /* We're done because 'as' has already been set in the
		 previous iteration.  */
	      goto done;

	    case AR_UNKNOWN:
	      return NULL;

	    case AR_SECTION:
	      as = ref->u.ar.as;
	      goto done;
	    }

	  gcc_unreachable ();

	case REF_COMPONENT:
	  as = ref->u.c.component->as;
	  continue;

	case REF_SUBSTRING:
	case REF_INQUIRY:
	  continue;
	}
    }

  if (!as)
    gcc_unreachable ();

 done:

  if (as->cotype == AS_DEFERRED || as->cotype == AS_ASSUMED_SHAPE)
    return NULL;

  if (dim == NULL)
    {
      /* Multi-dimensional cobounds.  */
      gfc_expr *bounds[GFC_MAX_DIMENSIONS];
      gfc_expr *e;
      int k;

      /* Simplify the cobounds for each dimension.  */
      for (d = 0; d < as->corank; d++)
	{
	  bounds[d] = simplify_bound_dim (array, kind, d + 1 + as->rank,
					  upper, as, ref, true);
	  if (bounds[d] == NULL || bounds[d] == &gfc_bad_expr)
	    {
	      int j;

	      for (j = 0; j < d; j++)
		gfc_free_expr (bounds[j]);
	      return bounds[d];
	    }
	}

      /* Allocate the result expression.  */
      e = gfc_get_expr ();
      e->where = array->where;
      e->expr_type = EXPR_ARRAY;
      e->ts.type = BT_INTEGER;
      k = get_kind (BT_INTEGER, kind, upper ? "UCOBOUND" : "LCOBOUND",
		    gfc_default_integer_kind);
      if (k == -1)
	{
	  gfc_free_expr (e);
	  return &gfc_bad_expr;
	}
      e->ts.kind = k;

      /* The result is a rank 1 array; its size is the rank of the first
	 argument to {L,U}COBOUND.  */
      e->rank = 1;
      e->shape = gfc_get_shape (1);
      mpz_init_set_ui (e->shape[0], as->corank);

      /* Create the constructor for this array.  */
      for (d = 0; d < as->corank; d++)
	gfc_constructor_append_expr (&e->value.constructor,
				     bounds[d], &e->where);
      return e;
    }
  else
    {
      /* A DIM argument is specified.  */
      if (dim->expr_type != EXPR_CONSTANT)
	return NULL;

      d = mpz_get_si (dim->value.integer);

      if (d < 1 || d > as->corank)
	{
	  gfc_error ("DIM argument at %L is out of bounds", &dim->where);
	  return &gfc_bad_expr;
	}

      return simplify_bound_dim (array, kind, d+as->rank, upper, as, ref, true);
    }
}


gfc_expr *
gfc_simplify_lbound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  return simplify_bound (array, dim, kind, 0);
}


gfc_expr *
gfc_simplify_lcobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  return simplify_cobound (array, dim, kind, 0);
}

gfc_expr *
gfc_simplify_leadz (gfc_expr *e)
{
  unsigned long lz, bs;
  int i;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  bs = gfc_integer_kinds[i].bit_size;
  if (mpz_cmp_si (e->value.integer, 0) == 0)
    lz = bs;
  else if (mpz_cmp_si (e->value.integer, 0) < 0)
    lz = 0;
  else
    lz = bs - mpz_sizeinbase (e->value.integer, 2);

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, lz);
}


/* Check for constant length of a substring.  */

static bool
substring_has_constant_len (gfc_expr *e)
{
  gfc_ref *ref;
  HOST_WIDE_INT istart, iend, length;
  bool equal_length = false;

  if (e->ts.type != BT_CHARACTER)
    return false;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type != REF_COMPONENT && ref->type != REF_ARRAY)
      break;

  if (!ref
      || ref->type != REF_SUBSTRING
      || !ref->u.ss.start
      || ref->u.ss.start->expr_type != EXPR_CONSTANT
      || !ref->u.ss.end
      || ref->u.ss.end->expr_type != EXPR_CONSTANT)
    return false;

  /* Basic checks on substring starting and ending indices.  */
  if (!gfc_resolve_substring (ref, &equal_length))
    return false;

  istart = gfc_mpz_get_hwi (ref->u.ss.start->value.integer);
  iend = gfc_mpz_get_hwi (ref->u.ss.end->value.integer);

  if (istart <= iend)
    length = iend - istart + 1;
  else
    length = 0;

  /* Fix substring length.  */
  e->value.character.length = length;

  return true;
}


gfc_expr *
gfc_simplify_len (gfc_expr *e, gfc_expr *kind)
{
  gfc_expr *result;
  int k = get_kind (BT_INTEGER, kind, "LEN", gfc_default_integer_kind);

  if (k == -1)
    return &gfc_bad_expr;

  if (e->expr_type == EXPR_CONSTANT
      || substring_has_constant_len (e))
    {
      result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
      mpz_set_si (result->value.integer, e->value.character.length);
      return range_check (result, "LEN");
    }
  else if (e->ts.u.cl != NULL && e->ts.u.cl->length != NULL
	   && e->ts.u.cl->length->expr_type == EXPR_CONSTANT
	   && e->ts.u.cl->length->ts.type == BT_INTEGER)
    {
      result = gfc_get_constant_expr (BT_INTEGER, k, &e->where);
      mpz_set (result->value.integer, e->ts.u.cl->length->value.integer);
      return range_check (result, "LEN");
    }
  else if (e->expr_type == EXPR_VARIABLE && e->ts.type == BT_CHARACTER
	   && e->symtree->n.sym
	   && e->symtree->n.sym->ts.type != BT_DERIVED
	   && e->symtree->n.sym->assoc && e->symtree->n.sym->assoc->target
	   && e->symtree->n.sym->assoc->target->ts.type == BT_DERIVED
	   && e->symtree->n.sym->assoc->target->symtree->n.sym
	   && UNLIMITED_POLY (e->symtree->n.sym->assoc->target->symtree->n.sym))

    /* The expression in assoc->target points to a ref to the _data component
       of the unlimited polymorphic entity.  To get the _len component the last
       _data ref needs to be stripped and a ref to the _len component added.  */
    return gfc_get_len_component (e->symtree->n.sym->assoc->target, k);
  else
    return NULL;
}


gfc_expr *
gfc_simplify_len_trim (gfc_expr *e, gfc_expr *kind)
{
  gfc_expr *result;
  size_t count, len, i;
  int k = get_kind (BT_INTEGER, kind, "LEN_TRIM", gfc_default_integer_kind);

  if (k == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  len = e->value.character.length;
  for (count = 0, i = 1; i <= len; i++)
    if (e->value.character.string[len - i] == ' ')
      count++;
    else
      break;

  result = gfc_get_int_expr (k, &e->where, len - count);
  return range_check (result, "LEN_TRIM");
}

gfc_expr *
gfc_simplify_lgamma (gfc_expr *x)
{
  gfc_expr *result;
  int sg;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_lgamma (result->value.real, &sg, x->value.real, GFC_RND_MODE);

  return range_check (result, "LGAMMA");
}


gfc_expr *
gfc_simplify_lge (gfc_expr *a, gfc_expr *b)
{
  if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
			       gfc_compare_string (a, b) >= 0);
}


gfc_expr *
gfc_simplify_lgt (gfc_expr *a, gfc_expr *b)
{
  if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
			       gfc_compare_string (a, b) > 0);
}


gfc_expr *
gfc_simplify_lle (gfc_expr *a, gfc_expr *b)
{
  if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
			       gfc_compare_string (a, b) <= 0);
}


gfc_expr *
gfc_simplify_llt (gfc_expr *a, gfc_expr *b)
{
  if (a->expr_type != EXPR_CONSTANT || b->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (gfc_default_logical_kind, &a->where,
			       gfc_compare_string (a, b) < 0);
}


gfc_expr *
gfc_simplify_log (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
    case BT_REAL:
      if (mpfr_sgn (x->value.real) <= 0)
	{
	  gfc_error ("Argument of LOG at %L cannot be less than or equal "
		     "to zero", &x->where);
	  gfc_free_expr (result);
	  return &gfc_bad_expr;
	}

      mpfr_log (result->value.real, x->value.real, GFC_RND_MODE);
      break;

    case BT_COMPLEX:
      if (mpfr_zero_p (mpc_realref (x->value.complex))
	  && mpfr_zero_p (mpc_imagref (x->value.complex)))
	{
	  gfc_error ("Complex argument of LOG at %L cannot be zero",
		     &x->where);
	  gfc_free_expr (result);
	  return &gfc_bad_expr;
	}

      gfc_set_model_kind (x->ts.kind);
      mpc_log (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
      break;

    default:
      gfc_internal_error ("gfc_simplify_log: bad type");
    }

  return range_check (result, "LOG");
}


gfc_expr *
gfc_simplify_log10 (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  if (mpfr_sgn (x->value.real) <= 0)
    {
      gfc_error ("Argument of LOG10 at %L cannot be less than or equal "
		 "to zero", &x->where);
      return &gfc_bad_expr;
    }

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
  mpfr_log10 (result->value.real, x->value.real, GFC_RND_MODE);

  return range_check (result, "LOG10");
}


gfc_expr *
gfc_simplify_logical (gfc_expr *e, gfc_expr *k)
{
  int kind;

  kind = get_kind (BT_LOGICAL, k, "LOGICAL", gfc_default_logical_kind);
  if (kind < 0)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  return gfc_get_logical_expr (kind, &e->where, e->value.logical);
}


gfc_expr*
gfc_simplify_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b)
{
  gfc_expr *result;
  int row, result_rows, col, result_columns;
  int stride_a, offset_a, stride_b, offset_b;

  if (!is_constant_array_expr (matrix_a)
      || !is_constant_array_expr (matrix_b))
    return NULL;

  /* MATMUL should do mixed-mode arithmetic.  Set the result type.  */
  if (matrix_a->ts.type != matrix_b->ts.type)
    {
      gfc_expr e;
      e.expr_type = EXPR_OP;
      gfc_clear_ts (&e.ts);
      e.value.op.op = INTRINSIC_NONE;
      e.value.op.op1 = matrix_a;
      e.value.op.op2 = matrix_b;
      gfc_type_convert_binary (&e, 1);
      result = gfc_get_array_expr (e.ts.type, e.ts.kind, &matrix_a->where);
    }
  else
    {
      result = gfc_get_array_expr (matrix_a->ts.type, matrix_a->ts.kind,
				   &matrix_a->where);
    }

  if (matrix_a->rank == 1 && matrix_b->rank == 2)
    {
      result_rows = 1;
      result_columns = mpz_get_si (matrix_b->shape[1]);
      stride_a = 1;
      stride_b = mpz_get_si (matrix_b->shape[0]);

      result->rank = 1;
      result->shape = gfc_get_shape (result->rank);
      mpz_init_set_si (result->shape[0], result_columns);
    }
  else if (matrix_a->rank == 2 && matrix_b->rank == 1)
    {
      result_rows = mpz_get_si (matrix_a->shape[0]);
      result_columns = 1;
      stride_a = mpz_get_si (matrix_a->shape[0]);
      stride_b = 1;

      result->rank = 1;
      result->shape = gfc_get_shape (result->rank);
      mpz_init_set_si (result->shape[0], result_rows);
    }
  else if (matrix_a->rank == 2 && matrix_b->rank == 2)
    {
      result_rows = mpz_get_si (matrix_a->shape[0]);
      result_columns = mpz_get_si (matrix_b->shape[1]);
      stride_a = mpz_get_si (matrix_a->shape[0]);
      stride_b = mpz_get_si (matrix_b->shape[0]);

      result->rank = 2;
      result->shape = gfc_get_shape (result->rank);
      mpz_init_set_si (result->shape[0], result_rows);
      mpz_init_set_si (result->shape[1], result_columns);
    }
  else
    gcc_unreachable();

  offset_b = 0;
  for (col = 0; col < result_columns; ++col)
    {
      offset_a = 0;

      for (row = 0; row < result_rows; ++row)
	{
	  gfc_expr *e = compute_dot_product (matrix_a, stride_a, offset_a,
					     matrix_b, 1, offset_b, false);
	  gfc_constructor_append_expr (&result->value.constructor,
				       e, NULL);

	  offset_a += 1;
        }

      offset_b += stride_b;
    }

  return result;
}


gfc_expr *
gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_arg)
{
  gfc_expr *result;
  int kind, arg, k;

  if (i->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = get_kind (BT_INTEGER, kind_arg, "MASKR", gfc_default_integer_kind);
  if (kind == -1)
    return &gfc_bad_expr;
  k = gfc_validate_kind (BT_INTEGER, kind, false);

  bool fail = gfc_extract_int (i, &arg);
  gcc_assert (!fail);

  result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);

  /* MASKR(n) = 2^n - 1 */
  mpz_set_ui (result->value.integer, 1);
  mpz_mul_2exp (result->value.integer, result->value.integer, arg);
  mpz_sub_ui (result->value.integer, result->value.integer, 1);

  gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);

  return result;
}


gfc_expr *
gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg)
{
  gfc_expr *result;
  int kind, arg, k;
  mpz_t z;

  if (i->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = get_kind (BT_INTEGER, kind_arg, "MASKL", gfc_default_integer_kind);
  if (kind == -1)
    return &gfc_bad_expr;
  k = gfc_validate_kind (BT_INTEGER, kind, false);

  bool fail = gfc_extract_int (i, &arg);
  gcc_assert (!fail);

  result = gfc_get_constant_expr (BT_INTEGER, kind, &i->where);

  /* MASKL(n) = 2^bit_size - 2^(bit_size - n) */
  mpz_init_set_ui (z, 1);
  mpz_mul_2exp (z, z, gfc_integer_kinds[k].bit_size);
  mpz_set_ui (result->value.integer, 1);
  mpz_mul_2exp (result->value.integer, result->value.integer,
		gfc_integer_kinds[k].bit_size - arg);
  mpz_sub (result->value.integer, z, result->value.integer);
  mpz_clear (z);

  gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);

  return result;
}


gfc_expr *
gfc_simplify_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
{
  gfc_expr * result;
  gfc_constructor *tsource_ctor, *fsource_ctor, *mask_ctor;

  if (mask->expr_type == EXPR_CONSTANT)
    {
      result = gfc_copy_expr (mask->value.logical ? tsource : fsource);
      /* Parenthesis is needed to get lower bounds of 1.  */
      result = gfc_get_parentheses (result);
      gfc_simplify_expr (result, 1);
      return result;
    }

  if (!mask->rank || !is_constant_array_expr (mask)
      || !is_constant_array_expr (tsource) || !is_constant_array_expr (fsource))
    return NULL;

  result = gfc_get_array_expr (tsource->ts.type, tsource->ts.kind,
			       &tsource->where);
  if (tsource->ts.type == BT_DERIVED)
    result->ts.u.derived = tsource->ts.u.derived;
  else if (tsource->ts.type == BT_CHARACTER)
    result->ts.u.cl = tsource->ts.u.cl;

  tsource_ctor = gfc_constructor_first (tsource->value.constructor);
  fsource_ctor = gfc_constructor_first (fsource->value.constructor);
  mask_ctor = gfc_constructor_first (mask->value.constructor);

  while (mask_ctor)
    {
      if (mask_ctor->expr->value.logical)
	gfc_constructor_append_expr (&result->value.constructor,
				     gfc_copy_expr (tsource_ctor->expr),
				     NULL);
      else
	gfc_constructor_append_expr (&result->value.constructor,
				     gfc_copy_expr (fsource_ctor->expr),
				     NULL);
      tsource_ctor = gfc_constructor_next (tsource_ctor);
      fsource_ctor = gfc_constructor_next (fsource_ctor);
      mask_ctor = gfc_constructor_next (mask_ctor);
    }

  result->shape = gfc_get_shape (1);
  gfc_array_size (result, &result->shape[0]);

  return result;
}


gfc_expr *
gfc_simplify_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask_expr)
{
  mpz_t arg1, arg2, mask;
  gfc_expr *result;

  if (i->expr_type != EXPR_CONSTANT || j->expr_type != EXPR_CONSTANT
      || mask_expr->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, i->ts.kind, &i->where);

  /* Convert all argument to unsigned.  */
  mpz_init_set (arg1, i->value.integer);
  mpz_init_set (arg2, j->value.integer);
  mpz_init_set (mask, mask_expr->value.integer);

  /* MERGE_BITS(I,J,MASK) = IOR (IAND (I, MASK), IAND (J, NOT (MASK))).  */
  mpz_and (arg1, arg1, mask);
  mpz_com (mask, mask);
  mpz_and (arg2, arg2, mask);
  mpz_ior (result->value.integer, arg1, arg2);

  mpz_clear (arg1);
  mpz_clear (arg2);
  mpz_clear (mask);

  return result;
}


/* Selects between current value and extremum for simplify_min_max
   and simplify_minval_maxval.  */
static int
min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign, bool back_val)
{
  int ret;

  switch (arg->ts.type)
    {
      case BT_INTEGER:
	if (extremum->ts.kind < arg->ts.kind)
	  extremum->ts.kind = arg->ts.kind;
	ret = mpz_cmp (arg->value.integer,
		       extremum->value.integer) * sign;
	if (ret > 0)
	  mpz_set (extremum->value.integer, arg->value.integer);
	break;

      case BT_REAL:
	if (extremum->ts.kind < arg->ts.kind)
	  extremum->ts.kind = arg->ts.kind;
	if (mpfr_nan_p (extremum->value.real))
	  {
	    ret = 1;
	    mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
	  }
	else if (mpfr_nan_p (arg->value.real))
	  ret = -1;
	else
	  {
	    ret = mpfr_cmp (arg->value.real, extremum->value.real) * sign;
	    if (ret > 0)
	      mpfr_set (extremum->value.real, arg->value.real, GFC_RND_MODE);
	  }
	break;

      case BT_CHARACTER:
#define LENGTH(x) ((x)->value.character.length)
#define STRING(x) ((x)->value.character.string)
	if (LENGTH (extremum) < LENGTH(arg))
	  {
	    gfc_char_t *tmp = STRING(extremum);

	    STRING(extremum) = gfc_get_wide_string (LENGTH(arg) + 1);
	    memcpy (STRING(extremum), tmp,
		      LENGTH(extremum) * sizeof (gfc_char_t));
	    gfc_wide_memset (&STRING(extremum)[LENGTH(extremum)], ' ',
			       LENGTH(arg) - LENGTH(extremum));
	    STRING(extremum)[LENGTH(arg)] = '\0';  /* For debugger  */
	    LENGTH(extremum) = LENGTH(arg);
	    free (tmp);
	  }
	ret = gfc_compare_string (arg, extremum) * sign;
	if (ret > 0)
	  {
	    free (STRING(extremum));
	    STRING(extremum) = gfc_get_wide_string (LENGTH(extremum) + 1);
	    memcpy (STRING(extremum), STRING(arg),
		      LENGTH(arg) * sizeof (gfc_char_t));
	    gfc_wide_memset (&STRING(extremum)[LENGTH(arg)], ' ',
			       LENGTH(extremum) - LENGTH(arg));
	    STRING(extremum)[LENGTH(extremum)] = '\0';  /* For debugger  */
	  }
#undef LENGTH
#undef STRING
	break;

      default:
	gfc_internal_error ("simplify_min_max(): Bad type in arglist");
    }
  if (back_val && ret == 0)
    ret = 1;

  return ret;
}


/* This function is special since MAX() can take any number of
   arguments.  The simplified expression is a rewritten version of the
   argument list containing at most one constant element.  Other
   constant elements are deleted.  Because the argument list has
   already been checked, this function always succeeds.  sign is 1 for
   MAX(), -1 for MIN().  */

static gfc_expr *
simplify_min_max (gfc_expr *expr, int sign)
{
  gfc_actual_arglist *arg, *last, *extremum;
  gfc_expr *tmp, *ret;
  const char *fname;

  last = NULL;
  extremum = NULL;

  arg = expr->value.function.actual;

  for (; arg; last = arg, arg = arg->next)
    {
      if (arg->expr->expr_type != EXPR_CONSTANT)
	continue;

      if (extremum == NULL)
	{
	  extremum = arg;
	  continue;
	}

      min_max_choose (arg->expr, extremum->expr, sign);

      /* Delete the extra constant argument.  */
      last->next = arg->next;

      arg->next = NULL;
      gfc_free_actual_arglist (arg);
      arg = last;
    }

  /* If there is one value left, replace the function call with the
     expression.  */
  if (expr->value.function.actual->next != NULL)
    return NULL;

  /* Handle special cases of specific functions (min|max)1 and
     a(min|max)0.  */

  tmp = expr->value.function.actual->expr;
  fname = expr->value.function.isym->name;

  if ((tmp->ts.type != BT_INTEGER || tmp->ts.kind != gfc_integer_4_kind)
      && (strcmp (fname, "min1") == 0 || strcmp (fname, "max1") == 0))
    {
      ret = gfc_convert_constant (tmp, BT_INTEGER, gfc_integer_4_kind);
    }
  else if ((tmp->ts.type != BT_REAL || tmp->ts.kind != gfc_real_4_kind)
	   && (strcmp (fname, "amin0") == 0 || strcmp (fname, "amax0") == 0))
    {
      ret = gfc_convert_constant (tmp, BT_REAL, gfc_real_4_kind);
    }
  else
    ret = gfc_copy_expr (tmp);

  return ret;

}


gfc_expr *
gfc_simplify_min (gfc_expr *e)
{
  return simplify_min_max (e, -1);
}


gfc_expr *
gfc_simplify_max (gfc_expr *e)
{
  return simplify_min_max (e, 1);
}

/* Helper function for gfc_simplify_minval.  */

static gfc_expr *
gfc_min (gfc_expr *op1, gfc_expr *op2)
{
  min_max_choose (op1, op2, -1);
  gfc_free_expr (op1);
  return op2;
}

/* Simplify minval for constant arrays.  */

gfc_expr *
gfc_simplify_minval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, INT_MAX, gfc_min);
}

/* Helper function for gfc_simplify_maxval.  */

static gfc_expr *
gfc_max (gfc_expr *op1, gfc_expr *op2)
{
  min_max_choose (op1, op2, 1);
  gfc_free_expr (op1);
  return op2;
}


/* Simplify maxval for constant arrays.  */

gfc_expr *
gfc_simplify_maxval (gfc_expr *array, gfc_expr* dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, INT_MIN, gfc_max);
}


/* Transform minloc or maxloc of an array, according to MASK,
   to the scalar result.  This code is mostly identical to
   simplify_transformation_to_scalar.  */

static gfc_expr *
simplify_minmaxloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *mask,
			      gfc_expr *extremum, int sign, bool back_val)
{
  gfc_expr *a, *m;
  gfc_constructor *array_ctor, *mask_ctor;
  mpz_t count;

  mpz_set_si (result->value.integer, 0);


  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  array_ctor = gfc_constructor_first (array->value.constructor);
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);
  else
    mask_ctor = NULL;

  mpz_init_set_si (count, 0);
  while (array_ctor)
    {
      mpz_add_ui (count, count, 1);
      a = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);
      /* A constant MASK equals .TRUE. here and can be ignored.  */
      if (mask_ctor)
	{
	  m = mask_ctor->expr;
	  mask_ctor = gfc_constructor_next (mask_ctor);
	  if (!m->value.logical)
	    continue;
	}
      if (min_max_choose (a, extremum, sign, back_val) > 0)
	mpz_set (result->value.integer, count);
    }
  mpz_clear (count);
  gfc_free_expr (extremum);
  return result;
}

/* Simplify minloc / maxloc in the absence of a dim argument.  */

static gfc_expr *
simplify_minmaxloc_nodim (gfc_expr *result, gfc_expr *extremum,
			  gfc_expr *array, gfc_expr *mask, int sign,
			  bool back_val)
{
  ssize_t res[GFC_MAX_DIMENSIONS];
  int i, n;
  gfc_constructor *result_ctor, *array_ctor, *mask_ctor;
  ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
    sstride[GFC_MAX_DIMENSIONS];
  gfc_expr *a, *m;
  bool continue_loop;
  bool ma;

  for (i = 0; i<array->rank; i++)
    res[i] = -1;

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    goto finish;

  for (i = 0; i < array->rank; i++)
    {
      count[i] = 0;
      sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
      extent[i] = mpz_get_si (array->shape[i]);
      if (extent[i] <= 0)
	goto finish;
    }

  continue_loop = true;
  array_ctor = gfc_constructor_first (array->value.constructor);
  if (mask && mask->rank > 0)
    mask_ctor = gfc_constructor_first (mask->value.constructor);
  else
    mask_ctor = NULL;

  /* Loop over the array elements (and mask), keeping track of
     the indices to return.  */
  while (continue_loop)
    {
      do
	{
	  a = array_ctor->expr;
	  if (mask_ctor)
	    {
	      m = mask_ctor->expr;
	      ma = m->value.logical;
	      mask_ctor = gfc_constructor_next (mask_ctor);
	    }
	  else
	    ma = true;

	  if (ma && min_max_choose (a, extremum, sign, back_val) > 0)
	    {
	      for (i = 0; i<array->rank; i++)
		res[i] = count[i];
	    }
	  array_ctor = gfc_constructor_next (array_ctor);
	  count[0] ++;
	} while (count[0] != extent[0]);
      n = 0;
      do
	{
	  /* When we get to the end of a dimension, reset it and increment
	     the next dimension.  */
	  count[n] = 0;
	  n++;
	  if (n >= array->rank)
	    {
	      continue_loop = false;
	      break;
	    }
	  else
	    count[n] ++;
	} while (count[n] == extent[n]);
    }

 finish:
  gfc_free_expr (extremum);
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i<array->rank; i++)
    {
      gfc_expr *r_expr;
      r_expr = result_ctor->expr;
      mpz_set_si (r_expr->value.integer, res[i] + 1);
      result_ctor = gfc_constructor_next (result_ctor);
    }
  return result;
}

/* Helper function for gfc_simplify_minmaxloc - build an array
   expression with n elements.  */

static gfc_expr *
new_array (bt type, int kind, int n, locus *where)
{
  gfc_expr *result;
  int i;

  result = gfc_get_array_expr (type, kind, where);
  result->rank = 1;
  result->shape = gfc_get_shape(1);
  mpz_init_set_si (result->shape[0], n);
  for (i = 0; i < n; i++)
    {
      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_get_constant_expr (type, kind, where),
				   NULL);
    }

  return result;
}

/* Simplify minloc and maxloc. This code is mostly identical to
   simplify_transformation_to_array.  */

static gfc_expr *
simplify_minmaxloc_to_array (gfc_expr *result, gfc_expr *array,
			     gfc_expr *dim, gfc_expr *mask,
			     gfc_expr *extremum, int sign, bool back_val)
{
  mpz_t size;
  int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
  gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
  gfc_constructor *array_ctor, *mask_ctor, *result_ctor;

  int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
      sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
      tmpstride[GFC_MAX_DIMENSIONS];

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  /* Build an indexed table for array element expressions to minimize
     linked-list traversal. Masked elements are set to NULL.  */
  gfc_array_size (array, &size);
  arraysize = mpz_get_ui (size);
  mpz_clear (size);

  arrayvec = XCNEWVEC (gfc_expr*, arraysize);

  array_ctor = gfc_constructor_first (array->value.constructor);
  mask_ctor = NULL;
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);

  for (i = 0; i < arraysize; ++i)
    {
      arrayvec[i] = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);

      if (mask_ctor)
	{
	  if (!mask_ctor->expr->value.logical)
	    arrayvec[i] = NULL;

	  mask_ctor = gfc_constructor_next (mask_ctor);
	}
    }

  /* Same for the result expression.  */
  gfc_array_size (result, &size);
  resultsize = mpz_get_ui (size);
  mpz_clear (size);

  resultvec = XCNEWVEC (gfc_expr*, resultsize);
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      resultvec[i] = result_ctor->expr;
      result_ctor = gfc_constructor_next (result_ctor);
    }

  gfc_extract_int (dim, &dim_index);
  dim_index -= 1;               /* zero-base index */
  dim_extent = 0;
  dim_stride = 0;

  for (i = 0, n = 0; i < array->rank; ++i)
    {
      count[i] = 0;
      tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
      if (i == dim_index)
	{
	  dim_extent = mpz_get_si (array->shape[i]);
	  dim_stride = tmpstride[i];
	  continue;
	}

      extent[n] = mpz_get_si (array->shape[i]);
      sstride[n] = tmpstride[i];
      dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
      n += 1;
    }

  done = resultsize <= 0;
  base = arrayvec;
  dest = resultvec;
  while (!done)
    {
      gfc_expr *ex;
      ex = gfc_copy_expr (extremum);
      for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
	{
	  if (*src && min_max_choose (*src, ex, sign, back_val) > 0)
	    mpz_set_si ((*dest)->value.integer, n + 1);
	}

      count[0]++;
      base += sstride[0];
      dest += dstride[0];
      gfc_free_expr (ex);

      n = 0;
      while (!done && count[n] == extent[n])
	{
	  count[n] = 0;
	  base -= sstride[n] * extent[n];
	  dest -= dstride[n] * extent[n];

	  n++;
	  if (n < result->rank)
	    {
	      /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
		 times, we'd warn for the last iteration, because the
		 array index will have already been incremented to the
		 array sizes, and we can't tell that this must make
		 the test against result->rank false, because ranks
		 must not exceed GFC_MAX_DIMENSIONS.  */
	      GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
	      count[n]++;
	      base += sstride[n];
	      dest += dstride[n];
	      GCC_DIAGNOSTIC_POP
	    }
	  else
	    done = true;
       }
    }

  /* Place updated expression in result constructor.  */
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      result_ctor->expr = resultvec[i];
      result_ctor = gfc_constructor_next (result_ctor);
    }

  free (arrayvec);
  free (resultvec);
  free (extremum);
  return result;
}

/* Simplify minloc and maxloc for constant arrays.  */

static gfc_expr *
gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask,
			gfc_expr *kind, gfc_expr *back, int sign)
{
  gfc_expr *result;
  gfc_expr *extremum;
  int ikind;
  int init_val;
  bool back_val = false;

  if (!is_constant_array_expr (array)
      || !gfc_is_constant_expr (dim))
    return NULL;

  if (mask
      && !is_constant_array_expr (mask)
      && mask->expr_type != EXPR_CONSTANT)
    return NULL;

  if (kind)
    {
      if (gfc_extract_int (kind, &ikind, -1))
	return NULL;
    }
  else
    ikind = gfc_default_integer_kind;

  if (back)
    {
      if (back->expr_type != EXPR_CONSTANT)
	return NULL;

      back_val = back->value.logical;
    }

  if (sign < 0)
    init_val = INT_MAX;
  else if (sign > 0)
    init_val = INT_MIN;
  else
    gcc_unreachable();

  extremum = gfc_get_constant_expr (array->ts.type, array->ts.kind, &array->where);
  init_result_expr (extremum, init_val, array);

  if (dim)
    {
      result = transformational_result (array, dim, BT_INTEGER,
					ikind, &array->where);
      init_result_expr (result, 0, array);

      if (array->rank == 1)
	return simplify_minmaxloc_to_scalar (result, array, mask, extremum,
					     sign, back_val);
      else
	return simplify_minmaxloc_to_array (result, array, dim, mask, extremum,
					    sign, back_val);
    }
  else
    {
      result = new_array (BT_INTEGER, ikind, array->rank, &array->where);
      return simplify_minmaxloc_nodim (result, extremum, array, mask,
				       sign, back_val);
    }
}

gfc_expr *
gfc_simplify_minloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
		     gfc_expr *back)
{
  return gfc_simplify_minmaxloc (array, dim, mask, kind, back, -1);
}

gfc_expr *
gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind,
		     gfc_expr *back)
{
  return gfc_simplify_minmaxloc (array, dim, mask, kind, back, 1);
}

/* Simplify findloc to scalar.  Similar to
   simplify_minmaxloc_to_scalar.  */

static gfc_expr *
simplify_findloc_to_scalar (gfc_expr *result, gfc_expr *array, gfc_expr *value,
			    gfc_expr *mask, int back_val)
{
  gfc_expr *a, *m;
  gfc_constructor *array_ctor, *mask_ctor;
  mpz_t count;

  mpz_set_si (result->value.integer, 0);

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  array_ctor = gfc_constructor_first (array->value.constructor);
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);
  else
    mask_ctor = NULL;

  mpz_init_set_si (count, 0);
  while (array_ctor)
    {
      mpz_add_ui (count, count, 1);
      a = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);
      /* A constant MASK equals .TRUE. here and can be ignored.  */
      if (mask_ctor)
	{
	  m = mask_ctor->expr;
	  mask_ctor = gfc_constructor_next (mask_ctor);
	  if (!m->value.logical)
	    continue;
	}
      if (gfc_compare_expr (a, value, INTRINSIC_EQ) == 0)
	{
	  /* We have a match.  If BACK is true, continue so we find
	     the last one.  */
	  mpz_set (result->value.integer, count);
	  if (!back_val)
	    break;
	}
    }
  mpz_clear (count);
  return result;
}

/* Simplify findloc in the absence of a dim argument.  Similar to
   simplify_minmaxloc_nodim.  */

static gfc_expr *
simplify_findloc_nodim (gfc_expr *result, gfc_expr *value, gfc_expr *array,
			gfc_expr *mask, bool back_val)
{
  ssize_t res[GFC_MAX_DIMENSIONS];
  int i, n;
  gfc_constructor *result_ctor, *array_ctor, *mask_ctor;
  ssize_t count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
    sstride[GFC_MAX_DIMENSIONS];
  gfc_expr *a, *m;
  bool continue_loop;
  bool ma;

  for (i = 0; i < array->rank; i++)
    res[i] = -1;

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    goto finish;

  for (i = 0; i < array->rank; i++)
    {
      count[i] = 0;
      sstride[i] = (i == 0) ? 1 : sstride[i-1] * mpz_get_si (array->shape[i-1]);
      extent[i] = mpz_get_si (array->shape[i]);
      if (extent[i] <= 0)
	goto finish;
    }

  continue_loop = true;
  array_ctor = gfc_constructor_first (array->value.constructor);
  if (mask && mask->rank > 0)
    mask_ctor = gfc_constructor_first (mask->value.constructor);
  else
    mask_ctor = NULL;

  /* Loop over the array elements (and mask), keeping track of
     the indices to return.  */
  while (continue_loop)
    {
      do
	{
	  a = array_ctor->expr;
	  if (mask_ctor)
	    {
	      m = mask_ctor->expr;
	      ma = m->value.logical;
	      mask_ctor = gfc_constructor_next (mask_ctor);
	    }
	  else
	    ma = true;

	  if (ma && gfc_compare_expr (a, value, INTRINSIC_EQ) == 0)
	    {
	      for (i = 0; i < array->rank; i++)
		res[i] = count[i];
	      if (!back_val)
		goto finish;
	    }
	  array_ctor = gfc_constructor_next (array_ctor);
	  count[0] ++;
	} while (count[0] != extent[0]);
      n = 0;
      do
	{
	  /* When we get to the end of a dimension, reset it and increment
	     the next dimension.  */
	  count[n] = 0;
	  n++;
	  if (n >= array->rank)
	    {
	      continue_loop = false;
	      break;
	    }
	  else
	    count[n] ++;
	} while (count[n] == extent[n]);
    }

finish:
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < array->rank; i++)
    {
      gfc_expr *r_expr;
      r_expr = result_ctor->expr;
      mpz_set_si (r_expr->value.integer, res[i] + 1);
      result_ctor = gfc_constructor_next (result_ctor);
    }
  return result;
}


/* Simplify findloc to an array.  Similar to
   simplify_minmaxloc_to_array.  */

static gfc_expr *
simplify_findloc_to_array (gfc_expr *result, gfc_expr *array, gfc_expr *value,
			   gfc_expr *dim, gfc_expr *mask, bool back_val)
{
  mpz_t size;
  int done, i, n, arraysize, resultsize, dim_index, dim_extent, dim_stride;
  gfc_expr **arrayvec, **resultvec, **base, **src, **dest;
  gfc_constructor *array_ctor, *mask_ctor, *result_ctor;

  int count[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS],
      sstride[GFC_MAX_DIMENSIONS], dstride[GFC_MAX_DIMENSIONS],
      tmpstride[GFC_MAX_DIMENSIONS];

  /* Shortcut for constant .FALSE. MASK.  */
  if (mask
      && mask->expr_type == EXPR_CONSTANT
      && !mask->value.logical)
    return result;

  /* Build an indexed table for array element expressions to minimize
     linked-list traversal. Masked elements are set to NULL.  */
  gfc_array_size (array, &size);
  arraysize = mpz_get_ui (size);
  mpz_clear (size);

  arrayvec = XCNEWVEC (gfc_expr*, arraysize);

  array_ctor = gfc_constructor_first (array->value.constructor);
  mask_ctor = NULL;
  if (mask && mask->expr_type == EXPR_ARRAY)
    mask_ctor = gfc_constructor_first (mask->value.constructor);

  for (i = 0; i < arraysize; ++i)
    {
      arrayvec[i] = array_ctor->expr;
      array_ctor = gfc_constructor_next (array_ctor);

      if (mask_ctor)
	{
	  if (!mask_ctor->expr->value.logical)
	    arrayvec[i] = NULL;

	  mask_ctor = gfc_constructor_next (mask_ctor);
	}
    }

  /* Same for the result expression.  */
  gfc_array_size (result, &size);
  resultsize = mpz_get_ui (size);
  mpz_clear (size);

  resultvec = XCNEWVEC (gfc_expr*, resultsize);
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      resultvec[i] = result_ctor->expr;
      result_ctor = gfc_constructor_next (result_ctor);
    }

  gfc_extract_int (dim, &dim_index);

  dim_index -= 1;	/* Zero-base index.  */
  dim_extent = 0;
  dim_stride = 0;

  for (i = 0, n = 0; i < array->rank; ++i)
    {
      count[i] = 0;
      tmpstride[i] = (i == 0) ? 1 : tmpstride[i-1] * mpz_get_si (array->shape[i-1]);
      if (i == dim_index)
	{
	  dim_extent = mpz_get_si (array->shape[i]);
	  dim_stride = tmpstride[i];
	  continue;
	}

      extent[n] = mpz_get_si (array->shape[i]);
      sstride[n] = tmpstride[i];
      dstride[n] = (n == 0) ? 1 : dstride[n-1] * extent[n-1];
      n += 1;
    }

  done = resultsize <= 0;
  base = arrayvec;
  dest = resultvec;
  while (!done)
    {
      for (src = base, n = 0; n < dim_extent; src += dim_stride, ++n)
	{
	  if (*src && gfc_compare_expr (*src, value, INTRINSIC_EQ) == 0)
	    {
	      mpz_set_si ((*dest)->value.integer, n + 1);
	      if (!back_val)
		break;
	    }
	}

      count[0]++;
      base += sstride[0];
      dest += dstride[0];

      n = 0;
      while (!done && count[n] == extent[n])
	{
	  count[n] = 0;
	  base -= sstride[n] * extent[n];
	  dest -= dstride[n] * extent[n];

	  n++;
	  if (n < result->rank)
	    {
	      /* If the nested loop is unrolled GFC_MAX_DIMENSIONS
		 times, we'd warn for the last iteration, because the
		 array index will have already been incremented to the
		 array sizes, and we can't tell that this must make
		 the test against result->rank false, because ranks
		 must not exceed GFC_MAX_DIMENSIONS.  */
	      GCC_DIAGNOSTIC_PUSH_IGNORED (-Warray-bounds)
	      count[n]++;
	      base += sstride[n];
	      dest += dstride[n];
	      GCC_DIAGNOSTIC_POP
	    }
	  else
	    done = true;
       }
    }

  /* Place updated expression in result constructor.  */
  result_ctor = gfc_constructor_first (result->value.constructor);
  for (i = 0; i < resultsize; ++i)
    {
      result_ctor->expr = resultvec[i];
      result_ctor = gfc_constructor_next (result_ctor);
    }

  free (arrayvec);
  free (resultvec);
  return result;
}

/* Simplify findloc.  */

gfc_expr *
gfc_simplify_findloc (gfc_expr *array, gfc_expr *value, gfc_expr *dim,
		      gfc_expr *mask, gfc_expr *kind, gfc_expr *back)
{
  gfc_expr *result;
  int ikind;
  bool back_val = false;

  if (!is_constant_array_expr (array)
      || !gfc_is_constant_expr (dim))
    return NULL;

  if (! gfc_is_constant_expr (value))
    return 0;

  if (mask
      && !is_constant_array_expr (mask)
      && mask->expr_type != EXPR_CONSTANT)
    return NULL;

  if (kind)
    {
      if (gfc_extract_int (kind, &ikind, -1))
	return NULL;
    }
  else
    ikind = gfc_default_integer_kind;

  if (back)
    {
      if (back->expr_type != EXPR_CONSTANT)
	return NULL;

      back_val = back->value.logical;
    }

  if (dim)
    {
      result = transformational_result (array, dim, BT_INTEGER,
					ikind, &array->where);
      init_result_expr (result, 0, array);

      if (array->rank == 1)
	return simplify_findloc_to_scalar (result, array, value, mask,
					   back_val);
      else
	return simplify_findloc_to_array (result, array, value, dim, mask,
      					  back_val);
    }
  else
    {
      result = new_array (BT_INTEGER, ikind, array->rank, &array->where);
      return simplify_findloc_nodim (result, value, array, mask, back_val);
    }
  return NULL;
}

gfc_expr *
gfc_simplify_maxexponent (gfc_expr *x)
{
  int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
  return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
			   gfc_real_kinds[i].max_exponent);
}


gfc_expr *
gfc_simplify_minexponent (gfc_expr *x)
{
  int i = gfc_validate_kind (BT_REAL, x->ts.kind, false);
  return gfc_get_int_expr (gfc_default_integer_kind, &x->where,
			   gfc_real_kinds[i].min_exponent);
}


gfc_expr *
gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
{
  gfc_expr *result;
  int kind;

  /* First check p.  */
  if (p->expr_type != EXPR_CONSTANT)
    return NULL;

  /* p shall not be 0.  */
  switch (p->ts.type)
    {
      case BT_INTEGER:
	if (mpz_cmp_ui (p->value.integer, 0) == 0)
	  {
	    gfc_error ("Argument %qs of MOD at %L shall not be zero",
			"P", &p->where);
	    return &gfc_bad_expr;
	  }
	break;
      case BT_REAL:
	if (mpfr_cmp_ui (p->value.real, 0) == 0)
	  {
	    gfc_error ("Argument %qs of MOD at %L shall not be zero",
			"P", &p->where);
	    return &gfc_bad_expr;
	  }
	break;
      default:
	gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
    }

  if (a->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
  result = gfc_get_constant_expr (a->ts.type, kind, &a->where);

  if (a->ts.type == BT_INTEGER)
    mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
  else
    {
      gfc_set_model_kind (kind);
      mpfr_fmod (result->value.real, a->value.real, p->value.real,
		 GFC_RND_MODE);
    }

  return range_check (result, "MOD");
}


gfc_expr *
gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
{
  gfc_expr *result;
  int kind;

  /* First check p.  */
  if (p->expr_type != EXPR_CONSTANT)
    return NULL;

  /* p shall not be 0.  */
  switch (p->ts.type)
    {
      case BT_INTEGER:
	if (mpz_cmp_ui (p->value.integer, 0) == 0)
	  {
	    gfc_error ("Argument %qs of MODULO at %L shall not be zero",
			"P", &p->where);
	    return &gfc_bad_expr;
	  }
	break;
      case BT_REAL:
	if (mpfr_cmp_ui (p->value.real, 0) == 0)
	  {
	    gfc_error ("Argument %qs of MODULO at %L shall not be zero",
			"P", &p->where);
	    return &gfc_bad_expr;
	  }
	break;
      default:
	gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
    }

  if (a->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
  result = gfc_get_constant_expr (a->ts.type, kind, &a->where);

  if (a->ts.type == BT_INTEGER)
	mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
  else
    {
      gfc_set_model_kind (kind);
      mpfr_fmod (result->value.real, a->value.real, p->value.real,
                 GFC_RND_MODE);
      if (mpfr_cmp_ui (result->value.real, 0) != 0)
        {
          if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
            mpfr_add (result->value.real, result->value.real, p->value.real,
                      GFC_RND_MODE);
	    }
	  else
        mpfr_copysign (result->value.real, result->value.real,
                       p->value.real, GFC_RND_MODE);
    }

  return range_check (result, "MODULO");
}


gfc_expr *
gfc_simplify_nearest (gfc_expr *x, gfc_expr *s)
{
  gfc_expr *result;
  mpfr_exp_t emin, emax;
  int kind;

  if (x->expr_type != EXPR_CONSTANT || s->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_copy_expr (x);

  /* Save current values of emin and emax.  */
  emin = mpfr_get_emin ();
  emax = mpfr_get_emax ();

  /* Set emin and emax for the current model number.  */
  kind = gfc_validate_kind (BT_REAL, x->ts.kind, 0);
  mpfr_set_emin ((mpfr_exp_t) gfc_real_kinds[kind].min_exponent -
		mpfr_get_prec(result->value.real) + 1);
  mpfr_set_emax ((mpfr_exp_t) gfc_real_kinds[kind].max_exponent - 1);
  mpfr_check_range (result->value.real, 0, MPFR_RNDU);

  if (mpfr_sgn (s->value.real) > 0)
    {
      mpfr_nextabove (result->value.real);
      mpfr_subnormalize (result->value.real, 0, MPFR_RNDU);
    }
  else
    {
      mpfr_nextbelow (result->value.real);
      mpfr_subnormalize (result->value.real, 0, MPFR_RNDD);
    }

  mpfr_set_emin (emin);
  mpfr_set_emax (emax);

  /* Only NaN can occur. Do not use range check as it gives an
     error for denormal numbers.  */
  if (mpfr_nan_p (result->value.real) && flag_range_check)
    {
      gfc_error ("Result of NEAREST is NaN at %L", &result->where);
      gfc_free_expr (result);
      return &gfc_bad_expr;
    }

  return result;
}


static gfc_expr *
simplify_nint (const char *name, gfc_expr *e, gfc_expr *k)
{
  gfc_expr *itrunc, *result;
  int kind;

  kind = get_kind (BT_INTEGER, k, name, gfc_default_integer_kind);
  if (kind == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  itrunc = gfc_copy_expr (e);
  mpfr_round (itrunc->value.real, e->value.real);

  result = gfc_get_constant_expr (BT_INTEGER, kind, &e->where);
  gfc_mpfr_to_mpz (result->value.integer, itrunc->value.real, &e->where);

  gfc_free_expr (itrunc);

  return range_check (result, name);
}


gfc_expr *
gfc_simplify_new_line (gfc_expr *e)
{
  gfc_expr *result;

  result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, 1);
  result->value.character.string[0] = '\n';

  return result;
}


gfc_expr *
gfc_simplify_nint (gfc_expr *e, gfc_expr *k)
{
  return simplify_nint ("NINT", e, k);
}


gfc_expr *
gfc_simplify_idnint (gfc_expr *e)
{
  return simplify_nint ("IDNINT", e, NULL);
}

static int norm2_scale;

static gfc_expr *
norm2_add_squared (gfc_expr *result, gfc_expr *e)
{
  mpfr_t tmp;

  gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_REAL
	      && result->expr_type == EXPR_CONSTANT);

  gfc_set_model_kind (result->ts.kind);
  int index = gfc_validate_kind (BT_REAL, result->ts.kind, false);
  mpfr_exp_t exp;
  if (mpfr_regular_p (result->value.real))
    {
      exp = mpfr_get_exp (result->value.real);
      /* If result is getting close to overflowing, scale down.  */
      if (exp >= gfc_real_kinds[index].max_exponent - 4
	  && norm2_scale <= gfc_real_kinds[index].max_exponent - 2)
	{
	  norm2_scale += 2;
	  mpfr_div_ui (result->value.real, result->value.real, 16,
		       GFC_RND_MODE);
	}
    }

  mpfr_init (tmp);
  if (mpfr_regular_p (e->value.real))
    {
      exp = mpfr_get_exp (e->value.real);
      /* If e**2 would overflow or close to overflowing, scale down.  */
      if (exp - norm2_scale >= gfc_real_kinds[index].max_exponent / 2 - 2)
	{
	  int new_scale = gfc_real_kinds[index].max_exponent / 2 + 4;
	  mpfr_set_ui (tmp, 1, GFC_RND_MODE);
	  mpfr_set_exp (tmp, new_scale - norm2_scale);
	  mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE);
	  mpfr_div (result->value.real, result->value.real, tmp, GFC_RND_MODE);
	  norm2_scale = new_scale;
	}
    }
  if (norm2_scale)
    {
      mpfr_set_ui (tmp, 1, GFC_RND_MODE);
      mpfr_set_exp (tmp, norm2_scale);
      mpfr_div (tmp, e->value.real, tmp, GFC_RND_MODE);
    }
  else
    mpfr_set (tmp, e->value.real, GFC_RND_MODE);
  mpfr_pow_ui (tmp, tmp, 2, GFC_RND_MODE);
  mpfr_add (result->value.real, result->value.real, tmp,
	    GFC_RND_MODE);
  mpfr_clear (tmp);

  return result;
}


static gfc_expr *
norm2_do_sqrt (gfc_expr *result, gfc_expr *e)
{
  gcc_assert (e->ts.type == BT_REAL && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_REAL
	      && result->expr_type == EXPR_CONSTANT);

  if (result != e)
    mpfr_set (result->value.real, e->value.real, GFC_RND_MODE);
  mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
  if (norm2_scale && mpfr_regular_p (result->value.real))
    {
      mpfr_t tmp;
      mpfr_init (tmp);
      mpfr_set_ui (tmp, 1, GFC_RND_MODE);
      mpfr_set_exp (tmp, norm2_scale);
      mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
      mpfr_clear (tmp);
    }
  norm2_scale = 0;

  return result;
}


gfc_expr *
gfc_simplify_norm2 (gfc_expr *e, gfc_expr *dim)
{
  gfc_expr *result;
  bool size_zero;

  size_zero = gfc_is_size_zero_array (e);

  if (!(is_constant_array_expr (e) || size_zero)
      || (dim != NULL && !gfc_is_constant_expr (dim)))
    return NULL;

  result = transformational_result (e, dim, e->ts.type, e->ts.kind, &e->where);
  init_result_expr (result, 0, NULL);

  if (size_zero)
    return result;

  norm2_scale = 0;
  if (!dim || e->rank == 1)
    {
      result = simplify_transformation_to_scalar (result, e, NULL,
						  norm2_add_squared);
      mpfr_sqrt (result->value.real, result->value.real, GFC_RND_MODE);
      if (norm2_scale && mpfr_regular_p (result->value.real))
	{
	  mpfr_t tmp;
	  mpfr_init (tmp);
	  mpfr_set_ui (tmp, 1, GFC_RND_MODE);
	  mpfr_set_exp (tmp, norm2_scale);
	  mpfr_mul (result->value.real, result->value.real, tmp, GFC_RND_MODE);
	  mpfr_clear (tmp);
	}
      norm2_scale = 0;
    }
  else
    result = simplify_transformation_to_array (result, e, dim, NULL,
					       norm2_add_squared,
					       norm2_do_sqrt);

  return result;
}


gfc_expr *
gfc_simplify_not (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
  mpz_com (result->value.integer, e->value.integer);

  return range_check (result, "NOT");
}


gfc_expr *
gfc_simplify_null (gfc_expr *mold)
{
  gfc_expr *result;

  if (mold)
    {
      result = gfc_copy_expr (mold);
      result->expr_type = EXPR_NULL;
    }
  else
    result = gfc_get_null_expr (NULL);

  return result;
}


gfc_expr *
gfc_simplify_num_images (gfc_expr *distance ATTRIBUTE_UNUSED, gfc_expr *failed)
{
  gfc_expr *result;

  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return &gfc_bad_expr;
    }

  if (flag_coarray != GFC_FCOARRAY_SINGLE)
    return NULL;

  if (failed && failed->expr_type != EXPR_CONSTANT)
    return NULL;

  /* FIXME: gfc_current_locus is wrong.  */
  result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				  &gfc_current_locus);

  if (failed && failed->value.logical != 0)
    mpz_set_si (result->value.integer, 0);
  else
    mpz_set_si (result->value.integer, 1);

  return result;
}


gfc_expr *
gfc_simplify_or (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int kind;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;

  switch (x->ts.type)
    {
      case BT_INTEGER:
	result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
	mpz_ior (result->value.integer, x->value.integer, y->value.integer);
	return range_check (result, "OR");

      case BT_LOGICAL:
	return gfc_get_logical_expr (kind, &x->where,
				     x->value.logical || y->value.logical);
      default:
	gcc_unreachable();
    }
}


gfc_expr *
gfc_simplify_pack (gfc_expr *array, gfc_expr *mask, gfc_expr *vector)
{
  gfc_expr *result;
  gfc_constructor *array_ctor, *mask_ctor, *vector_ctor;

  if (!is_constant_array_expr (array)
      || !is_constant_array_expr (vector)
      || (!gfc_is_constant_expr (mask)
          && !is_constant_array_expr (mask)))
    return NULL;

  result = gfc_get_array_expr (array->ts.type, array->ts.kind, &array->where);
  if (array->ts.type == BT_DERIVED)
    result->ts.u.derived = array->ts.u.derived;

  array_ctor = gfc_constructor_first (array->value.constructor);
  vector_ctor = vector
		  ? gfc_constructor_first (vector->value.constructor)
		  : NULL;

  if (mask->expr_type == EXPR_CONSTANT
      && mask->value.logical)
    {
      /* Copy all elements of ARRAY to RESULT.  */
      while (array_ctor)
	{
	  gfc_constructor_append_expr (&result->value.constructor,
				       gfc_copy_expr (array_ctor->expr),
				       NULL);

	  array_ctor = gfc_constructor_next (array_ctor);
	  vector_ctor = gfc_constructor_next (vector_ctor);
	}
    }
  else if (mask->expr_type == EXPR_ARRAY)
    {
      /* Copy only those elements of ARRAY to RESULT whose
	 MASK equals .TRUE..  */
      mask_ctor = gfc_constructor_first (mask->value.constructor);
      while (mask_ctor)
	{
	  if (mask_ctor->expr->value.logical)
	    {
	      gfc_constructor_append_expr (&result->value.constructor,
					   gfc_copy_expr (array_ctor->expr),
					   NULL);
	      vector_ctor = gfc_constructor_next (vector_ctor);
	    }

	  array_ctor = gfc_constructor_next (array_ctor);
	  mask_ctor = gfc_constructor_next (mask_ctor);
	}
    }

  /* Append any left-over elements from VECTOR to RESULT.  */
  while (vector_ctor)
    {
      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_copy_expr (vector_ctor->expr),
				   NULL);
      vector_ctor = gfc_constructor_next (vector_ctor);
    }

  result->shape = gfc_get_shape (1);
  gfc_array_size (result, &result->shape[0]);

  if (array->ts.type == BT_CHARACTER)
    result->ts.u.cl = array->ts.u.cl;

  return result;
}


static gfc_expr *
do_xor (gfc_expr *result, gfc_expr *e)
{
  gcc_assert (e->ts.type == BT_LOGICAL && e->expr_type == EXPR_CONSTANT);
  gcc_assert (result->ts.type == BT_LOGICAL
	      && result->expr_type == EXPR_CONSTANT);

  result->value.logical = result->value.logical != e->value.logical;
  return result;
}


gfc_expr *
gfc_simplify_is_contiguous (gfc_expr *array)
{
  if (gfc_is_simply_contiguous (array, false, true))
    return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 1);

  if (gfc_is_not_contiguous (array))
    return gfc_get_logical_expr (gfc_default_logical_kind, &array->where, 0);

  return NULL;
}


gfc_expr *
gfc_simplify_parity (gfc_expr *e, gfc_expr *dim)
{
  return simplify_transformation (e, dim, NULL, 0, do_xor);
}


gfc_expr *
gfc_simplify_popcnt (gfc_expr *e)
{
  int res, k;
  mpz_t x;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  k = gfc_validate_kind (e->ts.type, e->ts.kind, false);

  /* Convert argument to unsigned, then count the '1' bits.  */
  mpz_init_set (x, e->value.integer);
  convert_mpz_to_unsigned (x, gfc_integer_kinds[k].bit_size);
  res = mpz_popcount (x);
  mpz_clear (x);

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, res);
}


gfc_expr *
gfc_simplify_poppar (gfc_expr *e)
{
  gfc_expr *popcnt;
  int i;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  popcnt = gfc_simplify_popcnt (e);
  gcc_assert (popcnt);

  bool fail = gfc_extract_int (popcnt, &i);
  gcc_assert (!fail);

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i % 2);
}


gfc_expr *
gfc_simplify_precision (gfc_expr *e)
{
  int i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  return gfc_get_int_expr (gfc_default_integer_kind, &e->where,
			   gfc_real_kinds[i].precision);
}


gfc_expr *
gfc_simplify_product (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, 1, gfc_multiply);
}


gfc_expr *
gfc_simplify_radix (gfc_expr *e)
{
  int i;
  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);

  switch (e->ts.type)
    {
      case BT_INTEGER:
	i = gfc_integer_kinds[i].radix;
	break;

      case BT_REAL:
	i = gfc_real_kinds[i].radix;
	break;

      default:
	gcc_unreachable ();
    }

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
}


gfc_expr *
gfc_simplify_range (gfc_expr *e)
{
  int i;
  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);

  switch (e->ts.type)
    {
      case BT_INTEGER:
	i = gfc_integer_kinds[i].range;
	break;

      case BT_REAL:
      case BT_COMPLEX:
	i = gfc_real_kinds[i].range;
	break;

      default:
	gcc_unreachable ();
    }

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, i);
}


gfc_expr *
gfc_simplify_rank (gfc_expr *e)
{
  /* Assumed rank.  */
  if (e->rank == -1)
    return NULL;

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, e->rank);
}


gfc_expr *
gfc_simplify_real (gfc_expr *e, gfc_expr *k)
{
  gfc_expr *result = NULL;
  int kind, tmp1, tmp2;

  /* Convert BOZ to real, and return without range checking.  */
  if (e->ts.type == BT_BOZ)
    {
      /* Determine kind for conversion of the BOZ.  */
      if (k)
	gfc_extract_int (k, &kind);
      else
	kind = gfc_default_real_kind;

      if (!gfc_boz2real (e, kind))
	return NULL;
      result = gfc_copy_expr (e);
      return result;
    }

  if (e->ts.type == BT_COMPLEX)
    kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);
  else
    kind = get_kind (BT_REAL, k, "REAL", gfc_default_real_kind);

  if (kind == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
     warnings.  */
  tmp1 = warn_conversion;
  tmp2 = warn_conversion_extra;
  warn_conversion = warn_conversion_extra = 0;

  result = gfc_convert_constant (e, BT_REAL, kind);

  warn_conversion = tmp1;
  warn_conversion_extra = tmp2;

  if (result == &gfc_bad_expr)
    return &gfc_bad_expr;

  return range_check (result, "REAL");
}


gfc_expr *
gfc_simplify_realpart (gfc_expr *e)
{
  gfc_expr *result;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
  mpc_real (result->value.real, e->value.complex, GFC_RND_MODE);

  return range_check (result, "REALPART");
}

gfc_expr *
gfc_simplify_repeat (gfc_expr *e, gfc_expr *n)
{
  gfc_expr *result;
  gfc_charlen_t len;
  mpz_t ncopies;
  bool have_length = false;

  /* If NCOPIES isn't a constant, there's nothing we can do.  */
  if (n->expr_type != EXPR_CONSTANT)
    return NULL;

  /* If NCOPIES is negative, it's an error.  */
  if (mpz_sgn (n->value.integer) < 0)
    {
      gfc_error ("Argument NCOPIES of REPEAT intrinsic is negative at %L",
		 &n->where);
      return &gfc_bad_expr;
    }

  /* If we don't know the character length, we can do no more.  */
  if (e->ts.u.cl && e->ts.u.cl->length
	&& e->ts.u.cl->length->expr_type == EXPR_CONSTANT)
    {
      len = gfc_mpz_get_hwi (e->ts.u.cl->length->value.integer);
      have_length = true;
    }
  else if (e->expr_type == EXPR_CONSTANT
	     && (e->ts.u.cl == NULL || e->ts.u.cl->length == NULL))
    {
      len = e->value.character.length;
    }
  else
    return NULL;

  /* If the source length is 0, any value of NCOPIES is valid
     and everything behaves as if NCOPIES == 0.  */
  mpz_init (ncopies);
  if (len == 0)
    mpz_set_ui (ncopies, 0);
  else
    mpz_set (ncopies, n->value.integer);

  /* Check that NCOPIES isn't too large.  */
  if (len)
    {
      mpz_t max, mlen;
      int i;

      /* Compute the maximum value allowed for NCOPIES: huge(cl) / len.  */
      mpz_init (max);
      i = gfc_validate_kind (BT_INTEGER, gfc_charlen_int_kind, false);

      if (have_length)
	{
	  mpz_tdiv_q (max, gfc_integer_kinds[i].huge,
		      e->ts.u.cl->length->value.integer);
	}
      else
	{
	  mpz_init (mlen);
	  gfc_mpz_set_hwi (mlen, len);
	  mpz_tdiv_q (max, gfc_integer_kinds[i].huge, mlen);
	  mpz_clear (mlen);
	}

      /* The check itself.  */
      if (mpz_cmp (ncopies, max) > 0)
	{
	  mpz_clear (max);
	  mpz_clear (ncopies);
	  gfc_error ("Argument NCOPIES of REPEAT intrinsic is too large at %L",
		     &n->where);
	  return &gfc_bad_expr;
	}

      mpz_clear (max);
    }
  mpz_clear (ncopies);

  /* For further simplification, we need the character string to be
     constant.  */
  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  HOST_WIDE_INT ncop;
  if (len ||
      (e->ts.u.cl->length &&
       mpz_sgn (e->ts.u.cl->length->value.integer) != 0))
    {
      bool fail = gfc_extract_hwi (n, &ncop);
      gcc_assert (!fail);
    }
  else
    ncop = 0;

  if (ncop == 0)
    return gfc_get_character_expr (e->ts.kind, &e->where, NULL, 0);

  len = e->value.character.length;
  gfc_charlen_t nlen = ncop * len;

  /* Here's a semi-arbitrary limit. If the string is longer than 1 GB
     (2**28 elements * 4 bytes (wide chars) per element) defer to
     runtime instead of consuming (unbounded) memory and CPU at
     compile time.  */
  if (nlen > 268435456)
    {
      gfc_warning_now (0, "Evaluation of string longer than 2**28 at %L"
		       " deferred to runtime, expect bugs", &e->where);
      return NULL;
    }

  result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, nlen);
  for (size_t i = 0; i < (size_t) ncop; i++)
    for (size_t j = 0; j < (size_t) len; j++)
      result->value.character.string[j+i*len]= e->value.character.string[j];

  result->value.character.string[nlen] = '\0';	/* For debugger */
  return result;
}


/* This one is a bear, but mainly has to do with shuffling elements.  */

gfc_expr *
gfc_simplify_reshape (gfc_expr *source, gfc_expr *shape_exp,
		      gfc_expr *pad, gfc_expr *order_exp)
{
  int order[GFC_MAX_DIMENSIONS], shape[GFC_MAX_DIMENSIONS];
  int i, rank, npad, x[GFC_MAX_DIMENSIONS];
  mpz_t index, size;
  unsigned long j;
  size_t nsource;
  gfc_expr *e, *result;
  bool zerosize = false;

  /* Check that argument expression types are OK.  */
  if (!is_constant_array_expr (source)
      || !is_constant_array_expr (shape_exp)
      || !is_constant_array_expr (pad)
      || !is_constant_array_expr (order_exp))
    return NULL;

  if (source->shape == NULL)
    return NULL;

  /* Proceed with simplification, unpacking the array.  */

  mpz_init (index);
  rank = 0;

  for (i = 0; i < GFC_MAX_DIMENSIONS; i++)
    x[i] = 0;

  for (;;)
    {
      e = gfc_constructor_lookup_expr (shape_exp->value.constructor, rank);
      if (e == NULL)
	break;

      gfc_extract_int (e, &shape[rank]);

      gcc_assert (rank >= 0 && rank < GFC_MAX_DIMENSIONS);
      gcc_assert (shape[rank] >= 0);

      rank++;
    }

  gcc_assert (rank > 0);

  /* Now unpack the order array if present.  */
  if (order_exp == NULL)
    {
      for (i = 0; i < rank; i++)
	order[i] = i;
    }
  else
    {
      mpz_t size;
      int order_size, shape_size;

      if (order_exp->rank != shape_exp->rank)
	{
	  gfc_error ("Shapes of ORDER at %L and SHAPE at %L are different",
		     &order_exp->where, &shape_exp->where);
	  return &gfc_bad_expr;
	}

      gfc_array_size (shape_exp, &size);
      shape_size = mpz_get_ui (size);
      mpz_clear (size);
      gfc_array_size (order_exp, &size);
      order_size = mpz_get_ui (size);
      mpz_clear (size);
      if (order_size != shape_size)
	{
	  gfc_error ("Sizes of ORDER at %L and SHAPE at %L are different",
		     &order_exp->where, &shape_exp->where);
	  return &gfc_bad_expr;
	}

      for (i = 0; i < rank; i++)
	{
	  e = gfc_constructor_lookup_expr (order_exp->value.constructor, i);
	  gcc_assert (e);

	  gfc_extract_int (e, &order[i]);

	  if (order[i] < 1 || order[i] > rank)
	    {
	      gfc_error ("Element with a value of %d in ORDER at %L must be "
			 "in the range [1, ..., %d] for the RESHAPE intrinsic "
			 "near %L", order[i], &order_exp->where, rank,
			 &shape_exp->where);
	      return &gfc_bad_expr;
	    }

	  order[i]--;
	  if (x[order[i]] != 0)
	    {
	      gfc_error ("ORDER at %L is not a permutation of the size of "
			 "SHAPE at %L", &order_exp->where, &shape_exp->where);
	      return &gfc_bad_expr;
	    }
	  x[order[i]] = 1;
	}
    }

  /* Count the elements in the source and padding arrays.  */

  npad = 0;
  if (pad != NULL)
    {
      gfc_array_size (pad, &size);
      npad = mpz_get_ui (size);
      mpz_clear (size);
    }

  gfc_array_size (source, &size);
  nsource = mpz_get_ui (size);
  mpz_clear (size);

  /* If it weren't for that pesky permutation we could just loop
     through the source and round out any shortage with pad elements.
     But no, someone just had to have the compiler do something the
     user should be doing.  */

  for (i = 0; i < rank; i++)
    x[i] = 0;

  result = gfc_get_array_expr (source->ts.type, source->ts.kind,
			       &source->where);
  if (source->ts.type == BT_DERIVED)
    result->ts.u.derived = source->ts.u.derived;
  if (source->ts.type == BT_CHARACTER && result->ts.u.cl == NULL)
    result->ts = source->ts;
  result->rank = rank;
  result->shape = gfc_get_shape (rank);
  for (i = 0; i < rank; i++)
    {
      mpz_init_set_ui (result->shape[i], shape[i]);
      if (shape[i] == 0)
	zerosize = true;
    }

  if (zerosize)
    goto sizezero;

  while (nsource > 0 || npad > 0)
    {
      /* Figure out which element to extract.  */
      mpz_set_ui (index, 0);

      for (i = rank - 1; i >= 0; i--)
	{
	  mpz_add_ui (index, index, x[order[i]]);
	  if (i != 0)
	    mpz_mul_ui (index, index, shape[order[i - 1]]);
	}

      if (mpz_cmp_ui (index, INT_MAX) > 0)
	gfc_internal_error ("Reshaped array too large at %C");

      j = mpz_get_ui (index);

      if (j < nsource)
	e = gfc_constructor_lookup_expr (source->value.constructor, j);
      else
	{
	  if (npad <= 0)
	    {
	      mpz_clear (index);
	      return NULL;
	    }
	  j = j - nsource;
	  j = j % npad;
	  e = gfc_constructor_lookup_expr (pad->value.constructor, j);
	}
      gcc_assert (e);

      gfc_constructor_append_expr (&result->value.constructor,
				   gfc_copy_expr (e), &e->where);

      /* Calculate the next element.  */
      i = 0;

inc:
      if (++x[i] < shape[i])
	continue;
      x[i++] = 0;
      if (i < rank)
	goto inc;

      break;
    }

sizezero:

  mpz_clear (index);

  return result;
}


gfc_expr *
gfc_simplify_rrspacing (gfc_expr *x)
{
  gfc_expr *result;
  int i;
  long int e, p;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  i = gfc_validate_kind (x->ts.type, x->ts.kind, false);

  result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

  /* RRSPACING(+/- 0.0) = 0.0  */
  if (mpfr_zero_p (x->value.real))
    {
      mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
      return result;
    }

  /* RRSPACING(inf) = NaN  */
  if (mpfr_inf_p (x->value.real))
    {
      mpfr_set_nan (result->value.real);
      return result;
    }

  /* RRSPACING(NaN) = same NaN  */
  if (mpfr_nan_p (x->value.real))
    {
      mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
      return result;
    }

  /* | x * 2**(-e) | * 2**p.  */
  mpfr_abs (result->value.real, x->value.real, GFC_RND_MODE);
  e = - (long int) mpfr_get_exp (x->value.real);
  mpfr_mul_2si (result->value.real, result->value.real, e, GFC_RND_MODE);

  p = (long int) gfc_real_kinds[i].digits;
  mpfr_mul_2si (result->value.real, result->value.real, p, GFC_RND_MODE);

  return range_check (result, "RRSPACING");
}


gfc_expr *
gfc_simplify_scale (gfc_expr *x, gfc_expr *i)
{
  int k, neg_flag, power, exp_range;
  mpfr_t scale, radix;
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

  if (mpfr_zero_p (x->value.real))
    {
      mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
      return result;
    }

  k = gfc_validate_kind (BT_REAL, x->ts.kind, false);

  exp_range = gfc_real_kinds[k].max_exponent - gfc_real_kinds[k].min_exponent;

  /* This check filters out values of i that would overflow an int.  */
  if (mpz_cmp_si (i->value.integer, exp_range + 2) > 0
      || mpz_cmp_si (i->value.integer, -exp_range - 2) < 0)
    {
      gfc_error ("Result of SCALE overflows its kind at %L", &result->where);
      gfc_free_expr (result);
      return &gfc_bad_expr;
    }

  /* Compute scale = radix ** power.  */
  power = mpz_get_si (i->value.integer);

  if (power >= 0)
    neg_flag = 0;
  else
    {
      neg_flag = 1;
      power = -power;
    }

  gfc_set_model_kind (x->ts.kind);
  mpfr_init (scale);
  mpfr_init (radix);
  mpfr_set_ui (radix, gfc_real_kinds[k].radix, GFC_RND_MODE);
  mpfr_pow_ui (scale, radix, power, GFC_RND_MODE);

  if (neg_flag)
    mpfr_div (result->value.real, x->value.real, scale, GFC_RND_MODE);
  else
    mpfr_mul (result->value.real, x->value.real, scale, GFC_RND_MODE);

  mpfr_clears (scale, radix, NULL);

  return range_check (result, "SCALE");
}


/* Variants of strspn and strcspn that operate on wide characters.  */

static size_t
wide_strspn (const gfc_char_t *s1, const gfc_char_t *s2)
{
  size_t i = 0;
  const gfc_char_t *c;

  while (s1[i])
    {
      for (c = s2; *c; c++)
	{
	  if (s1[i] == *c)
	    break;
	}
      if (*c == '\0')
	break;
      i++;
    }

  return i;
}

static size_t
wide_strcspn (const gfc_char_t *s1, const gfc_char_t *s2)
{
  size_t i = 0;
  const gfc_char_t *c;

  while (s1[i])
    {
      for (c = s2; *c; c++)
	{
	  if (s1[i] == *c)
	    break;
	}
      if (*c)
	break;
      i++;
    }

  return i;
}


gfc_expr *
gfc_simplify_scan (gfc_expr *e, gfc_expr *c, gfc_expr *b, gfc_expr *kind)
{
  gfc_expr *result;
  int back;
  size_t i;
  size_t indx, len, lenc;
  int k = get_kind (BT_INTEGER, kind, "SCAN", gfc_default_integer_kind);

  if (k == -1)
    return &gfc_bad_expr;

  if (e->expr_type != EXPR_CONSTANT || c->expr_type != EXPR_CONSTANT
      || ( b != NULL && b->expr_type !=  EXPR_CONSTANT))
    return NULL;

  if (b != NULL && b->value.logical != 0)
    back = 1;
  else
    back = 0;

  len = e->value.character.length;
  lenc = c->value.character.length;

  if (len == 0 || lenc == 0)
    {
      indx = 0;
    }
  else
    {
      if (back == 0)
	{
	  indx = wide_strcspn (e->value.character.string,
			       c->value.character.string) + 1;
	  if (indx > len)
	    indx = 0;
	}
      else
	for (indx = len; indx > 0; indx--)
	  {
	    for (i = 0; i < lenc; i++)
	      {
		if (c->value.character.string[i]
		    == e->value.character.string[indx - 1])
		  break;
	      }
	    if (i < lenc)
	      break;
	  }
    }

  result = gfc_get_int_expr (k, &e->where, indx);
  return range_check (result, "SCAN");
}


gfc_expr *
gfc_simplify_selected_char_kind (gfc_expr *e)
{
  int kind;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  if (gfc_compare_with_Cstring (e, "ascii", false) == 0
      || gfc_compare_with_Cstring (e, "default", false) == 0)
    kind = 1;
  else if (gfc_compare_with_Cstring (e, "iso_10646", false) == 0)
    kind = 4;
  else
    kind = -1;

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
}


gfc_expr *
gfc_simplify_selected_int_kind (gfc_expr *e)
{
  int i, kind, range;

  if (e->expr_type != EXPR_CONSTANT || gfc_extract_int (e, &range))
    return NULL;

  kind = INT_MAX;

  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
    if (gfc_integer_kinds[i].range >= range
	&& gfc_integer_kinds[i].kind < kind)
      kind = gfc_integer_kinds[i].kind;

  if (kind == INT_MAX)
    kind = -1;

  return gfc_get_int_expr (gfc_default_integer_kind, &e->where, kind);
}


gfc_expr *
gfc_simplify_selected_real_kind (gfc_expr *p, gfc_expr *q, gfc_expr *rdx)
{
  int range, precision, radix, i, kind, found_precision, found_range,
      found_radix;
  locus *loc = &gfc_current_locus;

  if (p == NULL)
    precision = 0;
  else
    {
      if (p->expr_type != EXPR_CONSTANT
	  || gfc_extract_int (p, &precision))
	return NULL;
      loc = &p->where;
    }

  if (q == NULL)
    range = 0;
  else
    {
      if (q->expr_type != EXPR_CONSTANT
	  || gfc_extract_int (q, &range))
	return NULL;

      if (!loc)
	loc = &q->where;
    }

  if (rdx == NULL)
    radix = 0;
  else
    {
      if (rdx->expr_type != EXPR_CONSTANT
	  || gfc_extract_int (rdx, &radix))
	return NULL;

      if (!loc)
	loc = &rdx->where;
    }

  kind = INT_MAX;
  found_precision = 0;
  found_range = 0;
  found_radix = 0;

  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
    {
      if (gfc_real_kinds[i].precision >= precision)
	found_precision = 1;

      if (gfc_real_kinds[i].range >= range)
	found_range = 1;

      if (radix == 0 || gfc_real_kinds[i].radix == radix)
	found_radix = 1;

      if (gfc_real_kinds[i].precision >= precision
	  && gfc_real_kinds[i].range >= range
	  && (radix == 0 || gfc_real_kinds[i].radix == radix)
	  && gfc_real_kinds[i].kind < kind)
	kind = gfc_real_kinds[i].kind;
    }

  if (kind == INT_MAX)
    {
      if (found_radix && found_range && !found_precision)
	kind = -1;
      else if (found_radix && found_precision && !found_range)
	kind = -2;
      else if (found_radix && !found_precision && !found_range)
	kind = -3;
      else if (found_radix)
	kind = -4;
      else
	kind = -5;
    }

  return gfc_get_int_expr (gfc_default_integer_kind, loc, kind);
}


gfc_expr *
gfc_simplify_set_exponent (gfc_expr *x, gfc_expr *i)
{
  gfc_expr *result;
  mpfr_t exp, absv, log2, pow2, frac;
  unsigned long exp2;

  if (x->expr_type != EXPR_CONSTANT || i->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

  /* SET_EXPONENT (+/-0.0, I) = +/- 0.0
     SET_EXPONENT (NaN) = same NaN  */
  if (mpfr_zero_p (x->value.real) || mpfr_nan_p (x->value.real))
    {
      mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
      return result;
    }

  /* SET_EXPONENT (inf) = NaN  */
  if (mpfr_inf_p (x->value.real))
    {
      mpfr_set_nan (result->value.real);
      return result;
    }

  gfc_set_model_kind (x->ts.kind);
  mpfr_init (absv);
  mpfr_init (log2);
  mpfr_init (exp);
  mpfr_init (pow2);
  mpfr_init (frac);

  mpfr_abs (absv, x->value.real, GFC_RND_MODE);
  mpfr_log2 (log2, absv, GFC_RND_MODE);

  mpfr_trunc (log2, log2);
  mpfr_add_ui (exp, log2, 1, GFC_RND_MODE);

  /* Old exponent value, and fraction.  */
  mpfr_ui_pow (pow2, 2, exp, GFC_RND_MODE);

  mpfr_div (frac, absv, pow2, GFC_RND_MODE);

  /* New exponent.  */
  exp2 = (unsigned long) mpz_get_d (i->value.integer);
  mpfr_mul_2exp (result->value.real, frac, exp2, GFC_RND_MODE);

  mpfr_clears (absv, log2, pow2, frac, NULL);

  return range_check (result, "SET_EXPONENT");
}


gfc_expr *
gfc_simplify_shape (gfc_expr *source, gfc_expr *kind)
{
  mpz_t shape[GFC_MAX_DIMENSIONS];
  gfc_expr *result, *e, *f;
  gfc_array_ref *ar;
  int n;
  bool t;
  int k = get_kind (BT_INTEGER, kind, "SHAPE", gfc_default_integer_kind);

  if (source->rank == -1)
    return NULL;

  result = gfc_get_array_expr (BT_INTEGER, k, &source->where);
  result->shape = gfc_get_shape (1);
  mpz_init (result->shape[0]);

  if (source->rank == 0)
    return result;

  if (source->expr_type == EXPR_VARIABLE)
    {
      ar = gfc_find_array_ref (source);
      t = gfc_array_ref_shape (ar, shape);
    }
  else if (source->shape)
    {
      t = true;
      for (n = 0; n < source->rank; n++)
	{
	  mpz_init (shape[n]);
	  mpz_set (shape[n], source->shape[n]);
	}
    }
  else
    t = false;

  for (n = 0; n < source->rank; n++)
    {
      e = gfc_get_constant_expr (BT_INTEGER, k, &source->where);

      if (t)
	mpz_set (e->value.integer, shape[n]);
      else
	{
	  mpz_set_ui (e->value.integer, n + 1);

	  f = simplify_size (source, e, k);
	  gfc_free_expr (e);
	  if (f == NULL)
	    {
	      gfc_free_expr (result);
	      return NULL;
	    }
	  else
	    e = f;
	}

      if (e == &gfc_bad_expr || range_check (e, "SHAPE") == &gfc_bad_expr)
	{
	  gfc_free_expr (result);
	  if (t)
	    gfc_clear_shape (shape, source->rank);
	  return &gfc_bad_expr;
	}

      gfc_constructor_append_expr (&result->value.constructor, e, NULL);
    }

  if (t)
    gfc_clear_shape (shape, source->rank);

  mpz_set_si (result->shape[0], source->rank);

  return result;
}


static gfc_expr *
simplify_size (gfc_expr *array, gfc_expr *dim, int k)
{
  mpz_t size;
  gfc_expr *return_value;
  int d;

  /* For unary operations, the size of the result is given by the size
     of the operand.  For binary ones, it's the size of the first operand
     unless it is scalar, then it is the size of the second.  */
  if (array->expr_type == EXPR_OP && !array->value.op.uop)
    {
      gfc_expr* replacement;
      gfc_expr* simplified;

      switch (array->value.op.op)
	{
	  /* Unary operations.  */
	  case INTRINSIC_NOT:
	  case INTRINSIC_UPLUS:
	  case INTRINSIC_UMINUS:
	  case INTRINSIC_PARENTHESES:
	    replacement = array->value.op.op1;
	    break;

	  /* Binary operations.  If any one of the operands is scalar, take
	     the other one's size.  If both of them are arrays, it does not
	     matter -- try to find one with known shape, if possible.  */
	  default:
	    if (array->value.op.op1->rank == 0)
	      replacement = array->value.op.op2;
	    else if (array->value.op.op2->rank == 0)
	      replacement = array->value.op.op1;
	    else
	      {
		simplified = simplify_size (array->value.op.op1, dim, k);
		if (simplified)
		  return simplified;

		replacement = array->value.op.op2;
	      }
	    break;
	}

      /* Try to reduce it directly if possible.  */
      simplified = simplify_size (replacement, dim, k);

      /* Otherwise, we build a new SIZE call.  This is hopefully at least
	 simpler than the original one.  */
      if (!simplified)
	{
	  gfc_expr *kind = gfc_get_int_expr (gfc_default_integer_kind, NULL, k);
	  simplified = gfc_build_intrinsic_call (gfc_current_ns,
						 GFC_ISYM_SIZE, "size",
						 array->where, 3,
						 gfc_copy_expr (replacement),
						 gfc_copy_expr (dim),
						 kind);
	}
      return simplified;
    }

  if (dim == NULL)
    {
      if (!gfc_array_size (array, &size))
	return NULL;
    }
  else
    {
      if (dim->expr_type != EXPR_CONSTANT)
	return NULL;

      d = mpz_get_ui (dim->value.integer) - 1;
      if (!gfc_array_dimen_size (array, d, &size))
	return NULL;
    }

  return_value = gfc_get_constant_expr (BT_INTEGER, k, &array->where);
  mpz_set (return_value->value.integer, size);
  mpz_clear (size);

  return return_value;
}


gfc_expr *
gfc_simplify_size (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  gfc_expr *result;
  int k = get_kind (BT_INTEGER, kind, "SIZE", gfc_default_integer_kind);

  if (k == -1)
    return &gfc_bad_expr;

  result = simplify_size (array, dim, k);
  if (result == NULL || result == &gfc_bad_expr)
    return result;

  return range_check (result, "SIZE");
}


/* SIZEOF and C_SIZEOF return the size in bytes of an array element
   multiplied by the array size.  */

gfc_expr *
gfc_simplify_sizeof (gfc_expr *x)
{
  gfc_expr *result = NULL;
  mpz_t array_size;
  size_t res_size;

  if (x->ts.type == BT_CLASS || x->ts.deferred)
    return NULL;

  if (x->ts.type == BT_CHARACTER
      && (!x->ts.u.cl || !x->ts.u.cl->length
	  || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
    return NULL;

  if (x->rank && x->expr_type != EXPR_ARRAY
      && !gfc_array_size (x, &array_size))
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, gfc_index_integer_kind,
				  &x->where);
  gfc_target_expr_size (x, &res_size);
  mpz_set_si (result->value.integer, res_size);

  return result;
}


/* STORAGE_SIZE returns the size in bits of a single array element.  */

gfc_expr *
gfc_simplify_storage_size (gfc_expr *x,
			   gfc_expr *kind)
{
  gfc_expr *result = NULL;
  int k;
  size_t siz;

  if (x->ts.type == BT_CLASS || x->ts.deferred)
    return NULL;

  if (x->ts.type == BT_CHARACTER && x->expr_type != EXPR_CONSTANT
      && (!x->ts.u.cl || !x->ts.u.cl->length
	  || x->ts.u.cl->length->expr_type != EXPR_CONSTANT))
    return NULL;

  k = get_kind (BT_INTEGER, kind, "STORAGE_SIZE", gfc_default_integer_kind);
  if (k == -1)
    return &gfc_bad_expr;

  result = gfc_get_constant_expr (BT_INTEGER, k, &x->where);

  gfc_element_size (x, &siz);
  mpz_set_si (result->value.integer, siz);
  mpz_mul_ui (result->value.integer, result->value.integer, BITS_PER_UNIT);

  return range_check (result, "STORAGE_SIZE");
}


gfc_expr *
gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_INTEGER:
	mpz_abs (result->value.integer, x->value.integer);
	if (mpz_sgn (y->value.integer) < 0)
	  mpz_neg (result->value.integer, result->value.integer);
	break;

      case BT_REAL:
	if (flag_sign_zero)
	  mpfr_copysign (result->value.real, x->value.real, y->value.real,
			GFC_RND_MODE);
	else
	  mpfr_setsign (result->value.real, x->value.real,
			mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
	break;

      default:
	gfc_internal_error ("Bad type in gfc_simplify_sign");
    }

  return result;
}


gfc_expr *
gfc_simplify_sin (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_sin (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	gfc_set_model (x->value.real);
	mpc_sin (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("in gfc_simplify_sin(): Bad type");
    }

  return range_check (result, "SIN");
}


gfc_expr *
gfc_simplify_sinh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_sinh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_sinh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gcc_unreachable ();
    }

  return range_check (result, "SINH");
}


/* The argument is always a double precision real that is converted to
   single precision.  TODO: Rounding!  */

gfc_expr *
gfc_simplify_sngl (gfc_expr *a)
{
  gfc_expr *result;
  int tmp1, tmp2;

  if (a->expr_type != EXPR_CONSTANT)
    return NULL;

  /* For explicit conversion, turn off -Wconversion and -Wconversion-extra
     warnings.  */
  tmp1 = warn_conversion;
  tmp2 = warn_conversion_extra;
  warn_conversion = warn_conversion_extra = 0;

  result = gfc_real2real (a, gfc_default_real_kind);

  warn_conversion = tmp1;
  warn_conversion_extra = tmp2;

  return range_check (result, "SNGL");
}


gfc_expr *
gfc_simplify_spacing (gfc_expr *x)
{
  gfc_expr *result;
  int i;
  long int en, ep;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  i = gfc_validate_kind (x->ts.type, x->ts.kind, false);
  result = gfc_get_constant_expr (BT_REAL, x->ts.kind, &x->where);

  /* SPACING(+/- 0.0) = SPACING(TINY(0.0)) = TINY(0.0)  */
  if (mpfr_zero_p (x->value.real))
    {
      mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);
      return result;
    }

  /* SPACING(inf) = NaN  */
  if (mpfr_inf_p (x->value.real))
    {
      mpfr_set_nan (result->value.real);
      return result;
    }

  /* SPACING(NaN) = same NaN  */
  if (mpfr_nan_p (x->value.real))
    {
      mpfr_set (result->value.real, x->value.real, GFC_RND_MODE);
      return result;
    }

  /* In the Fortran 95 standard, the result is b**(e - p) where b, e, and p
     are the radix, exponent of x, and precision.  This excludes the
     possibility of subnormal numbers.  Fortran 2003 states the result is
     b**max(e - p, emin - 1).  */

  ep = (long int) mpfr_get_exp (x->value.real) - gfc_real_kinds[i].digits;
  en = (long int) gfc_real_kinds[i].min_exponent - 1;
  en = en > ep ? en : ep;

  mpfr_set_ui (result->value.real, 1, GFC_RND_MODE);
  mpfr_mul_2si (result->value.real, result->value.real, en, GFC_RND_MODE);

  return range_check (result, "SPACING");
}


gfc_expr *
gfc_simplify_spread (gfc_expr *source, gfc_expr *dim_expr, gfc_expr *ncopies_expr)
{
  gfc_expr *result = NULL;
  int nelem, i, j, dim, ncopies;
  mpz_t size;

  if ((!gfc_is_constant_expr (source)
       && !is_constant_array_expr (source))
      || !gfc_is_constant_expr (dim_expr)
      || !gfc_is_constant_expr (ncopies_expr))
    return NULL;

  gcc_assert (dim_expr->ts.type == BT_INTEGER);
  gfc_extract_int (dim_expr, &dim);
  dim -= 1;   /* zero-base DIM */

  gcc_assert (ncopies_expr->ts.type == BT_INTEGER);
  gfc_extract_int (ncopies_expr, &ncopies);
  ncopies = MAX (ncopies, 0);

  /* Do not allow the array size to exceed the limit for an array
     constructor.  */
  if (source->expr_type == EXPR_ARRAY)
    {
      if (!gfc_array_size (source, &size))
	gfc_internal_error ("Failure getting length of a constant array.");
    }
  else
    mpz_init_set_ui (size, 1);

  nelem = mpz_get_si (size) * ncopies;
  if (nelem > flag_max_array_constructor)
    {
      if (gfc_init_expr_flag)
	{
	  gfc_error ("The number of elements (%d) in the array constructor "
		     "at %L requires an increase of the allowed %d upper "
		     "limit.  See %<-fmax-array-constructor%> option.",
		     nelem, &source->where, flag_max_array_constructor);
	  return &gfc_bad_expr;
	}
      else
	return NULL;
    }

  if (source->expr_type == EXPR_CONSTANT
      || source->expr_type == EXPR_STRUCTURE)
    {
      gcc_assert (dim == 0);

      result = gfc_get_array_expr (source->ts.type, source->ts.kind,
				   &source->where);
      if (source->ts.type == BT_DERIVED)
	result->ts.u.derived = source->ts.u.derived;
      result->rank = 1;
      result->shape = gfc_get_shape (result->rank);
      mpz_init_set_si (result->shape[0], ncopies);

      for (i = 0; i < ncopies; ++i)
        gfc_constructor_append_expr (&result->value.constructor,
				     gfc_copy_expr (source), NULL);
    }
  else if (source->expr_type == EXPR_ARRAY)
    {
      int offset, rstride[GFC_MAX_DIMENSIONS], extent[GFC_MAX_DIMENSIONS];
      gfc_constructor *source_ctor;

      gcc_assert (source->rank < GFC_MAX_DIMENSIONS);
      gcc_assert (dim >= 0 && dim <= source->rank);

      result = gfc_get_array_expr (source->ts.type, source->ts.kind,
				   &source->where);
      if (source->ts.type == BT_DERIVED)
	result->ts.u.derived = source->ts.u.derived;
      result->rank = source->rank + 1;
      result->shape = gfc_get_shape (result->rank);

      for (i = 0, j = 0; i < result->rank; ++i)
	{
	  if (i != dim)
	    mpz_init_set (result->shape[i], source->shape[j++]);
	  else
	    mpz_init_set_si (result->shape[i], ncopies);

	  extent[i] = mpz_get_si (result->shape[i]);
	  rstride[i] = (i == 0) ? 1 : rstride[i-1] * extent[i-1];
	}

      offset = 0;
      for (source_ctor = gfc_constructor_first (source->value.constructor);
           source_ctor; source_ctor = gfc_constructor_next (source_ctor))
	{
	  for (i = 0; i < ncopies; ++i)
	    gfc_constructor_insert_expr (&result->value.constructor,
					 gfc_copy_expr (source_ctor->expr),
					 NULL, offset + i * rstride[dim]);

	  offset += (dim == 0 ? ncopies : 1);
	}
    }
  else
    {
      gfc_error ("Simplification of SPREAD at %C not yet implemented");
      return &gfc_bad_expr;
    }

  if (source->ts.type == BT_CHARACTER)
    result->ts.u.cl = source->ts.u.cl;

  return result;
}


gfc_expr *
gfc_simplify_sqrt (gfc_expr *e)
{
  gfc_expr *result = NULL;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  switch (e->ts.type)
    {
      case BT_REAL:
	if (mpfr_cmp_si (e->value.real, 0) < 0)
	  {
	    gfc_error ("Argument of SQRT at %L has a negative value",
		       &e->where);
	    return &gfc_bad_expr;
	  }
	result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
	mpfr_sqrt (result->value.real, e->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	gfc_set_model (e->value.real);

	result = gfc_get_constant_expr (e->ts.type, e->ts.kind, &e->where);
	mpc_sqrt (result->value.complex, e->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gfc_internal_error ("invalid argument of SQRT at %L", &e->where);
    }

  return range_check (result, "SQRT");
}


gfc_expr *
gfc_simplify_sum (gfc_expr *array, gfc_expr *dim, gfc_expr *mask)
{
  return simplify_transformation (array, dim, mask, 0, gfc_add);
}


/* Simplify COTAN(X) where X has the unit of radian.  */

gfc_expr *
gfc_simplify_cotan (gfc_expr *x)
{
  gfc_expr *result;
  mpc_t swp, *val;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
    case BT_REAL:
      mpfr_cot (result->value.real, x->value.real, GFC_RND_MODE);
      break;

    case BT_COMPLEX:
      /* There is no builtin mpc_cot, so compute cot = cos / sin.  */
      val = &result->value.complex;
      mpc_init2 (swp, mpfr_get_default_prec ());
      mpc_sin_cos (*val, swp, x->value.complex, GFC_MPC_RND_MODE,
		   GFC_MPC_RND_MODE);
      mpc_div (*val, swp, *val, GFC_MPC_RND_MODE);
      mpc_clear (swp);
      break;

    default:
      gcc_unreachable ();
    }

  return range_check (result, "COTAN");
}


gfc_expr *
gfc_simplify_tan (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_tan (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_tan (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gcc_unreachable ();
    }

  return range_check (result, "TAN");
}


gfc_expr *
gfc_simplify_tanh (gfc_expr *x)
{
  gfc_expr *result;

  if (x->expr_type != EXPR_CONSTANT)
    return NULL;

  result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);

  switch (x->ts.type)
    {
      case BT_REAL:
	mpfr_tanh (result->value.real, x->value.real, GFC_RND_MODE);
	break;

      case BT_COMPLEX:
	mpc_tanh (result->value.complex, x->value.complex, GFC_MPC_RND_MODE);
	break;

      default:
	gcc_unreachable ();
    }

  return range_check (result, "TANH");
}


gfc_expr *
gfc_simplify_tiny (gfc_expr *e)
{
  gfc_expr *result;
  int i;

  i = gfc_validate_kind (BT_REAL, e->ts.kind, false);

  result = gfc_get_constant_expr (BT_REAL, e->ts.kind, &e->where);
  mpfr_set (result->value.real, gfc_real_kinds[i].tiny, GFC_RND_MODE);

  return result;
}


gfc_expr *
gfc_simplify_trailz (gfc_expr *e)
{
  unsigned long tz, bs;
  int i;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  i = gfc_validate_kind (e->ts.type, e->ts.kind, false);
  bs = gfc_integer_kinds[i].bit_size;
  tz = mpz_scan1 (e->value.integer, 0);

  return gfc_get_int_expr (gfc_default_integer_kind,
			   &e->where, MIN (tz, bs));
}


gfc_expr *
gfc_simplify_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
{
  gfc_expr *result;
  gfc_expr *mold_element;
  size_t source_size;
  size_t result_size;
  size_t buffer_size;
  mpz_t tmp;
  unsigned char *buffer;
  size_t result_length;

  if (!gfc_is_constant_expr (source) || !gfc_is_constant_expr (size))
    return NULL;

  if (!gfc_resolve_expr (mold))
    return NULL;
  if (gfc_init_expr_flag && !gfc_is_constant_expr (mold))
    return NULL;

  if (!gfc_calculate_transfer_sizes (source, mold, size, &source_size,
				     &result_size, &result_length))
    return NULL;

  /* Calculate the size of the source.  */
  if (source->expr_type == EXPR_ARRAY && !gfc_array_size (source, &tmp))
    gfc_internal_error ("Failure getting length of a constant array.");

  /* Create an empty new expression with the appropriate characteristics.  */
  result = gfc_get_constant_expr (mold->ts.type, mold->ts.kind,
				  &source->where);
  result->ts = mold->ts;

  mold_element = (mold->expr_type == EXPR_ARRAY && mold->value.constructor)
		 ? gfc_constructor_first (mold->value.constructor)->expr
		 : mold;

  /* Set result character length, if needed.  Note that this needs to be
     set even for array expressions, in order to pass this information into
     gfc_target_interpret_expr.  */
  if (result->ts.type == BT_CHARACTER && gfc_is_constant_expr (mold_element))
    result->value.character.length = mold_element->value.character.length;

  /* Set the number of elements in the result, and determine its size.  */

  if (mold->expr_type == EXPR_ARRAY || mold->rank || size)
    {
      result->expr_type = EXPR_ARRAY;
      result->rank = 1;
      result->shape = gfc_get_shape (1);
      mpz_init_set_ui (result->shape[0], result_length);
    }
  else
    result->rank = 0;

  /* Allocate the buffer to store the binary version of the source.  */
  buffer_size = MAX (source_size, result_size);
  buffer = (unsigned char*)alloca (buffer_size);
  memset (buffer, 0, buffer_size);

  /* Now write source to the buffer.  */
  gfc_target_encode_expr (source, buffer, buffer_size);

  /* And read the buffer back into the new expression.  */
  gfc_target_interpret_expr (buffer, buffer_size, result, false);

  return result;
}


gfc_expr *
gfc_simplify_transpose (gfc_expr *matrix)
{
  int row, matrix_rows, col, matrix_cols;
  gfc_expr *result;

  if (!is_constant_array_expr (matrix))
    return NULL;

  gcc_assert (matrix->rank == 2);

  result = gfc_get_array_expr (matrix->ts.type, matrix->ts.kind,
			       &matrix->where);
  result->rank = 2;
  result->shape = gfc_get_shape (result->rank);
  mpz_init_set (result->shape[0], matrix->shape[1]);
  mpz_init_set (result->shape[1], matrix->shape[0]);

  if (matrix->ts.type == BT_CHARACTER)
    result->ts.u.cl = matrix->ts.u.cl;
  else if (matrix->ts.type == BT_DERIVED)
    result->ts.u.derived = matrix->ts.u.derived;

  matrix_rows = mpz_get_si (matrix->shape[0]);
  matrix_cols = mpz_get_si (matrix->shape[1]);
  for (row = 0; row < matrix_rows; ++row)
    for (col = 0; col < matrix_cols; ++col)
      {
	gfc_expr *e = gfc_constructor_lookup_expr (matrix->value.constructor,
						   col * matrix_rows + row);
	gfc_constructor_insert_expr (&result->value.constructor,
				     gfc_copy_expr (e), &matrix->where,
				     row * matrix_cols + col);
      }

  return result;
}


gfc_expr *
gfc_simplify_trim (gfc_expr *e)
{
  gfc_expr *result;
  int count, i, len, lentrim;

  if (e->expr_type != EXPR_CONSTANT)
    return NULL;

  len = e->value.character.length;
  for (count = 0, i = 1; i <= len; ++i)
    {
      if (e->value.character.string[len - i] == ' ')
	count++;
      else
	break;
    }

  lentrim = len - count;

  result = gfc_get_character_expr (e->ts.kind, &e->where, NULL, lentrim);
  for (i = 0; i < lentrim; i++)
    result->value.character.string[i] = e->value.character.string[i];

  return result;
}


gfc_expr *
gfc_simplify_image_index (gfc_expr *coarray, gfc_expr *sub)
{
  gfc_expr *result;
  gfc_ref *ref;
  gfc_array_spec *as;
  gfc_constructor *sub_cons;
  bool first_image;
  int d;

  if (!is_constant_array_expr (sub))
    return NULL;

  /* Follow any component references.  */
  as = coarray->symtree->n.sym->as;
  for (ref = coarray->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT)
      as = ref->u.ar.as;

  if (as->type == AS_DEFERRED)
    return NULL;

  /* "valid sequence of cosubscripts" are required; thus, return 0 unless
     the cosubscript addresses the first image.  */

  sub_cons = gfc_constructor_first (sub->value.constructor);
  first_image = true;

  for (d = 1; d <= as->corank; d++)
    {
      gfc_expr *ca_bound;
      int cmp;

      gcc_assert (sub_cons != NULL);

      ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 0, as,
				     NULL, true);
      if (ca_bound == NULL)
	return NULL;

      if (ca_bound == &gfc_bad_expr)
	return ca_bound;

      cmp = mpz_cmp (ca_bound->value.integer, sub_cons->expr->value.integer);

      if (cmp == 0)
	{
          gfc_free_expr (ca_bound);
	  sub_cons = gfc_constructor_next (sub_cons);
	  continue;
	}

      first_image = false;

      if (cmp > 0)
	{
	  gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
		     "SUB has %ld and COARRAY lower bound is %ld)",
		     &coarray->where, d,
		     mpz_get_si (sub_cons->expr->value.integer),
		     mpz_get_si (ca_bound->value.integer));
	  gfc_free_expr (ca_bound);
	  return &gfc_bad_expr;
	}

      gfc_free_expr (ca_bound);

      /* Check whether upperbound is valid for the multi-images case.  */
      if (d < as->corank)
	{
	  ca_bound = simplify_bound_dim (coarray, NULL, d + as->rank, 1, as,
					 NULL, true);
	  if (ca_bound == &gfc_bad_expr)
	    return ca_bound;

	  if (ca_bound && ca_bound->expr_type == EXPR_CONSTANT
	      && mpz_cmp (ca_bound->value.integer,
			  sub_cons->expr->value.integer) < 0)
	  {
	    gfc_error ("Out of bounds in IMAGE_INDEX at %L for dimension %d, "
		       "SUB has %ld and COARRAY upper bound is %ld)",
		       &coarray->where, d,
		       mpz_get_si (sub_cons->expr->value.integer),
		       mpz_get_si (ca_bound->value.integer));
	    gfc_free_expr (ca_bound);
	    return &gfc_bad_expr;
	  }

	  if (ca_bound)
	    gfc_free_expr (ca_bound);
	}

      sub_cons = gfc_constructor_next (sub_cons);
    }

  gcc_assert (sub_cons == NULL);

  if (flag_coarray != GFC_FCOARRAY_SINGLE && !first_image)
    return NULL;

  result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				  &gfc_current_locus);
  if (first_image)
    mpz_set_si (result->value.integer, 1);
  else
    mpz_set_si (result->value.integer, 0);

  return result;
}

gfc_expr *
gfc_simplify_image_status (gfc_expr *image, gfc_expr *team ATTRIBUTE_UNUSED)
{
  if (flag_coarray == GFC_FCOARRAY_NONE)
    {
      gfc_current_locus = *gfc_current_intrinsic_where;
      gfc_fatal_error ("Coarrays disabled at %C, use %<-fcoarray=%> to enable");
      return &gfc_bad_expr;
    }

  /* Simplification is possible for fcoarray = single only.  For all other modes
     the result depends on runtime conditions.  */
  if (flag_coarray != GFC_FCOARRAY_SINGLE)
    return NULL;

  if (gfc_is_constant_expr (image))
    {
      gfc_expr *result;
      result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				      &image->where);
      if (mpz_get_si (image->value.integer) == 1)
	mpz_set_si (result->value.integer, 0);
      else
	mpz_set_si (result->value.integer, GFC_STAT_STOPPED_IMAGE);
      return result;
    }
  else
    return NULL;
}


gfc_expr *
gfc_simplify_this_image (gfc_expr *coarray, gfc_expr *dim,
			 gfc_expr *distance ATTRIBUTE_UNUSED)
{
  if (flag_coarray != GFC_FCOARRAY_SINGLE)
    return NULL;

  /* If no coarray argument has been passed or when the first argument
     is actually a distance argment.  */
  if (coarray == NULL || !gfc_is_coarray (coarray))
    {
      gfc_expr *result;
      /* FIXME: gfc_current_locus is wrong.  */
      result = gfc_get_constant_expr (BT_INTEGER, gfc_default_integer_kind,
				      &gfc_current_locus);
      mpz_set_si (result->value.integer, 1);
      return result;
    }

  /* For -fcoarray=single, this_image(A) is the same as lcobound(A).  */
  return simplify_cobound (coarray, dim, NULL, 0);
}


gfc_expr *
gfc_simplify_ubound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  return simplify_bound (array, dim, kind, 1);
}

gfc_expr *
gfc_simplify_ucobound (gfc_expr *array, gfc_expr *dim, gfc_expr *kind)
{
  return simplify_cobound (array, dim, kind, 1);
}


gfc_expr *
gfc_simplify_unpack (gfc_expr *vector, gfc_expr *mask, gfc_expr *field)
{
  gfc_expr *result, *e;
  gfc_constructor *vector_ctor, *mask_ctor, *field_ctor;

  if (!is_constant_array_expr (vector)
      || !is_constant_array_expr (mask)
      || (!gfc_is_constant_expr (field)
	  && !is_constant_array_expr (field)))
    return NULL;

  result = gfc_get_array_expr (vector->ts.type, vector->ts.kind,
			       &vector->where);
  if (vector->ts.type == BT_DERIVED)
    result->ts.u.derived = vector->ts.u.derived;
  result->rank = mask->rank;
  result->shape = gfc_copy_shape (mask->shape, mask->rank);

  if (vector->ts.type == BT_CHARACTER)
    result->ts.u.cl = vector->ts.u.cl;

  vector_ctor = gfc_constructor_first (vector->value.constructor);
  mask_ctor = gfc_constructor_first (mask->value.constructor);
  field_ctor
    = field->expr_type == EXPR_ARRAY
			    ? gfc_constructor_first (field->value.constructor)
			    : NULL;

  while (mask_ctor)
    {
      if (mask_ctor->expr->value.logical)
	{
	  gcc_assert (vector_ctor);
	  e = gfc_copy_expr (vector_ctor->expr);
	  vector_ctor = gfc_constructor_next (vector_ctor);
	}
      else if (field->expr_type == EXPR_ARRAY)
	e = gfc_copy_expr (field_ctor->expr);
      else
	e = gfc_copy_expr (field);

      gfc_constructor_append_expr (&result->value.constructor, e, NULL);

      mask_ctor = gfc_constructor_next (mask_ctor);
      field_ctor = gfc_constructor_next (field_ctor);
    }

  return result;
}


gfc_expr *
gfc_simplify_verify (gfc_expr *s, gfc_expr *set, gfc_expr *b, gfc_expr *kind)
{
  gfc_expr *result;
  int back;
  size_t index, len, lenset;
  size_t i;
  int k = get_kind (BT_INTEGER, kind, "VERIFY", gfc_default_integer_kind);

  if (k == -1)
    return &gfc_bad_expr;

  if (s->expr_type != EXPR_CONSTANT || set->expr_type != EXPR_CONSTANT
      || ( b != NULL && b->expr_type !=  EXPR_CONSTANT))
    return NULL;

  if (b != NULL && b->value.logical != 0)
    back = 1;
  else
    back = 0;

  result = gfc_get_constant_expr (BT_INTEGER, k, &s->where);

  len = s->value.character.length;
  lenset = set->value.character.length;

  if (len == 0)
    {
      mpz_set_ui (result->value.integer, 0);
      return result;
    }

  if (back == 0)
    {
      if (lenset == 0)
	{
	  mpz_set_ui (result->value.integer, 1);
	  return result;
	}

      index = wide_strspn (s->value.character.string,
			   set->value.character.string) + 1;
      if (index > len)
	index = 0;

    }
  else
    {
      if (lenset == 0)
	{
	  mpz_set_ui (result->value.integer, len);
	  return result;
	}
      for (index = len; index > 0; index --)
	{
	  for (i = 0; i < lenset; i++)
	    {
	      if (s->value.character.string[index - 1]
		  == set->value.character.string[i])
		break;
	    }
	  if (i == lenset)
	    break;
	}
    }

  mpz_set_ui (result->value.integer, index);
  return result;
}


gfc_expr *
gfc_simplify_xor (gfc_expr *x, gfc_expr *y)
{
  gfc_expr *result;
  int kind;

  if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
    return NULL;

  kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;

  switch (x->ts.type)
    {
      case BT_INTEGER:
	result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
	mpz_xor (result->value.integer, x->value.integer, y->value.integer);
	return range_check (result, "XOR");

      case BT_LOGICAL:
	return gfc_get_logical_expr (kind, &x->where,
				     (x->value.logical && !y->value.logical)
				     || (!x->value.logical && y->value.logical));

      default:
	gcc_unreachable ();
    }
}


/****************** Constant simplification *****************/

/* Master function to convert one constant to another.  While this is
   used as a simplification function, it requires the destination type
   and kind information which is supplied by a special case in
   do_simplify().  */

gfc_expr *
gfc_convert_constant (gfc_expr *e, bt type, int kind)
{
  gfc_expr *result, *(*f) (gfc_expr *, int);
  gfc_constructor *c, *t;

  switch (e->ts.type)
    {
    case BT_INTEGER:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_int2int;
	  break;
	case BT_REAL:
	  f = gfc_int2real;
	  break;
	case BT_COMPLEX:
	  f = gfc_int2complex;
	  break;
	case BT_LOGICAL:
	  f = gfc_int2log;
	  break;
	default:
	  goto oops;
	}
      break;

    case BT_REAL:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_real2int;
	  break;
	case BT_REAL:
	  f = gfc_real2real;
	  break;
	case BT_COMPLEX:
	  f = gfc_real2complex;
	  break;
	default:
	  goto oops;
	}
      break;

    case BT_COMPLEX:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_complex2int;
	  break;
	case BT_REAL:
	  f = gfc_complex2real;
	  break;
	case BT_COMPLEX:
	  f = gfc_complex2complex;
	  break;

	default:
	  goto oops;
	}
      break;

    case BT_LOGICAL:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_log2int;
	  break;
	case BT_LOGICAL:
	  f = gfc_log2log;
	  break;
	default:
	  goto oops;
	}
      break;

    case BT_HOLLERITH:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_hollerith2int;
	  break;

	case BT_REAL:
	  f = gfc_hollerith2real;
	  break;

	case BT_COMPLEX:
	  f = gfc_hollerith2complex;
	  break;

	case BT_CHARACTER:
	  f = gfc_hollerith2character;
	  break;

	case BT_LOGICAL:
	  f = gfc_hollerith2logical;
	  break;

	default:
	  goto oops;
	}
      break;

    case BT_CHARACTER:
      switch (type)
	{
	case BT_INTEGER:
	  f = gfc_character2int;
	  break;

	case BT_REAL:
	  f = gfc_character2real;
	  break;

	case BT_COMPLEX:
	  f = gfc_character2complex;
	  break;

	case BT_CHARACTER:
	  f = gfc_character2character;
	  break;

	case BT_LOGICAL:
	  f = gfc_character2logical;
	  break;

	default:
	  goto oops;
	}
      break;

    default:
    oops:
      return &gfc_bad_expr;
    }

  result = NULL;

  switch (e->expr_type)
    {
    case EXPR_CONSTANT:
      result = f (e, kind);
      if (result == NULL)
	return &gfc_bad_expr;
      break;

    case EXPR_ARRAY:
      if (!gfc_is_constant_expr (e))
	break;

      result = gfc_get_array_expr (type, kind, &e->where);
      result->shape = gfc_copy_shape (e->shape, e->rank);
      result->rank = e->rank;

      for (c = gfc_constructor_first (e->value.constructor);
	   c; c = gfc_constructor_next (c))
	{
	  gfc_expr *tmp;
	  if (c->iterator == NULL)
	    {
	      if (c->expr->expr_type == EXPR_ARRAY)
		tmp = gfc_convert_constant (c->expr, type, kind);
	      else if (c->expr->expr_type == EXPR_OP)
		{
		  if (!gfc_simplify_expr (c->expr, 1))
		    return &gfc_bad_expr;
		  tmp = f (c->expr, kind);
		}
	      else
		tmp = f (c->expr, kind);
	    }
	  else
	    tmp = gfc_convert_constant (c->expr, type, kind);

	  if (tmp == NULL || tmp == &gfc_bad_expr)
	    {
	      gfc_free_expr (result);
	      return NULL;
	    }

	  t = gfc_constructor_append_expr (&result->value.constructor,
					   tmp, &c->where);
	  if (c->iterator)
	    t->iterator = gfc_copy_iterator (c->iterator);
	}

      break;

    default:
      break;
    }

  return result;
}


/* Function for converting character constants.  */
gfc_expr *
gfc_convert_char_constant (gfc_expr *e, bt type ATTRIBUTE_UNUSED, int kind)
{
  gfc_expr *result;
  int i;

  if (!gfc_is_constant_expr (e))
    return NULL;

  if (e->expr_type == EXPR_CONSTANT)
    {
      /* Simple case of a scalar.  */
      result = gfc_get_constant_expr (BT_CHARACTER, kind, &e->where);
      if (result == NULL)
	return &gfc_bad_expr;

      result->value.character.length = e->value.character.length;
      result->value.character.string
	= gfc_get_wide_string (e->value.character.length + 1);
      memcpy (result->value.character.string, e->value.character.string,
	      (e->value.character.length + 1) * sizeof (gfc_char_t));

      /* Check we only have values representable in the destination kind.  */
      for (i = 0; i < result->value.character.length; i++)
	if (!gfc_check_character_range (result->value.character.string[i],
					kind))
	  {
	    gfc_error ("Character %qs in string at %L cannot be converted "
		       "into character kind %d",
		       gfc_print_wide_char (result->value.character.string[i]),
		       &e->where, kind);
	    gfc_free_expr (result);
	    return &gfc_bad_expr;
	  }

      return result;
    }
  else if (e->expr_type == EXPR_ARRAY)
    {
      /* For an array constructor, we convert each constructor element.  */
      gfc_constructor *c;

      result = gfc_get_array_expr (type, kind, &e->where);
      result->shape = gfc_copy_shape (e->shape, e->rank);
      result->rank = e->rank;
      result->ts.u.cl = e->ts.u.cl;

      for (c = gfc_constructor_first (e->value.constructor);
	   c; c = gfc_constructor_next (c))
	{
	  gfc_expr *tmp = gfc_convert_char_constant (c->expr, type, kind);
	  if (tmp == &gfc_bad_expr)
	    {
	      gfc_free_expr (result);
	      return &gfc_bad_expr;
	    }

	  if (tmp == NULL)
	    {
	      gfc_free_expr (result);
	      return NULL;
	    }

	  gfc_constructor_append_expr (&result->value.constructor,
				       tmp, &c->where);
	}

      return result;
    }
  else
    return NULL;
}


gfc_expr *
gfc_simplify_compiler_options (void)
{
  char *str;
  gfc_expr *result;

  str = gfc_get_option_string ();
  result = gfc_get_character_expr (gfc_default_character_kind,
				   &gfc_current_locus, str, strlen (str));
  free (str);
  return result;
}


gfc_expr *
gfc_simplify_compiler_version (void)
{
  char *buffer;
  size_t len;

  len = strlen ("GCC version ") + strlen (version_string);
  buffer = XALLOCAVEC (char, len + 1);
  snprintf (buffer, len + 1, "GCC version %s", version_string);
  return gfc_get_character_expr (gfc_default_character_kind,
                                &gfc_current_locus, buffer, len);
}

/* Simplification routines for intrinsics of IEEE modules.  */

gfc_expr *
simplify_ieee_selected_real_kind (gfc_expr *expr)
{
  gfc_actual_arglist *arg;
  gfc_expr *p = NULL, *q = NULL, *rdx = NULL;

  arg = expr->value.function.actual;
  p = arg->expr;
  if (arg->next)
    {
      q = arg->next->expr;
      if (arg->next->next)
	rdx = arg->next->next->expr;
    }

  /* Currently, if IEEE is supported and this module is built, it means
     all our floating-point types conform to IEEE. Hence, we simply handle
     IEEE_SELECTED_REAL_KIND like SELECTED_REAL_KIND.  */
  return gfc_simplify_selected_real_kind (p, q, rdx);
}

gfc_expr *
simplify_ieee_support (gfc_expr *expr)
{
  /* We consider that if the IEEE modules are loaded, we have full support
     for flags, halting and rounding, which are the three functions
     (IEEE_SUPPORT_{FLAG,HALTING,ROUNDING}) allowed in constant
     expressions. One day, we will need libgfortran to detect support and
     communicate it back to us, allowing for partial support.  */

  return gfc_get_logical_expr (gfc_default_logical_kind, &expr->where,
			       true);
}

bool
matches_ieee_function_name (gfc_symbol *sym, const char *name)
{
  int n = strlen(name);

  if (!strncmp(sym->name, name, n))
    return true;

  /* If a generic was used and renamed, we need more work to find out.
     Compare the specific name.  */
  if (sym->generic && !strncmp(sym->generic->sym->name, name, n))
    return true;

  return false;
}

gfc_expr *
gfc_simplify_ieee_functions (gfc_expr *expr)
{
  gfc_symbol* sym = expr->symtree->n.sym;

  if (matches_ieee_function_name(sym, "ieee_selected_real_kind"))
    return simplify_ieee_selected_real_kind (expr);
  else if (matches_ieee_function_name(sym, "ieee_support_flag")
	   || matches_ieee_function_name(sym, "ieee_support_halting")
	   || matches_ieee_function_name(sym, "ieee_support_rounding"))
    return simplify_ieee_support (expr);
  else
    return NULL;
}
