/* Intrinsic translation
   Copyright (C) 2002-2019 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>
   and Steven Bosscher <s.bosscher@student.tudelft.nl>

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/>.  */

/* trans-intrinsic.c-- generate GENERIC trees for calls to intrinsics.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "memmodel.h"
#include "tm.h"		/* For UNITS_PER_WORD.  */
#include "tree.h"
#include "gfortran.h"
#include "trans.h"
#include "stringpool.h"
#include "fold-const.h"
#include "internal-fn.h"
#include "tree-nested.h"
#include "stor-layout.h"
#include "toplev.h"	/* For rest_of_decl_compilation.  */
#include "arith.h"
#include "trans-const.h"
#include "trans-types.h"
#include "trans-array.h"
#include "dependency.h"	/* For CAF array alias analysis.  */
/* Only for gfc_trans_assign and gfc_trans_pointer_assign.  */

/* This maps Fortran intrinsic math functions to external library or GCC
   builtin functions.  */
typedef struct GTY(()) gfc_intrinsic_map_t {
  /* The explicit enum is required to work around inadequacies in the
     garbage collection/gengtype parsing mechanism.  */
  enum gfc_isym_id id;

  /* Enum value from the "language-independent", aka C-centric, part
     of gcc, or END_BUILTINS of no such value set.  */
  enum built_in_function float_built_in;
  enum built_in_function double_built_in;
  enum built_in_function long_double_built_in;
  enum built_in_function complex_float_built_in;
  enum built_in_function complex_double_built_in;
  enum built_in_function complex_long_double_built_in;

  /* True if the naming pattern is to prepend "c" for complex and
     append "f" for kind=4.  False if the naming pattern is to
     prepend "_gfortran_" and append "[rc](4|8|10|16)".  */
  bool libm_name;

  /* True if a complex version of the function exists.  */
  bool complex_available;

  /* True if the function should be marked const.  */
  bool is_constant;

  /* The base library name of this function.  */
  const char *name;

  /* Cache decls created for the various operand types.  */
  tree real4_decl;
  tree real8_decl;
  tree real10_decl;
  tree real16_decl;
  tree complex4_decl;
  tree complex8_decl;
  tree complex10_decl;
  tree complex16_decl;
}
gfc_intrinsic_map_t;

/* ??? The NARGS==1 hack here is based on the fact that (c99 at least)
   defines complex variants of all of the entries in mathbuiltins.def
   except for atan2.  */
#define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE) \
  { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
    BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
    true, false, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, \
    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},

#define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE) \
  { GFC_ISYM_ ## ID, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
    BUILT_IN_ ## ID ## L, BUILT_IN_C ## ID ## F, BUILT_IN_C ## ID, \
    BUILT_IN_C ## ID ## L, true, true, true, NAME, NULL_TREE, NULL_TREE, \
    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},

#define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX) \
  { GFC_ISYM_ ## ID, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
    END_BUILTINS, END_BUILTINS, END_BUILTINS, \
    false, HAVE_COMPLEX, true, NAME, NULL_TREE, NULL_TREE, NULL_TREE, \
    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE }

#define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
  { GFC_ISYM_NONE, BUILT_IN_ ## ID ## F, BUILT_IN_ ## ID, \
    BUILT_IN_ ## ID ## L, END_BUILTINS, END_BUILTINS, END_BUILTINS, \
    true, false, CONST, NAME, NULL_TREE, NULL_TREE, \
    NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE},

static GTY(()) gfc_intrinsic_map_t gfc_intrinsic_map[] =
{
  /* Functions built into gcc itself (DEFINE_MATH_BUILTIN and
     DEFINE_MATH_BUILTIN_C), then the built-ins that don't correspond
     to any GFC_ISYM id directly, which use the OTHER_BUILTIN macro.  */
#include "mathbuiltins.def"

  /* Functions in libgfortran.  */
  LIB_FUNCTION (ERFC_SCALED, "erfc_scaled", false),

  /* End the list.  */
  LIB_FUNCTION (NONE, NULL, false)

};
#undef OTHER_BUILTIN
#undef LIB_FUNCTION
#undef DEFINE_MATH_BUILTIN
#undef DEFINE_MATH_BUILTIN_C


enum rounding_mode { RND_ROUND, RND_TRUNC, RND_CEIL, RND_FLOOR };


/* Find the correct variant of a given builtin from its argument.  */
static tree
builtin_decl_for_precision (enum built_in_function base_built_in,
			    int precision)
{
  enum built_in_function i = END_BUILTINS;

  gfc_intrinsic_map_t *m;
  for (m = gfc_intrinsic_map; m->double_built_in != base_built_in ; m++)
    ;

  if (precision == TYPE_PRECISION (float_type_node))
    i = m->float_built_in;
  else if (precision == TYPE_PRECISION (double_type_node))
    i = m->double_built_in;
  else if (precision == TYPE_PRECISION (long_double_type_node))
    i = m->long_double_built_in;
  else if (precision == TYPE_PRECISION (gfc_float128_type_node))
    {
      /* Special treatment, because it is not exactly a built-in, but
	 a library function.  */
      return m->real16_decl;
    }

  return (i == END_BUILTINS ? NULL_TREE : builtin_decl_explicit (i));
}


tree
gfc_builtin_decl_for_float_kind (enum built_in_function double_built_in,
				 int kind)
{
  int i = gfc_validate_kind (BT_REAL, kind, false);

  if (gfc_real_kinds[i].c_float128)
    {
      /* For __float128, the story is a bit different, because we return
	 a decl to a library function rather than a built-in.  */
      gfc_intrinsic_map_t *m;
      for (m = gfc_intrinsic_map; m->double_built_in != double_built_in ; m++)
	;

      return m->real16_decl;
    }

  return builtin_decl_for_precision (double_built_in,
				     gfc_real_kinds[i].mode_precision);
}


/* Evaluate the arguments to an intrinsic function.  The value
   of NARGS may be less than the actual number of arguments in EXPR
   to allow optional "KIND" arguments that are not included in the
   generated code to be ignored.  */

static void
gfc_conv_intrinsic_function_args (gfc_se *se, gfc_expr *expr,
				  tree *argarray, int nargs)
{
  gfc_actual_arglist *actual;
  gfc_expr *e;
  gfc_intrinsic_arg  *formal;
  gfc_se argse;
  int curr_arg;

  formal = expr->value.function.isym->formal;
  actual = expr->value.function.actual;

   for (curr_arg = 0; curr_arg < nargs; curr_arg++,
	actual = actual->next,
	formal = formal ? formal->next : NULL)
    {
      gcc_assert (actual);
      e = actual->expr;
      /* Skip omitted optional arguments.  */
      if (!e)
	{
	  --curr_arg;
	  continue;
	}

      /* Evaluate the parameter.  This will substitute scalarized
         references automatically.  */
      gfc_init_se (&argse, se);

      if (e->ts.type == BT_CHARACTER)
	{
	  gfc_conv_expr (&argse, e);
	  gfc_conv_string_parameter (&argse);
          argarray[curr_arg++] = argse.string_length;
	  gcc_assert (curr_arg < nargs);
	}
      else
        gfc_conv_expr_val (&argse, e);

      /* If an optional argument is itself an optional dummy argument,
	 check its presence and substitute a null if absent.  */
      if (e->expr_type == EXPR_VARIABLE
	    && e->symtree->n.sym->attr.optional
	    && formal
	    && formal->optional)
	gfc_conv_missing_dummy (&argse, e, formal->ts, 0);

      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      argarray[curr_arg] = argse.expr;
    }
}

/* Count the number of actual arguments to the intrinsic function EXPR
   including any "hidden" string length arguments.  */

static unsigned int
gfc_intrinsic_argument_list_length (gfc_expr *expr)
{
  int n = 0;
  gfc_actual_arglist *actual;

  for (actual = expr->value.function.actual; actual; actual = actual->next)
    {
      if (!actual->expr)
	continue;

      if (actual->expr->ts.type == BT_CHARACTER)
	n += 2;
      else
	n++;
    }

  return n;
}


/* Conversions between different types are output by the frontend as
   intrinsic functions.  We implement these directly with inline code.  */

static void
gfc_conv_intrinsic_conversion (gfc_se * se, gfc_expr * expr)
{
  tree type;
  tree *args;
  int nargs;

  nargs = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, nargs);

  /* Evaluate all the arguments passed. Whilst we're only interested in the
     first one here, there are other parts of the front-end that assume this
     and will trigger an ICE if it's not the case.  */
  type = gfc_typenode_for_spec (&expr->ts);
  gcc_assert (expr->value.function.actual->expr);
  gfc_conv_intrinsic_function_args (se, expr, args, nargs);

  /* Conversion between character kinds involves a call to a library
     function.  */
  if (expr->ts.type == BT_CHARACTER)
    {
      tree fndecl, var, addr, tmp;

      if (expr->ts.kind == 1
	  && expr->value.function.actual->expr->ts.kind == 4)
	fndecl = gfor_fndecl_convert_char4_to_char1;
      else if (expr->ts.kind == 4
	       && expr->value.function.actual->expr->ts.kind == 1)
	fndecl = gfor_fndecl_convert_char1_to_char4;
      else
	gcc_unreachable ();

      /* Create the variable storing the converted value.  */
      type = gfc_get_pchar_type (expr->ts.kind);
      var = gfc_create_var (type, "str");
      addr = gfc_build_addr_expr (build_pointer_type (type), var);

      /* Call the library function that will perform the conversion.  */
      gcc_assert (nargs >= 2);
      tmp = build_call_expr_loc (input_location,
			     fndecl, 3, addr, args[0], args[1]);
      gfc_add_expr_to_block (&se->pre, tmp);

      /* Free the temporary afterwards.  */
      tmp = gfc_call_free (var);
      gfc_add_expr_to_block (&se->post, tmp);

      se->expr = var;
      se->string_length = args[0];

      return;
    }

  /* Conversion from complex to non-complex involves taking the real
     component of the value.  */
  if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
      && expr->ts.type != BT_COMPLEX)
    {
      tree artype;

      artype = TREE_TYPE (TREE_TYPE (args[0]));
      args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
				 args[0]);
    }

  se->expr = convert (type, args[0]);
}

/* This is needed because the gcc backend only implements
   FIX_TRUNC_EXPR, which is the same as INT() in Fortran.
   FLOOR(x) = INT(x) <= x ? INT(x) : INT(x) - 1
   Similarly for CEILING.  */

static tree
build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
{
  tree tmp;
  tree cond;
  tree argtype;
  tree intval;

  argtype = TREE_TYPE (arg);
  arg = gfc_evaluate_now (arg, pblock);

  intval = convert (type, arg);
  intval = gfc_evaluate_now (intval, pblock);

  tmp = convert (argtype, intval);
  cond = fold_build2_loc (input_location, up ? GE_EXPR : LE_EXPR,
			  logical_type_node, tmp, arg);

  tmp = fold_build2_loc (input_location, up ? PLUS_EXPR : MINUS_EXPR, type,
			 intval, build_int_cst (type, 1));
  tmp = fold_build3_loc (input_location, COND_EXPR, type, cond, intval, tmp);
  return tmp;
}


/* Round to nearest integer, away from zero.  */

static tree
build_round_expr (tree arg, tree restype)
{
  tree argtype;
  tree fn;
  int argprec, resprec;

  argtype = TREE_TYPE (arg);
  argprec = TYPE_PRECISION (argtype);
  resprec = TYPE_PRECISION (restype);

  /* Depending on the type of the result, choose the int intrinsic
     (iround, available only as a builtin, therefore cannot use it for
     __float128), long int intrinsic (lround family) or long long
     intrinsic (llround).  We might also need to convert the result
     afterwards.  */
  if (resprec <= INT_TYPE_SIZE && argprec <= LONG_DOUBLE_TYPE_SIZE)
    fn = builtin_decl_for_precision (BUILT_IN_IROUND, argprec);
  else if (resprec <= LONG_TYPE_SIZE)
    fn = builtin_decl_for_precision (BUILT_IN_LROUND, argprec);
  else if (resprec <= LONG_LONG_TYPE_SIZE)
    fn = builtin_decl_for_precision (BUILT_IN_LLROUND, argprec);
  else
    gcc_unreachable ();

  return fold_convert (restype, build_call_expr_loc (input_location,
						 fn, 1, arg));
}


/* Convert a real to an integer using a specific rounding mode.
   Ideally we would just build the corresponding GENERIC node,
   however the RTL expander only actually supports FIX_TRUNC_EXPR.  */

static tree
build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
               enum rounding_mode op)
{
  switch (op)
    {
    case RND_FLOOR:
      return build_fixbound_expr (pblock, arg, type, 0);

    case RND_CEIL:
      return build_fixbound_expr (pblock, arg, type, 1);

    case RND_ROUND:
      return build_round_expr (arg, type);

    case RND_TRUNC:
      return fold_build1_loc (input_location, FIX_TRUNC_EXPR, type, arg);

    default:
      gcc_unreachable ();
    }
}


/* Round a real value using the specified rounding mode.
   We use a temporary integer of that same kind size as the result.
   Values larger than those that can be represented by this kind are
   unchanged, as they will not be accurate enough to represent the
   rounding.
    huge = HUGE (KIND (a))
    aint (a) = ((a > huge) || (a < -huge)) ? a : (real)(int)a
   */

static void
gfc_conv_intrinsic_aint (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
{
  tree type;
  tree itype;
  tree arg[2];
  tree tmp;
  tree cond;
  tree decl;
  mpfr_t huge;
  int n, nargs;
  int kind;

  kind = expr->ts.kind;
  nargs = gfc_intrinsic_argument_list_length (expr);

  decl = NULL_TREE;
  /* We have builtin functions for some cases.  */
  switch (op)
    {
    case RND_ROUND:
      decl = gfc_builtin_decl_for_float_kind (BUILT_IN_ROUND, kind);
      break;

    case RND_TRUNC:
      decl = gfc_builtin_decl_for_float_kind (BUILT_IN_TRUNC, kind);
      break;

    default:
      gcc_unreachable ();
    }

  /* Evaluate the argument.  */
  gcc_assert (expr->value.function.actual->expr);
  gfc_conv_intrinsic_function_args (se, expr, arg, nargs);

  /* Use a builtin function if one exists.  */
  if (decl != NULL_TREE)
    {
      se->expr = build_call_expr_loc (input_location, decl, 1, arg[0]);
      return;
    }

  /* This code is probably redundant, but we'll keep it lying around just
     in case.  */
  type = gfc_typenode_for_spec (&expr->ts);
  arg[0] = gfc_evaluate_now (arg[0], &se->pre);

  /* Test if the value is too large to handle sensibly.  */
  gfc_set_model_kind (kind);
  mpfr_init (huge);
  n = gfc_validate_kind (BT_INTEGER, kind, false);
  mpfr_set_z (huge, gfc_integer_kinds[n].huge, GFC_RND_MODE);
  tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node, arg[0],
			  tmp);

  mpfr_neg (huge, huge, GFC_RND_MODE);
  tmp = gfc_conv_mpfr_to_tree (huge, kind, 0);
  tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node, arg[0],
			 tmp);
  cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
			  cond, tmp);
  itype = gfc_get_int_type (kind);

  tmp = build_fix_expr (&se->pre, arg[0], itype, op);
  tmp = convert (type, tmp);
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
			      arg[0]);
  mpfr_clear (huge);
}


/* Convert to an integer using the specified rounding mode.  */

static void
gfc_conv_intrinsic_int (gfc_se * se, gfc_expr * expr, enum rounding_mode op)
{
  tree type;
  tree *args;
  int nargs;

  nargs = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, nargs);

  /* Evaluate the argument, we process all arguments even though we only
     use the first one for code generation purposes.  */
  type = gfc_typenode_for_spec (&expr->ts);
  gcc_assert (expr->value.function.actual->expr);
  gfc_conv_intrinsic_function_args (se, expr, args, nargs);

  if (TREE_CODE (TREE_TYPE (args[0])) == INTEGER_TYPE)
    {
      /* Conversion to a different integer kind.  */
      se->expr = convert (type, args[0]);
    }
  else
    {
      /* Conversion from complex to non-complex involves taking the real
         component of the value.  */
      if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE
	  && expr->ts.type != BT_COMPLEX)
	{
	  tree artype;

	  artype = TREE_TYPE (TREE_TYPE (args[0]));
	  args[0] = fold_build1_loc (input_location, REALPART_EXPR, artype,
				     args[0]);
	}

      se->expr = build_fix_expr (&se->pre, args[0], type, op);
    }
}


/* Get the imaginary component of a value.  */

static void
gfc_conv_intrinsic_imagpart (gfc_se * se, gfc_expr * expr)
{
  tree arg;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  se->expr = fold_build1_loc (input_location, IMAGPART_EXPR,
			      TREE_TYPE (TREE_TYPE (arg)), arg);
}


/* Get the complex conjugate of a value.  */

static void
gfc_conv_intrinsic_conjg (gfc_se * se, gfc_expr * expr)
{
  tree arg;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  se->expr = fold_build1_loc (input_location, CONJ_EXPR, TREE_TYPE (arg), arg);
}



static tree
define_quad_builtin (const char *name, tree type, bool is_const)
{
  tree fndecl;
  fndecl = build_decl (input_location, FUNCTION_DECL, get_identifier (name),
		       type);

  /* Mark the decl as external.  */
  DECL_EXTERNAL (fndecl) = 1;
  TREE_PUBLIC (fndecl) = 1;

  /* Mark it __attribute__((const)).  */
  TREE_READONLY (fndecl) = is_const;

  rest_of_decl_compilation (fndecl, 1, 0);

  return fndecl;
}

/* Add SIMD attribute for FNDECL built-in if the built-in
   name is in VECTORIZED_BUILTINS.  */

static void
add_simd_flag_for_built_in (tree fndecl)
{
  if (gfc_vectorized_builtins == NULL
      || fndecl == NULL_TREE)
    return;

  const char *name = IDENTIFIER_POINTER (DECL_NAME (fndecl));
  int *clauses = gfc_vectorized_builtins->get (name);
  if (clauses)
    {
      for (unsigned i = 0; i < 3; i++)
	if (*clauses & (1 << i))
	  {
	    gfc_simd_clause simd_type = (gfc_simd_clause)*clauses;
	    tree omp_clause = NULL_TREE;
	    if (simd_type == SIMD_NONE)
	      ; /* No SIMD clause.  */
	    else
	      {
		omp_clause_code code
		  = (simd_type == SIMD_INBRANCH
		     ? OMP_CLAUSE_INBRANCH : OMP_CLAUSE_NOTINBRANCH);
		omp_clause = build_omp_clause (UNKNOWN_LOCATION, code);
		omp_clause = build_tree_list (NULL_TREE, omp_clause);
	      }

	    DECL_ATTRIBUTES (fndecl)
	      = tree_cons (get_identifier ("omp declare simd"), omp_clause,
			   DECL_ATTRIBUTES (fndecl));
	  }
    }
}

  /* Set SIMD attribute to all built-in functions that are mentioned
     in gfc_vectorized_builtins vector.  */

void
gfc_adjust_builtins (void)
{
  gfc_intrinsic_map_t *m;
  for (m = gfc_intrinsic_map;
       m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
    {
      add_simd_flag_for_built_in (m->real4_decl);
      add_simd_flag_for_built_in (m->complex4_decl);
      add_simd_flag_for_built_in (m->real8_decl);
      add_simd_flag_for_built_in (m->complex8_decl);
      add_simd_flag_for_built_in (m->real10_decl);
      add_simd_flag_for_built_in (m->complex10_decl);
      add_simd_flag_for_built_in (m->real16_decl);
      add_simd_flag_for_built_in (m->complex16_decl);
      add_simd_flag_for_built_in (m->real16_decl);
      add_simd_flag_for_built_in (m->complex16_decl);
    }

  /* Release all strings.  */
  if (gfc_vectorized_builtins != NULL)
    {
      for (hash_map<nofree_string_hash, int>::iterator it
	   = gfc_vectorized_builtins->begin ();
	   it != gfc_vectorized_builtins->end (); ++it)
	free (CONST_CAST (char *, (*it).first));

      delete gfc_vectorized_builtins;
      gfc_vectorized_builtins = NULL;
    }
}

/* Initialize function decls for library functions.  The external functions
   are created as required.  Builtin functions are added here.  */

void
gfc_build_intrinsic_lib_fndecls (void)
{
  gfc_intrinsic_map_t *m;
  tree quad_decls[END_BUILTINS + 1];

  if (gfc_real16_is_float128)
  {
    /* If we have soft-float types, we create the decls for their
       C99-like library functions.  For now, we only handle __float128
       q-suffixed functions.  */

    tree type, complex_type, func_1, func_2, func_cabs, func_frexp;
    tree func_iround, func_lround, func_llround, func_scalbn, func_cpow;

    memset (quad_decls, 0, sizeof(tree) * (END_BUILTINS + 1));

    type = gfc_float128_type_node;
    complex_type = gfc_complex_float128_type_node;
    /* type (*) (type) */
    func_1 = build_function_type_list (type, type, NULL_TREE);
    /* int (*) (type) */
    func_iround = build_function_type_list (integer_type_node,
					    type, NULL_TREE);
    /* long (*) (type) */
    func_lround = build_function_type_list (long_integer_type_node,
					    type, NULL_TREE);
    /* long long (*) (type) */
    func_llround = build_function_type_list (long_long_integer_type_node,
					     type, NULL_TREE);
    /* type (*) (type, type) */
    func_2 = build_function_type_list (type, type, type, NULL_TREE);
    /* type (*) (type, &int) */
    func_frexp
      = build_function_type_list (type,
				  type,
				  build_pointer_type (integer_type_node),
				  NULL_TREE);
    /* type (*) (type, int) */
    func_scalbn = build_function_type_list (type,
					    type, integer_type_node, NULL_TREE);
    /* type (*) (complex type) */
    func_cabs = build_function_type_list (type, complex_type, NULL_TREE);
    /* complex type (*) (complex type, complex type) */
    func_cpow
      = build_function_type_list (complex_type,
				  complex_type, complex_type, NULL_TREE);

#define DEFINE_MATH_BUILTIN(ID, NAME, ARGTYPE)
#define DEFINE_MATH_BUILTIN_C(ID, NAME, ARGTYPE)
#define LIB_FUNCTION(ID, NAME, HAVE_COMPLEX)

    /* Only these built-ins are actually needed here. These are used directly
       from the code, when calling builtin_decl_for_precision() or
       builtin_decl_for_float_type(). The others are all constructed by
       gfc_get_intrinsic_lib_fndecl().  */
#define OTHER_BUILTIN(ID, NAME, TYPE, CONST) \
  quad_decls[BUILT_IN_ ## ID] = define_quad_builtin (NAME "q", func_ ## TYPE, CONST);

#include "mathbuiltins.def"

#undef OTHER_BUILTIN
#undef LIB_FUNCTION
#undef DEFINE_MATH_BUILTIN
#undef DEFINE_MATH_BUILTIN_C

    /* There is one built-in we defined manually, because it gets called
       with builtin_decl_for_precision() or builtin_decl_for_float_type()
       even though it is not an OTHER_BUILTIN: it is SQRT.  */
    quad_decls[BUILT_IN_SQRT] = define_quad_builtin ("sqrtq", func_1, true);

  }

  /* Add GCC builtin functions.  */
  for (m = gfc_intrinsic_map;
       m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
    {
      if (m->float_built_in != END_BUILTINS)
	m->real4_decl = builtin_decl_explicit (m->float_built_in);
      if (m->complex_float_built_in != END_BUILTINS)
	m->complex4_decl = builtin_decl_explicit (m->complex_float_built_in);
      if (m->double_built_in != END_BUILTINS)
	m->real8_decl = builtin_decl_explicit (m->double_built_in);
      if (m->complex_double_built_in != END_BUILTINS)
	m->complex8_decl = builtin_decl_explicit (m->complex_double_built_in);

      /* If real(kind=10) exists, it is always long double.  */
      if (m->long_double_built_in != END_BUILTINS)
	m->real10_decl = builtin_decl_explicit (m->long_double_built_in);
      if (m->complex_long_double_built_in != END_BUILTINS)
	m->complex10_decl
	  = builtin_decl_explicit (m->complex_long_double_built_in);

      if (!gfc_real16_is_float128)
	{
	  if (m->long_double_built_in != END_BUILTINS)
	    m->real16_decl = builtin_decl_explicit (m->long_double_built_in);
	  if (m->complex_long_double_built_in != END_BUILTINS)
	    m->complex16_decl
	      = builtin_decl_explicit (m->complex_long_double_built_in);
	}
      else if (quad_decls[m->double_built_in] != NULL_TREE)
        {
	  /* Quad-precision function calls are constructed when first
	     needed by builtin_decl_for_precision(), except for those
	     that will be used directly (define by OTHER_BUILTIN).  */
	  m->real16_decl = quad_decls[m->double_built_in];
	}
      else if (quad_decls[m->complex_double_built_in] != NULL_TREE)
        {
	  /* Same thing for the complex ones.  */
	  m->complex16_decl = quad_decls[m->double_built_in];
	}
    }
}


/* Create a fndecl for a simple intrinsic library function.  */

static tree
gfc_get_intrinsic_lib_fndecl (gfc_intrinsic_map_t * m, gfc_expr * expr)
{
  tree type;
  vec<tree, va_gc> *argtypes;
  tree fndecl;
  gfc_actual_arglist *actual;
  tree *pdecl;
  gfc_typespec *ts;
  char name[GFC_MAX_SYMBOL_LEN + 3];

  ts = &expr->ts;
  if (ts->type == BT_REAL)
    {
      switch (ts->kind)
	{
	case 4:
	  pdecl = &m->real4_decl;
	  break;
	case 8:
	  pdecl = &m->real8_decl;
	  break;
	case 10:
	  pdecl = &m->real10_decl;
	  break;
	case 16:
	  pdecl = &m->real16_decl;
	  break;
	default:
	  gcc_unreachable ();
	}
    }
  else if (ts->type == BT_COMPLEX)
    {
      gcc_assert (m->complex_available);

      switch (ts->kind)
	{
	case 4:
	  pdecl = &m->complex4_decl;
	  break;
	case 8:
	  pdecl = &m->complex8_decl;
	  break;
	case 10:
	  pdecl = &m->complex10_decl;
	  break;
	case 16:
	  pdecl = &m->complex16_decl;
	  break;
	default:
	  gcc_unreachable ();
	}
    }
  else
    gcc_unreachable ();

  if (*pdecl)
    return *pdecl;

  if (m->libm_name)
    {
      int n = gfc_validate_kind (BT_REAL, ts->kind, false);
      if (gfc_real_kinds[n].c_float)
	snprintf (name, sizeof (name), "%s%s%s",
		  ts->type == BT_COMPLEX ? "c" : "", m->name, "f");
      else if (gfc_real_kinds[n].c_double)
	snprintf (name, sizeof (name), "%s%s",
		  ts->type == BT_COMPLEX ? "c" : "", m->name);
      else if (gfc_real_kinds[n].c_long_double)
	snprintf (name, sizeof (name), "%s%s%s",
		  ts->type == BT_COMPLEX ? "c" : "", m->name, "l");
      else if (gfc_real_kinds[n].c_float128)
	snprintf (name, sizeof (name), "%s%s%s",
		  ts->type == BT_COMPLEX ? "c" : "", m->name, "q");
      else
	gcc_unreachable ();
    }
  else
    {
      snprintf (name, sizeof (name), PREFIX ("%s_%c%d"), m->name,
		ts->type == BT_COMPLEX ? 'c' : 'r',
		ts->kind);
    }

  argtypes = NULL;
  for (actual = expr->value.function.actual; actual; actual = actual->next)
    {
      type = gfc_typenode_for_spec (&actual->expr->ts);
      vec_safe_push (argtypes, type);
    }
  type = build_function_type_vec (gfc_typenode_for_spec (ts), argtypes);
  fndecl = build_decl (input_location,
		       FUNCTION_DECL, get_identifier (name), type);

  /* Mark the decl as external.  */
  DECL_EXTERNAL (fndecl) = 1;
  TREE_PUBLIC (fndecl) = 1;

  /* Mark it __attribute__((const)), if possible.  */
  TREE_READONLY (fndecl) = m->is_constant;

  rest_of_decl_compilation (fndecl, 1, 0);

  (*pdecl) = fndecl;
  return fndecl;
}


/* Convert an intrinsic function into an external or builtin call.  */

static void
gfc_conv_intrinsic_lib_function (gfc_se * se, gfc_expr * expr)
{
  gfc_intrinsic_map_t *m;
  tree fndecl;
  tree rettype;
  tree *args;
  unsigned int num_args;
  gfc_isym_id id;

  id = expr->value.function.isym->id;
  /* Find the entry for this function.  */
  for (m = gfc_intrinsic_map;
       m->id != GFC_ISYM_NONE || m->double_built_in != END_BUILTINS; m++)
    {
      if (id == m->id)
	break;
    }

  if (m->id == GFC_ISYM_NONE)
    {
      gfc_internal_error ("Intrinsic function %qs (%d) not recognized",
			  expr->value.function.name, id);
    }

  /* Get the decl and generate the call.  */
  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);

  gfc_conv_intrinsic_function_args (se, expr, args, num_args);
  fndecl = gfc_get_intrinsic_lib_fndecl (m, expr);
  rettype = TREE_TYPE (TREE_TYPE (fndecl));

  fndecl = build_addr (fndecl);
  se->expr = build_call_array_loc (input_location, rettype, fndecl, num_args, args);
}


/* If bounds-checking is enabled, create code to verify at runtime that the
   string lengths for both expressions are the same (needed for e.g. MERGE).
   If bounds-checking is not enabled, does nothing.  */

void
gfc_trans_same_strlen_check (const char* intr_name, locus* where,
			     tree a, tree b, stmtblock_t* target)
{
  tree cond;
  tree name;

  /* If bounds-checking is disabled, do nothing.  */
  if (!(gfc_option.rtcheck & GFC_RTCHECK_BOUNDS))
    return;

  /* Compare the two string lengths.  */
  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, a, b);

  /* Output the runtime-check.  */
  name = gfc_build_cstring_const (intr_name);
  name = gfc_build_addr_expr (pchar_type_node, name);
  gfc_trans_runtime_check (true, false, cond, target, where,
			   "Unequal character lengths (%ld/%ld) in %s",
			   fold_convert (long_integer_type_node, a),
			   fold_convert (long_integer_type_node, b), name);
}


/* The EXPONENT(X) intrinsic function is translated into
       int ret;
       return isfinite(X) ? (frexp (X, &ret) , ret) : huge
   so that if X is a NaN or infinity, the result is HUGE(0).
 */

static void
gfc_conv_intrinsic_exponent (gfc_se *se, gfc_expr *expr)
{
  tree arg, type, res, tmp, frexp, cond, huge;
  int i;

  frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP,
				       expr->value.function.actual->expr->ts.kind);

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  i = gfc_validate_kind (BT_INTEGER, gfc_c_int_kind, false);
  huge = gfc_conv_mpz_to_tree (gfc_integer_kinds[i].huge, gfc_c_int_kind);
  cond = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_ISFINITE),
			      1, arg);

  res = gfc_create_var (integer_type_node, NULL);
  tmp = build_call_expr_loc (input_location, frexp, 2, arg,
			     gfc_build_addr_expr (NULL_TREE, res));
  tmp = fold_build2_loc (input_location, COMPOUND_EXPR, integer_type_node,
			 tmp, res);
  se->expr = fold_build3_loc (input_location, COND_EXPR, integer_type_node,
			      cond, tmp, huge);

  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = fold_convert (type, se->expr);
}


/* Fill in the following structure
     struct caf_vector_t {
       size_t nvec;  // size of the vector
       union {
         struct {
           void *vector;
           int kind;
         } v;
         struct {
           ptrdiff_t lower_bound;
           ptrdiff_t upper_bound;
           ptrdiff_t stride;
         } triplet;
       } u;
     }  */

static void
conv_caf_vector_subscript_elem (stmtblock_t *block, int i, tree desc,
				tree lower, tree upper, tree stride,
				tree vector, int kind, tree nvec)
{
  tree field, type, tmp;

  desc = gfc_build_array_ref (desc, gfc_rank_cst[i], NULL_TREE);
  type = TREE_TYPE (desc);

  field = gfc_advance_chain (TYPE_FIELDS (type), 0);
  tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			 desc, field, NULL_TREE);
  gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field), nvec));

  /* Access union.  */
  field = gfc_advance_chain (TYPE_FIELDS (type), 1);
  desc = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			  desc, field, NULL_TREE);
  type = TREE_TYPE (desc);

  /* Access the inner struct.  */
  field = gfc_advance_chain (TYPE_FIELDS (type), vector != NULL_TREE ? 0 : 1);
  desc = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
		      desc, field, NULL_TREE);
  type = TREE_TYPE (desc);

  if (vector != NULL_TREE)
    {
      /* Set vector and kind.  */
      field = gfc_advance_chain (TYPE_FIELDS (type), 0);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			 desc, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field), vector));
      field = gfc_advance_chain (TYPE_FIELDS (type), 1);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			 desc, field, NULL_TREE);
      gfc_add_modify (block, tmp, build_int_cst (integer_type_node, kind));
    }
  else
    {
      /* Set dim.lower/upper/stride.  */
      field = gfc_advance_chain (TYPE_FIELDS (type), 0);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     desc, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field), lower));

      field = gfc_advance_chain (TYPE_FIELDS (type), 1);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     desc, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field), upper));

      field = gfc_advance_chain (TYPE_FIELDS (type), 2);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     desc, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field), stride));
    }
}


static tree
conv_caf_vector_subscript (stmtblock_t *block, tree desc, gfc_array_ref *ar)
{
  gfc_se argse;
  tree var, lower, upper = NULL_TREE, stride = NULL_TREE, vector, nvec;
  tree lbound, ubound, tmp;
  int i;

  var = gfc_create_var (gfc_get_caf_vector_type (ar->dimen), "vector");

  for (i = 0; i < ar->dimen; i++)
    switch (ar->dimen_type[i])
      {
      case DIMEN_RANGE:
        if (ar->end[i])
	  {
	    gfc_init_se (&argse, NULL);
	    gfc_conv_expr (&argse, ar->end[i]);
	    gfc_add_block_to_block (block, &argse.pre);
	    upper = gfc_evaluate_now (argse.expr, block);
	  }
        else
	  upper = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
	if (ar->stride[i])
	  {
	    gfc_init_se (&argse, NULL);
	    gfc_conv_expr (&argse, ar->stride[i]);
	    gfc_add_block_to_block (block, &argse.pre);
	    stride = gfc_evaluate_now (argse.expr, block);
	  }
	else
	  stride = gfc_index_one_node;

	/* Fall through.  */
      case DIMEN_ELEMENT:
	if (ar->start[i])
	  {
	    gfc_init_se (&argse, NULL);
	    gfc_conv_expr (&argse, ar->start[i]);
	    gfc_add_block_to_block (block, &argse.pre);
	    lower = gfc_evaluate_now (argse.expr, block);
	  }
	else
	  lower = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
	if (ar->dimen_type[i] == DIMEN_ELEMENT)
	  {
	    upper = lower;
	    stride = gfc_index_one_node;
	  }
	vector = NULL_TREE;
	nvec = size_zero_node;
	conv_caf_vector_subscript_elem (block, i, var, lower, upper, stride,
					vector, 0, nvec);
	break;

      case DIMEN_VECTOR:
	gfc_init_se (&argse, NULL);
	argse.descriptor_only = 1;
	gfc_conv_expr_descriptor (&argse, ar->start[i]);
	gfc_add_block_to_block (block, &argse.pre);
	vector = argse.expr;
	lbound = gfc_conv_descriptor_lbound_get (vector, gfc_rank_cst[0]);
	ubound = gfc_conv_descriptor_ubound_get (vector, gfc_rank_cst[0]);
	nvec = gfc_conv_array_extent_dim (lbound, ubound, NULL);
        tmp = gfc_conv_descriptor_stride_get (vector, gfc_rank_cst[0]);
	nvec = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
				TREE_TYPE (nvec), nvec, tmp);
	lower = gfc_index_zero_node;
	upper = gfc_index_zero_node;
	stride = gfc_index_zero_node;
	vector = gfc_conv_descriptor_data_get (vector);
	conv_caf_vector_subscript_elem (block, i, var, lower, upper, stride,
					vector, ar->start[i]->ts.kind, nvec);
	break;
      default:
	gcc_unreachable();
    }
  return gfc_build_addr_expr (NULL_TREE, var);
}


static tree
compute_component_offset (tree field, tree type)
{
  tree tmp;
  if (DECL_FIELD_BIT_OFFSET (field) != NULL_TREE
      && !integer_zerop (DECL_FIELD_BIT_OFFSET (field)))
    {
      tmp = fold_build2 (TRUNC_DIV_EXPR, type,
			 DECL_FIELD_BIT_OFFSET (field),
			 bitsize_unit_node);
      return fold_build2 (PLUS_EXPR, type, DECL_FIELD_OFFSET (field), tmp);
    }
  else
    return DECL_FIELD_OFFSET (field);
}


static tree
conv_expr_ref_to_caf_ref (stmtblock_t *block, gfc_expr *expr)
{
  gfc_ref *ref = expr->ref, *last_comp_ref;
  tree caf_ref = NULL_TREE, prev_caf_ref = NULL_TREE, reference_type, tmp, tmp2,
      field, last_type, inner_struct, mode, mode_rhs, dim_array, dim, dim_type,
      start, end, stride, vector, nvec;
  gfc_se se;
  bool ref_static_array = false;
  tree last_component_ref_tree = NULL_TREE;
  int i, last_type_n;

  if (expr->symtree)
    {
      last_component_ref_tree = expr->symtree->n.sym->backend_decl;
      ref_static_array = !expr->symtree->n.sym->attr.allocatable
	  && !expr->symtree->n.sym->attr.pointer;
    }

  /* Prevent uninit-warning.  */
  reference_type = NULL_TREE;

  /* Skip refs upto the first coarray-ref.  */
  last_comp_ref = NULL;
  while (ref && (ref->type != REF_ARRAY || ref->u.ar.codimen == 0))
    {
      /* Remember the type of components skipped.  */
      if (ref->type == REF_COMPONENT)
	last_comp_ref = ref;
      ref = ref->next;
    }
  /* When a component was skipped, get the type information of the last
     component ref, else get the type from the symbol.  */
  if (last_comp_ref)
    {
      last_type = gfc_typenode_for_spec (&last_comp_ref->u.c.component->ts);
      last_type_n = last_comp_ref->u.c.component->ts.type;
    }
  else
    {
      last_type = gfc_typenode_for_spec (&expr->symtree->n.sym->ts);
      last_type_n = expr->symtree->n.sym->ts.type;
    }

  while (ref)
    {
      if (ref->type == REF_ARRAY && ref->u.ar.codimen > 0
	  && ref->u.ar.dimen == 0)
	{
	  /* Skip pure coindexes.  */
	  ref = ref->next;
	  continue;
	}
      tmp = gfc_create_var (gfc_get_caf_reference_type (), "caf_ref");
      reference_type = TREE_TYPE (tmp);

      if (caf_ref == NULL_TREE)
	caf_ref = tmp;

      /* Construct the chain of refs.  */
      if (prev_caf_ref != NULL_TREE)
	{
	  field = gfc_advance_chain (TYPE_FIELDS (reference_type), 0);
	  tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
				  TREE_TYPE (field), prev_caf_ref, field,
				  NULL_TREE);
	  gfc_add_modify (block, tmp2, gfc_build_addr_expr (TREE_TYPE (field),
							    tmp));
	}
      prev_caf_ref = tmp;

      switch (ref->type)
	{
	case REF_COMPONENT:
	  last_type = gfc_typenode_for_spec (&ref->u.c.component->ts);
	  last_type_n = ref->u.c.component->ts.type;
	  /* Set the type of the ref.  */
	  field = gfc_advance_chain (TYPE_FIELDS (reference_type), 1);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), prev_caf_ref, field,
				 NULL_TREE);
	  gfc_add_modify (block, tmp, build_int_cst (integer_type_node,
						     GFC_CAF_REF_COMPONENT));

	  /* Ref the c in union u.  */
	  field = gfc_advance_chain (TYPE_FIELDS (reference_type), 3);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), prev_caf_ref, field,
				 NULL_TREE);
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (field)), 0);
	  inner_struct = fold_build3_loc (input_location, COMPONENT_REF,
				       TREE_TYPE (field), tmp, field,
				       NULL_TREE);

	  /* Set the offset.  */
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (inner_struct)), 0);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), inner_struct, field,
				 NULL_TREE);
	  /* Computing the offset is somewhat harder.  The bit_offset has to be
	     taken into account.  When the bit_offset in the field_decl is non-
	     null, divide it by the bitsize_unit and add it to the regular
	     offset.  */
	  tmp2 = compute_component_offset (ref->u.c.component->backend_decl,
					   TREE_TYPE (tmp));
	  gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));

	  /* Set caf_token_offset.  */
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (inner_struct)), 1);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), inner_struct, field,
				 NULL_TREE);
	  if ((ref->u.c.component->attr.allocatable
	       || ref->u.c.component->attr.pointer)
	      && ref->u.c.component->attr.dimension)
	    {
	      tree arr_desc_token_offset;
	      /* Get the token field from the descriptor.  */
	      arr_desc_token_offset = TREE_OPERAND (
		    gfc_conv_descriptor_token (ref->u.c.component->backend_decl), 1);
	      arr_desc_token_offset
		  = compute_component_offset (arr_desc_token_offset,
					      TREE_TYPE (tmp));
	      tmp2 = fold_build2_loc (input_location, PLUS_EXPR,
				      TREE_TYPE (tmp2), tmp2,
				      arr_desc_token_offset);
	    }
	  else if (ref->u.c.component->caf_token)
	    tmp2 = compute_component_offset (ref->u.c.component->caf_token,
					     TREE_TYPE (tmp));
	  else
	    tmp2 = integer_zero_node;
	  gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (tmp), tmp2));

	  /* Remember whether this ref was to a non-allocatable/non-pointer
	     component so the next array ref can be tailored correctly.  */
	  ref_static_array = !ref->u.c.component->attr.allocatable
	      && !ref->u.c.component->attr.pointer;
	  last_component_ref_tree = ref_static_array
	      ? ref->u.c.component->backend_decl : NULL_TREE;
	  break;
	case REF_ARRAY:
	  if (ref_static_array && ref->u.ar.as->type == AS_DEFERRED)
	    ref_static_array = false;
	  /* Set the type of the ref.  */
	  field = gfc_advance_chain (TYPE_FIELDS (reference_type), 1);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), prev_caf_ref, field,
				 NULL_TREE);
	  gfc_add_modify (block, tmp, build_int_cst (integer_type_node,
						     ref_static_array
						     ? GFC_CAF_REF_STATIC_ARRAY
						     : GFC_CAF_REF_ARRAY));

	  /* Ref the a in union u.  */
	  field = gfc_advance_chain (TYPE_FIELDS (reference_type), 3);
	  tmp = fold_build3_loc (input_location, COMPONENT_REF,
				 TREE_TYPE (field), prev_caf_ref, field,
				 NULL_TREE);
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (field)), 1);
	  inner_struct = fold_build3_loc (input_location, COMPONENT_REF,
				       TREE_TYPE (field), tmp, field,
				       NULL_TREE);

	  /* Set the static_array_type in a for static arrays.  */
	  if (ref_static_array)
	    {
	      field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (inner_struct)),
					 1);
	      tmp = fold_build3_loc (input_location, COMPONENT_REF,
				     TREE_TYPE (field), inner_struct, field,
				     NULL_TREE);
	      gfc_add_modify (block, tmp, build_int_cst (TREE_TYPE (tmp),
							 last_type_n));
	    }
	  /* Ref the mode in the inner_struct.  */
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (inner_struct)), 0);
	  mode = fold_build3_loc (input_location, COMPONENT_REF,
				  TREE_TYPE (field), inner_struct, field,
				  NULL_TREE);
	  /* Ref the dim in the inner_struct.  */
	  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (inner_struct)), 2);
	  dim_array = fold_build3_loc (input_location, COMPONENT_REF,
				       TREE_TYPE (field), inner_struct, field,
				       NULL_TREE);
	  for (i = 0; i < ref->u.ar.dimen; ++i)
	    {
	      /* Ref dim i.  */
	      dim = gfc_build_array_ref (dim_array, gfc_rank_cst[i], NULL_TREE);
	      dim_type = TREE_TYPE (dim);
	      mode_rhs = start = end = stride = NULL_TREE;
	      switch (ref->u.ar.dimen_type[i])
		{
		case DIMEN_RANGE:
		  if (ref->u.ar.end[i])
		    {
		      gfc_init_se (&se, NULL);
		      gfc_conv_expr (&se, ref->u.ar.end[i]);
		      gfc_add_block_to_block (block, &se.pre);
		      if (ref_static_array)
			{
			  /* Make the index zero-based, when reffing a static
			     array.  */
			  end = se.expr;
			  gfc_init_se (&se, NULL);
			  gfc_conv_expr (&se, ref->u.ar.as->lower[i]);
			  gfc_add_block_to_block (block, &se.pre);
			  se.expr = fold_build2 (MINUS_EXPR,
						 gfc_array_index_type,
						 end, fold_convert (
						   gfc_array_index_type,
						   se.expr));
			}
		      end = gfc_evaluate_now (fold_convert (
						gfc_array_index_type,
						se.expr),
					      block);
		    }
		  else if (ref_static_array)
		    end = fold_build2 (MINUS_EXPR,
				       gfc_array_index_type,
				       gfc_conv_array_ubound (
					 last_component_ref_tree, i),
				       gfc_conv_array_lbound (
					 last_component_ref_tree, i));
		  else
		    {
		      end = NULL_TREE;
		      mode_rhs = build_int_cst (unsigned_char_type_node,
						GFC_CAF_ARR_REF_OPEN_END);
		    }
		  if (ref->u.ar.stride[i])
		    {
		      gfc_init_se (&se, NULL);
		      gfc_conv_expr (&se, ref->u.ar.stride[i]);
		      gfc_add_block_to_block (block, &se.pre);
		      stride = gfc_evaluate_now (fold_convert (
						   gfc_array_index_type,
						   se.expr),
						 block);
		      if (ref_static_array)
			{
			  /* Make the index zero-based, when reffing a static
			     array.  */
			  stride = fold_build2 (MULT_EXPR,
						gfc_array_index_type,
						gfc_conv_array_stride (
						  last_component_ref_tree,
						  i),
						stride);
			  gcc_assert (end != NULL_TREE);
			  /* Multiply with the product of array's stride and
			     the step of the ref to a virtual upper bound.
			     We cannot compute the actual upper bound here or
			     the caflib would compute the extend
			     incorrectly.  */
			  end = fold_build2 (MULT_EXPR, gfc_array_index_type,
					     end, gfc_conv_array_stride (
					       last_component_ref_tree,
					       i));
			  end = gfc_evaluate_now (end, block);
			  stride = gfc_evaluate_now (stride, block);
			}
		    }
		  else if (ref_static_array)
		    {
		      stride = gfc_conv_array_stride (last_component_ref_tree,
						      i);
		      end = fold_build2 (MULT_EXPR, gfc_array_index_type,
					 end, stride);
		      end = gfc_evaluate_now (end, block);
		    }
		  else
		    /* Always set a ref stride of one to make caflib's
		       handling easier.  */
		    stride = gfc_index_one_node;

		  /* Fall through.  */
		case DIMEN_ELEMENT:
		  if (ref->u.ar.start[i])
		    {
		      gfc_init_se (&se, NULL);
		      gfc_conv_expr (&se, ref->u.ar.start[i]);
		      gfc_add_block_to_block (block, &se.pre);
		      if (ref_static_array)
			{
			  /* Make the index zero-based, when reffing a static
			     array.  */
			  start = fold_convert (gfc_array_index_type, se.expr);
			  gfc_init_se (&se, NULL);
			  gfc_conv_expr (&se, ref->u.ar.as->lower[i]);
			  gfc_add_block_to_block (block, &se.pre);
			  se.expr = fold_build2 (MINUS_EXPR,
						 gfc_array_index_type,
						 start, fold_convert (
						   gfc_array_index_type,
						   se.expr));
			  /* Multiply with the stride.  */
			  se.expr = fold_build2 (MULT_EXPR,
						 gfc_array_index_type,
						 se.expr,
						 gfc_conv_array_stride (
						   last_component_ref_tree,
						   i));
			}
		      start = gfc_evaluate_now (fold_convert (
						  gfc_array_index_type,
						  se.expr),
						block);
		      if (mode_rhs == NULL_TREE)
			mode_rhs = build_int_cst (unsigned_char_type_node,
						  ref->u.ar.dimen_type[i]
						  == DIMEN_ELEMENT
						  ? GFC_CAF_ARR_REF_SINGLE
						  : GFC_CAF_ARR_REF_RANGE);
		    }
		  else if (ref_static_array)
		    {
		      start = integer_zero_node;
		      mode_rhs = build_int_cst (unsigned_char_type_node,
						ref->u.ar.start[i] == NULL
						? GFC_CAF_ARR_REF_FULL
						: GFC_CAF_ARR_REF_RANGE);
		    }
		  else if (end == NULL_TREE)
		    mode_rhs = build_int_cst (unsigned_char_type_node,
					      GFC_CAF_ARR_REF_FULL);
		  else
		    mode_rhs = build_int_cst (unsigned_char_type_node,
					      GFC_CAF_ARR_REF_OPEN_START);

		  /* Ref the s in dim.  */
		  field = gfc_advance_chain (TYPE_FIELDS (dim_type), 0);
		  tmp = fold_build3_loc (input_location, COMPONENT_REF,
					 TREE_TYPE (field), dim, field,
					 NULL_TREE);

		  /* Set start in s.  */
		  if (start != NULL_TREE)
		    {
		      field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)),
						 0);
		      tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					      TREE_TYPE (field), tmp, field,
					      NULL_TREE);
		      gfc_add_modify (block, tmp2,
				      fold_convert (TREE_TYPE (tmp2), start));
		    }

		  /* Set end in s.  */
		  if (end != NULL_TREE)
		    {
		      field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)),
						 1);
		      tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					      TREE_TYPE (field), tmp, field,
					      NULL_TREE);
		      gfc_add_modify (block, tmp2,
				      fold_convert (TREE_TYPE (tmp2), end));
		    }

		  /* Set end in s.  */
		  if (stride != NULL_TREE)
		    {
		      field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)),
						 2);
		      tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					      TREE_TYPE (field), tmp, field,
					      NULL_TREE);
		      gfc_add_modify (block, tmp2,
				      fold_convert (TREE_TYPE (tmp2), stride));
		    }
		  break;
		case DIMEN_VECTOR:
		  /* TODO: In case of static array.  */
		  gcc_assert (!ref_static_array);
		  mode_rhs = build_int_cst (unsigned_char_type_node,
					    GFC_CAF_ARR_REF_VECTOR);
		  gfc_init_se (&se, NULL);
		  se.descriptor_only = 1;
		  gfc_conv_expr_descriptor (&se, ref->u.ar.start[i]);
		  gfc_add_block_to_block (block, &se.pre);
		  vector = se.expr;
		  tmp = gfc_conv_descriptor_lbound_get (vector,
							gfc_rank_cst[0]);
		  tmp2 = gfc_conv_descriptor_ubound_get (vector,
							 gfc_rank_cst[0]);
		  nvec = gfc_conv_array_extent_dim (tmp, tmp2, NULL);
		  tmp = gfc_conv_descriptor_stride_get (vector,
							gfc_rank_cst[0]);
		  nvec = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
					  TREE_TYPE (nvec), nvec, tmp);
		  vector = gfc_conv_descriptor_data_get (vector);

		  /* Ref the v in dim.  */
		  field = gfc_advance_chain (TYPE_FIELDS (dim_type), 1);
		  tmp = fold_build3_loc (input_location, COMPONENT_REF,
					 TREE_TYPE (field), dim, field,
					 NULL_TREE);

		  /* Set vector in v.  */
		  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), 0);
		  tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					  TREE_TYPE (field), tmp, field,
					  NULL_TREE);
		  gfc_add_modify (block, tmp2, fold_convert (TREE_TYPE (tmp2),
							     vector));

		  /* Set nvec in v.  */
		  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), 1);
		  tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					  TREE_TYPE (field), tmp, field,
					  NULL_TREE);
		  gfc_add_modify (block, tmp2, fold_convert (TREE_TYPE (tmp2),
							     nvec));

		  /* Set kind in v.  */
		  field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), 2);
		  tmp2 = fold_build3_loc (input_location, COMPONENT_REF,
					  TREE_TYPE (field), tmp, field,
					  NULL_TREE);
		  gfc_add_modify (block, tmp2, build_int_cst (integer_type_node,
						  ref->u.ar.start[i]->ts.kind));
		  break;
		default:
		  gcc_unreachable ();
		}
	      /* Set the mode for dim i.  */
	      tmp = gfc_build_array_ref (mode, gfc_rank_cst[i], NULL_TREE);
	      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (tmp),
							mode_rhs));
	    }

	  /* Set the mode for dim i+1 to GFC_ARR_REF_NONE.  */
	  if (i < GFC_MAX_DIMENSIONS)
	    {
	      tmp = gfc_build_array_ref (mode, gfc_rank_cst[i], NULL_TREE);
	      gfc_add_modify (block, tmp,
			      build_int_cst (unsigned_char_type_node,
					     GFC_CAF_ARR_REF_NONE));
	    }
	  break;
	default:
	  gcc_unreachable ();
	}

      /* Set the size of the current type.  */
      field = gfc_advance_chain (TYPE_FIELDS (reference_type), 2);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     prev_caf_ref, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field),
						TYPE_SIZE_UNIT (last_type)));

      ref = ref->next;
    }

  if (prev_caf_ref != NULL_TREE)
    {
      field = gfc_advance_chain (TYPE_FIELDS (reference_type), 0);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     prev_caf_ref, field, NULL_TREE);
      gfc_add_modify (block, tmp, fold_convert (TREE_TYPE (field),
						  null_pointer_node));
    }
  return caf_ref != NULL_TREE ? gfc_build_addr_expr (NULL_TREE, caf_ref)
			      : NULL_TREE;
}

/* Get data from a remote coarray.  */

static void
gfc_conv_intrinsic_caf_get (gfc_se *se, gfc_expr *expr, tree lhs, tree lhs_kind,
			    tree may_require_tmp, bool may_realloc,
			    symbol_attribute *caf_attr)
{
  gfc_expr *array_expr, *tmp_stat;
  gfc_se argse;
  tree caf_decl, token, offset, image_index, tmp;
  tree res_var, dst_var, type, kind, vec, stat;
  tree caf_reference;
  symbol_attribute caf_attr_store;

  gcc_assert (flag_coarray == GFC_FCOARRAY_LIB);

  if (se->ss && se->ss->info->useflags)
    {
       /* Access the previously obtained result.  */
       gfc_conv_tmp_array_ref (se);
       return;
    }

  /* If lhs is set, the CAF_GET intrinsic has already been stripped.  */
  array_expr = (lhs == NULL_TREE) ? expr->value.function.actual->expr : expr;
  type = gfc_typenode_for_spec (&array_expr->ts);

  if (caf_attr == NULL)
    {
      caf_attr_store = gfc_caf_attr (array_expr);
      caf_attr = &caf_attr_store;
    }

  res_var = lhs;
  dst_var = lhs;

  vec = null_pointer_node;
  tmp_stat = gfc_find_stat_co (expr);

  if (tmp_stat)
    {
      gfc_se stat_se;
      gfc_init_se (&stat_se, NULL);
      gfc_conv_expr_reference (&stat_se, tmp_stat);
      stat = stat_se.expr;
      gfc_add_block_to_block (&se->pre, &stat_se.pre);
      gfc_add_block_to_block (&se->post, &stat_se.post);
    }
  else
    stat = null_pointer_node;

  /* Only use the new get_by_ref () where it is necessary.  I.e., when the lhs
     is reallocatable or the right-hand side has allocatable components.  */
  if (caf_attr->alloc_comp || caf_attr->pointer_comp || may_realloc)
    {
      /* Get using caf_get_by_ref.  */
      caf_reference = conv_expr_ref_to_caf_ref (&se->pre, array_expr);

      if (caf_reference != NULL_TREE)
	{
	  if (lhs == NULL_TREE)
	    {
	      if (array_expr->ts.type == BT_CHARACTER)
		gfc_init_se (&argse, NULL);
	      if (array_expr->rank == 0)
		{
		  symbol_attribute attr;
		  gfc_clear_attr (&attr);
		  if (array_expr->ts.type == BT_CHARACTER)
		    {
		      res_var = gfc_conv_string_tmp (se,
						     build_pointer_type (type),
					     array_expr->ts.u.cl->backend_decl);
		      argse.string_length = array_expr->ts.u.cl->backend_decl;
		    }
		  else
		    res_var = gfc_create_var (type, "caf_res");
		  dst_var = gfc_conv_scalar_to_descriptor (se, res_var, attr);
		  dst_var = gfc_build_addr_expr (NULL_TREE, dst_var);
		}
	      else
		{
		  /* Create temporary.  */
		  if (array_expr->ts.type == BT_CHARACTER)
		    gfc_conv_expr_descriptor (&argse, array_expr);
		  may_realloc = gfc_trans_create_temp_array (&se->pre,
							     &se->post,
							     se->ss, type,
							     NULL_TREE, false,
							     false, false,
							     &array_expr->where)
		      == NULL_TREE;
		  res_var = se->ss->info->data.array.descriptor;
		  dst_var = gfc_build_addr_expr (NULL_TREE, res_var);
		  if (may_realloc)
		    {
		      tmp = gfc_conv_descriptor_data_get (res_var);
		      tmp = gfc_deallocate_with_status (tmp, NULL_TREE,
							NULL_TREE, NULL_TREE,
							NULL_TREE, true,
							NULL,
						     GFC_CAF_COARRAY_NOCOARRAY);
		      gfc_add_expr_to_block (&se->post, tmp);
		    }
		}
	    }

	  kind = build_int_cst (integer_type_node, expr->ts.kind);
	  if (lhs_kind == NULL_TREE)
	    lhs_kind = kind;

	  caf_decl = gfc_get_tree_for_caf_expr (array_expr);
	  if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
	    caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
	  image_index = gfc_caf_get_image_index (&se->pre, array_expr,
						 caf_decl);
	  gfc_get_caf_token_offset (se, &token, NULL, caf_decl, NULL,
				    array_expr);

	  /* No overlap possible as we have generated a temporary.  */
	  if (lhs == NULL_TREE)
	    may_require_tmp = boolean_false_node;

	  /* It guarantees memory consistency within the same segment.  */
	  tmp = gfc_build_string_const (strlen ("memory") + 1, "memory");
	  tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			    gfc_build_string_const (1, ""), NULL_TREE,
			    NULL_TREE, tree_cons (NULL_TREE, tmp, NULL_TREE),
			    NULL_TREE);
	  ASM_VOLATILE_P (tmp) = 1;
	  gfc_add_expr_to_block (&se->pre, tmp);

	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_get_by_ref,
				     10, token, image_index, dst_var,
				     caf_reference, lhs_kind, kind,
				     may_require_tmp,
				     may_realloc ? boolean_true_node :
						   boolean_false_node,
				     stat, build_int_cst (integer_type_node,
							  array_expr->ts.type));

	  gfc_add_expr_to_block (&se->pre, tmp);

	  if (se->ss)
	    gfc_advance_se_ss_chain (se);

	  se->expr = res_var;
	  if (array_expr->ts.type == BT_CHARACTER)
	    se->string_length = argse.string_length;

	  return;
	}
    }

  gfc_init_se (&argse, NULL);
  if (array_expr->rank == 0)
    {
      symbol_attribute attr;

      gfc_clear_attr (&attr);
      gfc_conv_expr (&argse, array_expr);

      if (lhs == NULL_TREE)
	{
	  gfc_clear_attr (&attr);
	  if (array_expr->ts.type == BT_CHARACTER)
	    res_var = gfc_conv_string_tmp (se, build_pointer_type (type),
					   argse.string_length);
	  else
	    res_var = gfc_create_var (type, "caf_res");
	  dst_var = gfc_conv_scalar_to_descriptor (&argse, res_var, attr);
	  dst_var = gfc_build_addr_expr (NULL_TREE, dst_var);
	}
      argse.expr = gfc_conv_scalar_to_descriptor (&argse, argse.expr, attr);
      argse.expr = gfc_build_addr_expr (NULL_TREE, argse.expr);
    }
  else
    {
      /* If has_vector, pass descriptor for whole array and the
         vector bounds separately.  */
      gfc_array_ref *ar, ar2;
      bool has_vector = false;

      if (gfc_is_coindexed (expr) && gfc_has_vector_subscript (expr))
	{
          has_vector = true;
          ar = gfc_find_array_ref (expr);
	  ar2 = *ar;
	  memset (ar, '\0', sizeof (*ar));
	  ar->as = ar2.as;
	  ar->type = AR_FULL;
	}
      // TODO: Check whether argse.want_coarray = 1 can help with the below.
      gfc_conv_expr_descriptor (&argse, array_expr);
      /* Using gfc_conv_expr_descriptor, we only get the descriptor, but that
	 has the wrong type if component references are done.  */
      gfc_add_modify (&argse.pre, gfc_conv_descriptor_dtype (argse.expr),
		      gfc_get_dtype_rank_type (has_vector ? ar2.dimen
							  : array_expr->rank,
					       type));
      if (has_vector)
	{
	  vec = conv_caf_vector_subscript (&argse.pre, argse.expr, &ar2);
	  *ar = ar2;
	}

      if (lhs == NULL_TREE)
	{
	  /* Create temporary.  */
	  for (int n = 0; n < se->ss->loop->dimen; n++)
	    if (se->loop->to[n] == NULL_TREE)
	      {
		se->loop->from[n] = gfc_conv_descriptor_lbound_get (argse.expr,
							       gfc_rank_cst[n]);
		se->loop->to[n] = gfc_conv_descriptor_ubound_get (argse.expr,
							       gfc_rank_cst[n]);
	      }
	  gfc_trans_create_temp_array (&argse.pre, &argse.post, se->ss, type,
				       NULL_TREE, false, true, false,
				       &array_expr->where);
	  res_var = se->ss->info->data.array.descriptor;
	  dst_var = gfc_build_addr_expr (NULL_TREE, res_var);
	}
      argse.expr = gfc_build_addr_expr (NULL_TREE, argse.expr);
    }

  kind = build_int_cst (integer_type_node, expr->ts.kind);
  if (lhs_kind == NULL_TREE)
    lhs_kind = kind;

  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);

  caf_decl = gfc_get_tree_for_caf_expr (array_expr);
  if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
    caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
  image_index = gfc_caf_get_image_index (&se->pre, array_expr, caf_decl);
  gfc_get_caf_token_offset (se, &token, &offset, caf_decl, argse.expr,
			    array_expr);

  /* No overlap possible as we have generated a temporary.  */
  if (lhs == NULL_TREE)
    may_require_tmp = boolean_false_node;

  /* It guarantees memory consistency within the same segment.  */
  tmp = gfc_build_string_const (strlen ("memory") + 1, "memory");
  tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
		    gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
		    tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
  ASM_VOLATILE_P (tmp) = 1;
  gfc_add_expr_to_block (&se->pre, tmp);

  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_get, 10,
			     token, offset, image_index, argse.expr, vec,
			     dst_var, kind, lhs_kind, may_require_tmp, stat);

  gfc_add_expr_to_block (&se->pre, tmp);

  if (se->ss)
    gfc_advance_se_ss_chain (se);

  se->expr = res_var;
  if (array_expr->ts.type == BT_CHARACTER)
    se->string_length = argse.string_length;
}


/* Send data to a remote coarray.  */

static tree
conv_caf_send (gfc_code *code) {
  gfc_expr *lhs_expr, *rhs_expr, *tmp_stat, *tmp_team;
  gfc_se lhs_se, rhs_se;
  stmtblock_t block;
  tree caf_decl, token, offset, image_index, tmp, lhs_kind, rhs_kind;
  tree may_require_tmp, src_stat, dst_stat, dst_team;
  tree lhs_type = NULL_TREE;
  tree vec = null_pointer_node, rhs_vec = null_pointer_node;
  symbol_attribute lhs_caf_attr, rhs_caf_attr;

  gcc_assert (flag_coarray == GFC_FCOARRAY_LIB);

  lhs_expr = code->ext.actual->expr;
  rhs_expr = code->ext.actual->next->expr;
  may_require_tmp = gfc_check_dependency (lhs_expr, rhs_expr, true) == 0
		    ? boolean_false_node : boolean_true_node;
  gfc_init_block (&block);

  lhs_caf_attr = gfc_caf_attr (lhs_expr);
  rhs_caf_attr = gfc_caf_attr (rhs_expr);
  src_stat = dst_stat = null_pointer_node;
  dst_team = null_pointer_node;

  /* LHS.  */
  gfc_init_se (&lhs_se, NULL);
  if (lhs_expr->rank == 0)
    {
      if (lhs_expr->ts.type == BT_CHARACTER && lhs_expr->ts.deferred)
	{
	  lhs_se.expr = gfc_get_tree_for_caf_expr (lhs_expr);
	  lhs_se.expr = gfc_build_addr_expr (NULL_TREE, lhs_se.expr);
	}
      else
	{
	  symbol_attribute attr;
	  gfc_clear_attr (&attr);
	  gfc_conv_expr (&lhs_se, lhs_expr);
	  lhs_type = TREE_TYPE (lhs_se.expr);
	  lhs_se.expr = gfc_conv_scalar_to_descriptor (&lhs_se, lhs_se.expr,
						       attr);
	  lhs_se.expr = gfc_build_addr_expr (NULL_TREE, lhs_se.expr);
	}
    }
  else if ((lhs_caf_attr.alloc_comp || lhs_caf_attr.pointer_comp)
	   && lhs_caf_attr.codimension)
    {
      lhs_se.want_pointer = 1;
      gfc_conv_expr_descriptor (&lhs_se, lhs_expr);
      /* Using gfc_conv_expr_descriptor, we only get the descriptor, but that
	 has the wrong type if component references are done.  */
      lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
      tmp = build_fold_indirect_ref_loc (input_location, lhs_se.expr);
      gfc_add_modify (&lhs_se.pre, gfc_conv_descriptor_dtype (tmp),
		      gfc_get_dtype_rank_type (
			gfc_has_vector_subscript (lhs_expr)
			? gfc_find_array_ref (lhs_expr)->dimen
			: lhs_expr->rank,
		      lhs_type));
    }
  else
    {
      bool has_vector = gfc_has_vector_subscript (lhs_expr);

      if (gfc_is_coindexed (lhs_expr) || !has_vector)
	{
	  /* If has_vector, pass descriptor for whole array and the
	     vector bounds separately.  */
	  gfc_array_ref *ar, ar2;
	  bool has_tmp_lhs_array = false;
	  if (has_vector)
	    {
	      has_tmp_lhs_array = true;
	      ar = gfc_find_array_ref (lhs_expr);
	      ar2 = *ar;
	      memset (ar, '\0', sizeof (*ar));
	      ar->as = ar2.as;
	      ar->type = AR_FULL;
	    }
	  lhs_se.want_pointer = 1;
	  gfc_conv_expr_descriptor (&lhs_se, lhs_expr);
	  /* Using gfc_conv_expr_descriptor, we only get the descriptor, but
	     that has the wrong type if component references are done.  */
	  lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
	  tmp = build_fold_indirect_ref_loc (input_location, lhs_se.expr);
	  gfc_add_modify (&lhs_se.pre, gfc_conv_descriptor_dtype (tmp),
			  gfc_get_dtype_rank_type (has_vector ? ar2.dimen
							      : lhs_expr->rank,
						   lhs_type));
	  if (has_tmp_lhs_array)
	    {
	      vec = conv_caf_vector_subscript (&block, lhs_se.expr, &ar2);
	      *ar = ar2;
	    }
	}
      else
	{
	  /* Special casing for arr1 ([...]) = arr2[...], i.e. caf_get to
	     indexed array expression.  This is rewritten to:

	     tmp_array = arr2[...]
	     arr1 ([...]) = tmp_array

	     because using the standard gfc_conv_expr (lhs_expr) did the
	     assignment with lhs and rhs exchanged.  */

	  gfc_ss *lss_for_tmparray, *lss_real;
	  gfc_loopinfo loop;
	  gfc_se se;
	  stmtblock_t body;
	  tree tmparr_desc, src;
	  tree index = gfc_index_zero_node;
	  tree stride = gfc_index_zero_node;
	  int n;

	  /* Walk both sides of the assignment, once to get the shape of the
	     temporary array to create right.  */
	  lss_for_tmparray = gfc_walk_expr (lhs_expr);
	  /* And a second time to be able to create an assignment of the
	     temporary to the lhs_expr.  gfc_trans_create_temp_array replaces
	     the tree in the descriptor with the one for the temporary
	     array.  */
	  lss_real = gfc_walk_expr (lhs_expr);
	  gfc_init_loopinfo (&loop);
	  gfc_add_ss_to_loop (&loop, lss_for_tmparray);
	  gfc_add_ss_to_loop (&loop, lss_real);
	  gfc_conv_ss_startstride (&loop);
	  gfc_conv_loop_setup (&loop, &lhs_expr->where);
	  lhs_type = gfc_typenode_for_spec (&lhs_expr->ts);
	  gfc_trans_create_temp_array (&lhs_se.pre, &lhs_se.post,
				       lss_for_tmparray, lhs_type, NULL_TREE,
				       false, true, false,
				       &lhs_expr->where);
	  tmparr_desc = lss_for_tmparray->info->data.array.descriptor;
	  gfc_start_scalarized_body (&loop, &body);
	  gfc_init_se (&se, NULL);
	  gfc_copy_loopinfo_to_se (&se, &loop);
	  se.ss = lss_real;
	  gfc_conv_expr (&se, lhs_expr);
	  gfc_add_block_to_block (&body, &se.pre);

	  /* Walk over all indexes of the loop.  */
	  for (n = loop.dimen - 1; n > 0; --n)
	    {
	      tmp = loop.loopvar[n];
	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
				     gfc_array_index_type, tmp, loop.from[n]);
	      tmp = fold_build2_loc (input_location, PLUS_EXPR,
				     gfc_array_index_type, tmp, index);

	      stride = fold_build2_loc (input_location, MINUS_EXPR,
					gfc_array_index_type,
					loop.to[n - 1], loop.from[n - 1]);
	      stride = fold_build2_loc (input_location, PLUS_EXPR,
					gfc_array_index_type,
					stride, gfc_index_one_node);

	      index = fold_build2_loc (input_location, MULT_EXPR,
				       gfc_array_index_type, tmp, stride);
	    }

	  index = fold_build2_loc (input_location, MINUS_EXPR,
				   gfc_array_index_type,
				   index, loop.from[0]);

	  index = fold_build2_loc (input_location, PLUS_EXPR,
				   gfc_array_index_type,
				   loop.loopvar[0], index);

	  src = build_fold_indirect_ref (gfc_conv_array_data (tmparr_desc));
	  src = gfc_build_array_ref (src, index, NULL);
	  /* Now create the assignment of lhs_expr = tmp_array.  */
	  gfc_add_modify (&body, se.expr, src);
	  gfc_add_block_to_block (&body, &se.post);
	  lhs_se.expr = gfc_build_addr_expr (NULL_TREE, tmparr_desc);
	  gfc_trans_scalarizing_loops (&loop, &body);
	  gfc_add_block_to_block (&loop.pre, &loop.post);
	  gfc_add_expr_to_block (&lhs_se.post, gfc_finish_block (&loop.pre));
	  gfc_free_ss (lss_for_tmparray);
	  gfc_free_ss (lss_real);
	}
    }

  lhs_kind = build_int_cst (integer_type_node, lhs_expr->ts.kind);

  /* Special case: RHS is a coarray but LHS is not; this code path avoids a
     temporary and a loop.  */
  if (!gfc_is_coindexed (lhs_expr)
      && (!lhs_caf_attr.codimension
	  || !(lhs_expr->rank > 0
	       && (lhs_caf_attr.allocatable || lhs_caf_attr.pointer))))
    {
      bool lhs_may_realloc = lhs_expr->rank > 0 && lhs_caf_attr.allocatable;
      gcc_assert (gfc_is_coindexed (rhs_expr));
      gfc_init_se (&rhs_se, NULL);
      if (lhs_expr->rank == 0 && lhs_caf_attr.allocatable)
	{
	  gfc_se scal_se;
	  gfc_init_se (&scal_se, NULL);
	  scal_se.want_pointer = 1;
	  gfc_conv_expr (&scal_se, lhs_expr);
	  /* Ensure scalar on lhs is allocated.  */
	  gfc_add_block_to_block (&block, &scal_se.pre);

	  gfc_allocate_using_malloc (&scal_se.pre, scal_se.expr,
				    TYPE_SIZE_UNIT (
				       gfc_typenode_for_spec (&lhs_expr->ts)),
				    NULL_TREE);
	  tmp = fold_build2 (EQ_EXPR, logical_type_node, scal_se.expr,
			     null_pointer_node);
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 tmp, gfc_finish_block (&scal_se.pre),
				 build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&block, tmp);
	}
      else
	lhs_may_realloc = lhs_may_realloc
	    && gfc_full_array_ref_p (lhs_expr->ref, NULL);
      gfc_add_block_to_block (&block, &lhs_se.pre);
      gfc_conv_intrinsic_caf_get (&rhs_se, rhs_expr, lhs_se.expr, lhs_kind,
				  may_require_tmp, lhs_may_realloc,
				  &rhs_caf_attr);
      gfc_add_block_to_block (&block, &rhs_se.pre);
      gfc_add_block_to_block (&block, &rhs_se.post);
      gfc_add_block_to_block (&block, &lhs_se.post);
      return gfc_finish_block (&block);
    }

  gfc_add_block_to_block (&block, &lhs_se.pre);

  /* Obtain token, offset and image index for the LHS.  */
  caf_decl = gfc_get_tree_for_caf_expr (lhs_expr);
  if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
    caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
  image_index = gfc_caf_get_image_index (&block, lhs_expr, caf_decl);
  tmp = lhs_se.expr;
  if (lhs_caf_attr.alloc_comp)
    gfc_get_caf_token_offset (&lhs_se, &token, NULL, caf_decl, NULL_TREE,
			      NULL);
  else
    gfc_get_caf_token_offset (&lhs_se, &token, &offset, caf_decl, tmp,
			      lhs_expr);
  lhs_se.expr = tmp;

  /* RHS.  */
  gfc_init_se (&rhs_se, NULL);
  if (rhs_expr->expr_type == EXPR_FUNCTION && rhs_expr->value.function.isym
      && rhs_expr->value.function.isym->id == GFC_ISYM_CONVERSION)
    rhs_expr = rhs_expr->value.function.actual->expr;
  if (rhs_expr->rank == 0)
    {
      symbol_attribute attr;
      gfc_clear_attr (&attr);
      gfc_conv_expr (&rhs_se, rhs_expr);
      rhs_se.expr = gfc_conv_scalar_to_descriptor (&rhs_se, rhs_se.expr, attr);
      rhs_se.expr = gfc_build_addr_expr (NULL_TREE, rhs_se.expr);
    }
  else if ((rhs_caf_attr.alloc_comp || rhs_caf_attr.pointer_comp)
	   && rhs_caf_attr.codimension)
    {
      tree tmp2;
      rhs_se.want_pointer = 1;
      gfc_conv_expr_descriptor (&rhs_se, rhs_expr);
      /* Using gfc_conv_expr_descriptor, we only get the descriptor, but that
	 has the wrong type if component references are done.  */
      tmp2 = gfc_typenode_for_spec (&rhs_expr->ts);
      tmp = build_fold_indirect_ref_loc (input_location, rhs_se.expr);
      gfc_add_modify (&rhs_se.pre, gfc_conv_descriptor_dtype (tmp),
		      gfc_get_dtype_rank_type (
			gfc_has_vector_subscript (rhs_expr)
			? gfc_find_array_ref (rhs_expr)->dimen
			: rhs_expr->rank,
		      tmp2));
    }
  else
    {
      /* If has_vector, pass descriptor for whole array and the
         vector bounds separately.  */
      gfc_array_ref *ar, ar2;
      bool has_vector = false;
      tree tmp2;

      if (gfc_is_coindexed (rhs_expr) && gfc_has_vector_subscript (rhs_expr))
	{
          has_vector = true;
          ar = gfc_find_array_ref (rhs_expr);
	  ar2 = *ar;
	  memset (ar, '\0', sizeof (*ar));
	  ar->as = ar2.as;
	  ar->type = AR_FULL;
	}
      rhs_se.want_pointer = 1;
      gfc_conv_expr_descriptor (&rhs_se, rhs_expr);
      /* Using gfc_conv_expr_descriptor, we only get the descriptor, but that
         has the wrong type if component references are done.  */
      tmp = build_fold_indirect_ref_loc (input_location, rhs_se.expr);
      tmp2 = gfc_typenode_for_spec (&rhs_expr->ts);
      gfc_add_modify (&rhs_se.pre, gfc_conv_descriptor_dtype (tmp),
                      gfc_get_dtype_rank_type (has_vector ? ar2.dimen
							  : rhs_expr->rank,
		      tmp2));
      if (has_vector)
	{
	  rhs_vec = conv_caf_vector_subscript (&block, rhs_se.expr, &ar2);
	  *ar = ar2;
	}
    }

  gfc_add_block_to_block (&block, &rhs_se.pre);

  rhs_kind = build_int_cst (integer_type_node, rhs_expr->ts.kind);

  tmp_stat = gfc_find_stat_co (lhs_expr);

  if (tmp_stat)
    {
      gfc_se stat_se;
      gfc_init_se (&stat_se, NULL);
      gfc_conv_expr_reference (&stat_se, tmp_stat);
      dst_stat = stat_se.expr;
      gfc_add_block_to_block (&block, &stat_se.pre);
      gfc_add_block_to_block (&block, &stat_se.post);
    }

  tmp_team = gfc_find_team_co (lhs_expr);

  if (tmp_team)
    {
      gfc_se team_se;
      gfc_init_se (&team_se, NULL);
      gfc_conv_expr_reference (&team_se, tmp_team);
      dst_team = team_se.expr;
      gfc_add_block_to_block (&block, &team_se.pre);
      gfc_add_block_to_block (&block, &team_se.post);
    }

  if (!gfc_is_coindexed (rhs_expr))
    {
      if (lhs_caf_attr.alloc_comp || lhs_caf_attr.pointer_comp)
	{
	  tree reference, dst_realloc;
	  reference = conv_expr_ref_to_caf_ref (&block, lhs_expr);
	  dst_realloc = lhs_caf_attr.allocatable ? boolean_true_node
					     : boolean_false_node;
	  tmp = build_call_expr_loc (input_location,
				     gfor_fndecl_caf_send_by_ref,
				     10, token, image_index, rhs_se.expr,
				     reference, lhs_kind, rhs_kind,
				     may_require_tmp, dst_realloc, src_stat,
				     build_int_cst (integer_type_node,
						    lhs_expr->ts.type));
	  }
      else
	tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_send, 11,
				   token, offset, image_index, lhs_se.expr, vec,
				   rhs_se.expr, lhs_kind, rhs_kind,
				   may_require_tmp, src_stat, dst_team);
    }
  else
    {
      tree rhs_token, rhs_offset, rhs_image_index;

      /* It guarantees memory consistency within the same segment.  */
      tmp = gfc_build_string_const (strlen ("memory") + 1, "memory");
      tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
			  gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
			  tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
      ASM_VOLATILE_P (tmp) = 1;
      gfc_add_expr_to_block (&block, tmp);

      caf_decl = gfc_get_tree_for_caf_expr (rhs_expr);
      if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
	caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
      rhs_image_index = gfc_caf_get_image_index (&block, rhs_expr, caf_decl);
      tmp = rhs_se.expr;
      if (rhs_caf_attr.alloc_comp || rhs_caf_attr.pointer_comp)
	{
	  tmp_stat = gfc_find_stat_co (lhs_expr);

	  if (tmp_stat)
	    {
	      gfc_se stat_se;
	      gfc_init_se (&stat_se, NULL);
	      gfc_conv_expr_reference (&stat_se, tmp_stat);
	      src_stat = stat_se.expr;
	      gfc_add_block_to_block (&block, &stat_se.pre);
	      gfc_add_block_to_block (&block, &stat_se.post);
	    }

	  gfc_get_caf_token_offset (&rhs_se, &rhs_token, NULL, caf_decl,
				    NULL_TREE, NULL);
	  tree lhs_reference, rhs_reference;
	  lhs_reference = conv_expr_ref_to_caf_ref (&block, lhs_expr);
	  rhs_reference = conv_expr_ref_to_caf_ref (&block, rhs_expr);
	  tmp = build_call_expr_loc (input_location,
				     gfor_fndecl_caf_sendget_by_ref, 13,
				     token, image_index, lhs_reference,
				     rhs_token, rhs_image_index, rhs_reference,
				     lhs_kind, rhs_kind, may_require_tmp,
				     dst_stat, src_stat,
				     build_int_cst (integer_type_node,
						    lhs_expr->ts.type),
				     build_int_cst (integer_type_node,
						    rhs_expr->ts.type));
	}
      else
	{
	  gfc_get_caf_token_offset (&rhs_se, &rhs_token, &rhs_offset, caf_decl,
				    tmp, rhs_expr);
	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sendget,
				     14, token, offset, image_index,
				     lhs_se.expr, vec, rhs_token, rhs_offset,
				     rhs_image_index, tmp, rhs_vec, lhs_kind,
				     rhs_kind, may_require_tmp, src_stat);
	}
    }
  gfc_add_expr_to_block (&block, tmp);
  gfc_add_block_to_block (&block, &lhs_se.post);
  gfc_add_block_to_block (&block, &rhs_se.post);

  /* It guarantees memory consistency within the same segment.  */
  tmp = gfc_build_string_const (strlen ("memory") + 1, "memory");
  tmp = build5_loc (input_location, ASM_EXPR, void_type_node,
		    gfc_build_string_const (1, ""), NULL_TREE, NULL_TREE,
		    tree_cons (NULL_TREE, tmp, NULL_TREE), NULL_TREE);
  ASM_VOLATILE_P (tmp) = 1;
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


static void
trans_this_image (gfc_se * se, gfc_expr *expr)
{
  stmtblock_t loop;
  tree type, desc, dim_arg, cond, tmp, m, loop_var, exit_label, min_var,
       lbound, ubound, extent, ml;
  gfc_se argse;
  int rank, corank;
  gfc_expr *distance = expr->value.function.actual->next->next->expr;

  if (expr->value.function.actual->expr
      && !gfc_is_coarray (expr->value.function.actual->expr))
    distance = expr->value.function.actual->expr;

  /* The case -fcoarray=single is handled elsewhere.  */
  gcc_assert (flag_coarray != GFC_FCOARRAY_SINGLE);

  /* Argument-free version: THIS_IMAGE().  */
  if (distance || expr->value.function.actual->expr == NULL)
    {
      if (distance)
	{
	  gfc_init_se (&argse, NULL);
	  gfc_conv_expr_val (&argse, distance);
	  gfc_add_block_to_block (&se->pre, &argse.pre);
	  gfc_add_block_to_block (&se->post, &argse.post);
	  tmp = fold_convert (integer_type_node, argse.expr);
	}
      else
	tmp = integer_zero_node;
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
				 tmp);
      se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
			       tmp);
      return;
    }

  /* Coarray-argument version: THIS_IMAGE(coarray [, dim]).  */

  type = gfc_get_int_type (gfc_default_integer_kind);
  corank = gfc_get_corank (expr->value.function.actual->expr);
  rank = expr->value.function.actual->expr->rank;

  /* Obtain the descriptor of the COARRAY.  */
  gfc_init_se (&argse, NULL);
  argse.want_coarray = 1;
  gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);
  desc = argse.expr;

  if (se->ss)
    {
      /* Create an implicit second parameter from the loop variable.  */
      gcc_assert (!expr->value.function.actual->next->expr);
      gcc_assert (corank > 0);
      gcc_assert (se->loop->dimen == 1);
      gcc_assert (se->ss->info->expr == expr);

      dim_arg = se->loop->loopvar[0];
      dim_arg = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, dim_arg,
				 build_int_cst (TREE_TYPE (dim_arg), 1));
      gfc_advance_se_ss_chain (se);
    }
  else
    {
      /* Use the passed DIM= argument.  */
      gcc_assert (expr->value.function.actual->next->expr);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_type (&argse, expr->value.function.actual->next->expr,
			  gfc_array_index_type);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      dim_arg = argse.expr;

      if (INTEGER_CST_P (dim_arg))
	{
	  if (wi::ltu_p (wi::to_wide (dim_arg), 1)
	      || wi::gtu_p (wi::to_wide (dim_arg),
			    GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))))
	    gfc_error ("%<dim%> argument of %s intrinsic at %L is not a valid "
		       "dimension index", expr->value.function.isym->name,
		       &expr->where);
	}
     else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
	{
	  dim_arg = gfc_evaluate_now (dim_arg, &se->pre);
	  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				  dim_arg,
				  build_int_cst (TREE_TYPE (dim_arg), 1));
	  tmp = gfc_rank_cst[GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))];
	  tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
				 dim_arg, tmp);
	  cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
				  logical_type_node, cond, tmp);
	  gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
			           gfc_msg_fault);
	}
    }

  /* Used algorithm; cf. Fortran 2008, C.10. Note, due to the scalarizer,
     one always has a dim_arg argument.

     m = this_image() - 1
     if (corank == 1)
       {
	 sub(1) = m + lcobound(corank)
	 return;
       }
     i = rank
     min_var = min (rank + corank - 2, rank + dim_arg - 1)
     for (;;)
       {
	 extent = gfc_extent(i)
	 ml = m
	 m  = m/extent
	 if (i >= min_var)
	   goto exit_label
	 i++
       }
     exit_label:
     sub(dim_arg) = (dim_arg < corank) ? ml - m*extent + lcobound(dim_arg)
				       : m + lcobound(corank)
  */

  /* this_image () - 1.  */
  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_this_image, 1,
			     integer_zero_node);
  tmp = fold_build2_loc (input_location, MINUS_EXPR, type,
			 fold_convert (type, tmp), build_int_cst (type, 1));
  if (corank == 1)
    {
      /* sub(1) = m + lcobound(corank).  */
      lbound = gfc_conv_descriptor_lbound_get (desc,
			build_int_cst (TREE_TYPE (gfc_array_index_type),
				       corank+rank-1));
      lbound = fold_convert (type, lbound);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp, lbound);

      se->expr = tmp;
      return;
    }

  m = gfc_create_var (type, NULL);
  ml = gfc_create_var (type, NULL);
  loop_var = gfc_create_var (integer_type_node, NULL);
  min_var = gfc_create_var (integer_type_node, NULL);

  /* m = this_image () - 1.  */
  gfc_add_modify (&se->pre, m, tmp);

  /* min_var = min (rank + corank-2, rank + dim_arg - 1).  */
  tmp = fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
			 fold_convert (integer_type_node, dim_arg),
			 build_int_cst (integer_type_node, rank - 1));
  tmp = fold_build2_loc (input_location, MIN_EXPR, integer_type_node,
			 build_int_cst (integer_type_node, rank + corank - 2),
			 tmp);
  gfc_add_modify (&se->pre, min_var, tmp);

  /* i = rank.  */
  tmp = build_int_cst (integer_type_node, rank);
  gfc_add_modify (&se->pre, loop_var, tmp);

  exit_label = gfc_build_label_decl (NULL_TREE);
  TREE_USED (exit_label) = 1;

  /* Loop body.  */
  gfc_init_block (&loop);

  /* ml = m.  */
  gfc_add_modify (&loop, ml, m);

  /* extent = ...  */
  lbound = gfc_conv_descriptor_lbound_get (desc, loop_var);
  ubound = gfc_conv_descriptor_ubound_get (desc, loop_var);
  extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);
  extent = fold_convert (type, extent);

  /* m = m/extent.  */
  gfc_add_modify (&loop, m,
		  fold_build2_loc (input_location, TRUNC_DIV_EXPR, type,
			  m, extent));

  /* Exit condition:  if (i >= min_var) goto exit_label.  */
  cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node, loop_var,
		  min_var);
  tmp = build1_v (GOTO_EXPR, exit_label);
  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
                         build_empty_stmt (input_location));
  gfc_add_expr_to_block (&loop, tmp);

  /* Increment loop variable: i++.  */
  gfc_add_modify (&loop, loop_var,
                  fold_build2_loc (input_location, PLUS_EXPR, integer_type_node,
				   loop_var,
				   build_int_cst (integer_type_node, 1)));

  /* Making the loop... actually loop!  */
  tmp = gfc_finish_block (&loop);
  tmp = build1_v (LOOP_EXPR, tmp);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* The exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&se->pre, tmp);

  /*  sub(co_dim) = (co_dim < corank) ? ml - m*extent + lcobound(dim_arg)
				      : m + lcobound(corank) */

  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node, dim_arg,
			  build_int_cst (TREE_TYPE (dim_arg), corank));

  lbound = gfc_conv_descriptor_lbound_get (desc,
		fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, dim_arg,
				 build_int_cst (TREE_TYPE (dim_arg), rank-1)));
  lbound = fold_convert (type, lbound);

  tmp = fold_build2_loc (input_location, MINUS_EXPR, type, ml,
			 fold_build2_loc (input_location, MULT_EXPR, type,
					  m, extent));
  tmp = fold_build2_loc (input_location, PLUS_EXPR, type, tmp, lbound);

  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond, tmp,
			      fold_build2_loc (input_location, PLUS_EXPR, type,
					       m, lbound));
}


/* Convert a call to image_status.  */

static void
conv_intrinsic_image_status (gfc_se *se, gfc_expr *expr)
{
  unsigned int num_args;
  tree *args, tmp;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);
  gfc_conv_intrinsic_function_args (se, expr, args, num_args);
  /* In args[0] the number of the image the status is desired for has to be
     given.  */

  if (flag_coarray == GFC_FCOARRAY_SINGLE)
    {
      tree arg;
      arg = gfc_evaluate_now (args[0], &se->pre);
      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			     fold_convert (integer_type_node, arg),
			     integer_one_node);
      tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node,
			     tmp, integer_zero_node,
			     build_int_cst (integer_type_node,
					    GFC_STAT_STOPPED_IMAGE));
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_image_status, 2,
			       args[0], build_int_cst (integer_type_node, -1));
  else
    gcc_unreachable ();

  se->expr = tmp;
}

static void
conv_intrinsic_team_number (gfc_se *se, gfc_expr *expr)
{
  unsigned int num_args;

  tree *args, tmp;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);
  gfc_conv_intrinsic_function_args (se, expr, args, num_args);

  if (flag_coarray ==
      GFC_FCOARRAY_SINGLE && expr->value.function.actual->expr)
    {
      tree arg;

      arg = gfc_evaluate_now (args[0], &se->pre);
      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
      			     fold_convert (integer_type_node, arg),
      			     integer_one_node);
      tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node,
      			     tmp, integer_zero_node,
      			     build_int_cst (integer_type_node,
      					    GFC_STAT_STOPPED_IMAGE));
    }
  else if (flag_coarray == GFC_FCOARRAY_SINGLE)
    {
      // the value -1 represents that no team has been created yet
      tmp = build_int_cst (integer_type_node, -1);
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB && expr->value.function.actual->expr)
    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_team_number, 1,
			       args[0], build_int_cst (integer_type_node, -1));
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_team_number, 1,
		integer_zero_node, build_int_cst (integer_type_node, -1));
  else
    gcc_unreachable ();

  se->expr = tmp;
}


static void
trans_image_index (gfc_se * se, gfc_expr *expr)
{
  tree num_images, cond, coindex, type, lbound, ubound, desc, subdesc,
       tmp, invalid_bound;
  gfc_se argse, subse;
  int rank, corank, codim;

  type = gfc_get_int_type (gfc_default_integer_kind);
  corank = gfc_get_corank (expr->value.function.actual->expr);
  rank = expr->value.function.actual->expr->rank;

  /* Obtain the descriptor of the COARRAY.  */
  gfc_init_se (&argse, NULL);
  argse.want_coarray = 1;
  gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);
  desc = argse.expr;

  /* Obtain a handle to the SUB argument.  */
  gfc_init_se (&subse, NULL);
  gfc_conv_expr_descriptor (&subse, expr->value.function.actual->next->expr);
  gfc_add_block_to_block (&se->pre, &subse.pre);
  gfc_add_block_to_block (&se->post, &subse.post);
  subdesc = build_fold_indirect_ref_loc (input_location,
			gfc_conv_descriptor_data_get (subse.expr));

  /* Fortran 2008 does not require that the values remain in the cobounds,
     thus we need explicitly check this - and return 0 if they are exceeded.  */

  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]);
  tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1], NULL);
  invalid_bound = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				 fold_convert (gfc_array_index_type, tmp),
				 lbound);

  for (codim = corank + rank - 2; codim >= rank; codim--)
    {
      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
      ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[codim]);
      tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], NULL);
      cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
			      fold_convert (gfc_array_index_type, tmp),
			      lbound);
      invalid_bound = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				       logical_type_node, invalid_bound, cond);
      cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			      fold_convert (gfc_array_index_type, tmp),
			      ubound);
      invalid_bound = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				       logical_type_node, invalid_bound, cond);
    }

  invalid_bound = gfc_unlikely (invalid_bound, PRED_FORTRAN_INVALID_BOUND);

  /* See Fortran 2008, C.10 for the following algorithm.  */

  /* coindex = sub(corank) - lcobound(n).  */
  coindex = fold_convert (gfc_array_index_type,
			  gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1],
					       NULL));
  lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]);
  coindex = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			     fold_convert (gfc_array_index_type, coindex),
			     lbound);

  for (codim = corank + rank - 2; codim >= rank; codim--)
    {
      tree extent, ubound;

      /* coindex = coindex*extent(codim) + sub(codim) - lcobound(codim).  */
      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
      ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[codim]);
      extent = gfc_conv_array_extent_dim (lbound, ubound, NULL);

      /* coindex *= extent.  */
      coindex = fold_build2_loc (input_location, MULT_EXPR,
				 gfc_array_index_type, coindex, extent);

      /* coindex += sub(codim).  */
      tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], NULL);
      coindex = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, coindex,
				 fold_convert (gfc_array_index_type, tmp));

      /* coindex -= lbound(codim).  */
      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]);
      coindex = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type, coindex, lbound);
    }

  coindex = fold_build2_loc (input_location, PLUS_EXPR, type,
			     fold_convert(type, coindex),
			     build_int_cst (type, 1));

  /* Return 0 if "coindex" exceeds num_images().  */

  if (flag_coarray == GFC_FCOARRAY_SINGLE)
    num_images = build_int_cst (type, 1);
  else
    {
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images, 2,
				 integer_zero_node,
				 build_int_cst (integer_type_node, -1));
      num_images = fold_convert (type, tmp);
    }

  tmp = gfc_create_var (type, NULL);
  gfc_add_modify (&se->pre, tmp, coindex);

  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node, tmp,
			  num_images);
  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node,
			  cond,
			  fold_convert (logical_type_node, invalid_bound));
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
			      build_int_cst (type, 0), tmp);
}

static void
trans_num_images (gfc_se * se, gfc_expr *expr)
{
  tree tmp, distance, failed;
  gfc_se argse;

  if (expr->value.function.actual->expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, expr->value.function.actual->expr);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      distance = fold_convert (integer_type_node, argse.expr);
    }
  else
    distance = integer_zero_node;

  if (expr->value.function.actual->next->expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, expr->value.function.actual->next->expr);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      failed = fold_convert (integer_type_node, argse.expr);
    }
  else
    failed = build_int_cst (integer_type_node, -1);
  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images, 2,
			     distance, failed);
  se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind), tmp);
}


static void
gfc_conv_intrinsic_rank (gfc_se *se, gfc_expr *expr)
{
  gfc_se argse;

  gfc_init_se (&argse, NULL);
  argse.data_not_needed = 1;
  argse.descriptor_only = 1;

  gfc_conv_expr_descriptor (&argse, expr->value.function.actual->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);

  se->expr = gfc_conv_descriptor_rank (argse.expr);
  se->expr = fold_convert (gfc_get_int_type (gfc_default_integer_kind),
			   se->expr);
}


static void
gfc_conv_intrinsic_is_contiguous (gfc_se * se, gfc_expr * expr)
{
  gfc_expr *arg;
  gfc_ss *ss;
  gfc_se argse;
  tree desc, tmp, stride, extent, cond;
  int i;
  tree fncall0;
  gfc_array_spec *as;

  arg = expr->value.function.actual->expr;

  if (arg->ts.type == BT_CLASS)
    gfc_add_class_array_ref (arg);

  ss = gfc_walk_expr (arg);
  gcc_assert (ss != gfc_ss_terminator);
  gfc_init_se (&argse, NULL);
  argse.data_not_needed = 1;
  gfc_conv_expr_descriptor (&argse, arg);

  as = gfc_get_full_arrayspec_from_expr (arg);

  /* Create:  stride[0] == 1 && stride[1] == extend[0]*stride[0] && ...
     Note in addition that zero-sized arrays don't count as contiguous.  */

  if (as && as->type == AS_ASSUMED_RANK)
    {
      /* Build the call to is_contiguous0.  */
      argse.want_pointer = 1;
      gfc_conv_expr_descriptor (&argse, arg);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      desc = gfc_evaluate_now (argse.expr, &se->pre);
      fncall0 = build_call_expr_loc (input_location,
				     gfor_fndecl_is_contiguous0, 1, desc);
      se->expr = fncall0;
      se->expr = convert (logical_type_node, se->expr);
    }
  else
    {
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      desc = gfc_evaluate_now (argse.expr, &se->pre);

      stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[0]);
      cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
			      stride, build_int_cst (TREE_TYPE (stride), 1));

      for (i = 0; i < expr->value.function.actual->expr->rank - 1; i++)
	{
	  tmp = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
	  extent = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
	  extent = fold_build2_loc (input_location, MINUS_EXPR,
				    gfc_array_index_type, extent, tmp);
	  extent = fold_build2_loc (input_location, PLUS_EXPR,
				    gfc_array_index_type, extent,
				    gfc_index_one_node);
	  tmp = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[i]);
	  tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp),
				 tmp, extent);
	  stride = gfc_conv_descriptor_stride_get (desc, gfc_rank_cst[i+1]);
	  tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node,
				 stride, tmp);
	  cond = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				  boolean_type_node, cond, tmp);
	}
      se->expr = convert (gfc_typenode_for_spec (&expr->ts), cond);
    }
}


/* Evaluate a single upper or lower bound.  */
/* TODO: bound intrinsic generates way too much unnecessary code.  */

static void
gfc_conv_intrinsic_bound (gfc_se * se, gfc_expr * expr, int upper)
{
  gfc_actual_arglist *arg;
  gfc_actual_arglist *arg2;
  tree desc;
  tree type;
  tree bound;
  tree tmp;
  tree cond, cond1, cond3, cond4, size;
  tree ubound;
  tree lbound;
  gfc_se argse;
  gfc_array_spec * as;
  bool assumed_rank_lb_one;

  arg = expr->value.function.actual;
  arg2 = arg->next;

  if (se->ss)
    {
      /* Create an implicit second parameter from the loop variable.  */
      gcc_assert (!arg2->expr);
      gcc_assert (se->loop->dimen == 1);
      gcc_assert (se->ss->info->expr == expr);
      gfc_advance_se_ss_chain (se);
      bound = se->loop->loopvar[0];
      bound = fold_build2_loc (input_location, MINUS_EXPR,
			       gfc_array_index_type, bound,
			       se->loop->from[0]);
    }
  else
    {
      /* use the passed argument.  */
      gcc_assert (arg2->expr);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      bound = argse.expr;
      /* Convert from one based to zero based.  */
      bound = fold_build2_loc (input_location, MINUS_EXPR,
			       gfc_array_index_type, bound,
			       gfc_index_one_node);
    }

  /* TODO: don't re-evaluate the descriptor on each iteration.  */
  /* Get a descriptor for the first parameter.  */
  gfc_init_se (&argse, NULL);
  gfc_conv_expr_descriptor (&argse, arg->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);

  desc = argse.expr;

  as = gfc_get_full_arrayspec_from_expr (arg->expr);

  if (INTEGER_CST_P (bound))
    {
      if (((!as || as->type != AS_ASSUMED_RANK)
	   && wi::geu_p (wi::to_wide (bound),
			 GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))))
	  || wi::gtu_p (wi::to_wide (bound), GFC_MAX_DIMENSIONS))
	gfc_error ("%<dim%> argument of %s intrinsic at %L is not a valid "
		   "dimension index", upper ? "UBOUND" : "LBOUND",
		   &expr->where);
    }

  if (!INTEGER_CST_P (bound) || (as && as->type == AS_ASSUMED_RANK))
    {
      if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
        {
          bound = gfc_evaluate_now (bound, &se->pre);
          cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				  bound, build_int_cst (TREE_TYPE (bound), 0));
	  if (as && as->type == AS_ASSUMED_RANK)
	    tmp = gfc_conv_descriptor_rank (desc);
	  else
	    tmp = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (TREE_TYPE (desc))];
          tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
				 bound, fold_convert(TREE_TYPE (bound), tmp));
          cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
				  logical_type_node, cond, tmp);
          gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
				   gfc_msg_fault);
        }
    }

  /* Take care of the lbound shift for assumed-rank arrays, which are
     nonallocatable and nonpointers. Those has a lbound of 1.  */
  assumed_rank_lb_one = as && as->type == AS_ASSUMED_RANK
			&& ((arg->expr->ts.type != BT_CLASS
			     && !arg->expr->symtree->n.sym->attr.allocatable
			     && !arg->expr->symtree->n.sym->attr.pointer)
			    || (arg->expr->ts.type == BT_CLASS
			     && !CLASS_DATA (arg->expr)->attr.allocatable
			     && !CLASS_DATA (arg->expr)->attr.class_pointer));

  ubound = gfc_conv_descriptor_ubound_get (desc, bound);
  lbound = gfc_conv_descriptor_lbound_get (desc, bound);

  /* 13.14.53: Result value for LBOUND

     Case (i): For an array section or for an array expression other than a
               whole array or array structure component, LBOUND(ARRAY, DIM)
               has the value 1.  For a whole array or array structure
               component, LBOUND(ARRAY, DIM) has the value:
                 (a) equal to the lower bound for subscript DIM of ARRAY if
                     dimension DIM of ARRAY does not have extent zero
                     or if ARRAY is an assumed-size array of rank DIM,
              or (b) 1 otherwise.

     13.14.113: Result value for UBOUND

     Case (i): For an array section or for an array expression other than a
               whole array or array structure component, UBOUND(ARRAY, DIM)
               has the value equal to the number of elements in the given
               dimension; otherwise, it has a value equal to the upper bound
               for subscript DIM of ARRAY if dimension DIM of ARRAY does
               not have size zero and has value zero if dimension DIM has
               size zero.  */

  if (!upper && assumed_rank_lb_one)
    se->expr = gfc_index_one_node;
  else if (as)
    {
      tree stride = gfc_conv_descriptor_stride_get (desc, bound);

      cond1 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
			       ubound, lbound);
      cond3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
			       stride, gfc_index_zero_node);
      cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
			       logical_type_node, cond3, cond1);
      cond4 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
			       stride, gfc_index_zero_node);

      if (upper)
	{
	  tree cond5;
	  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				  logical_type_node, cond3, cond4);
	  cond5 = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				   gfc_index_one_node, lbound);
	  cond5 = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				   logical_type_node, cond4, cond5);

	  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				  logical_type_node, cond, cond5);

	  if (assumed_rank_lb_one)
	    {
	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
			       gfc_array_index_type, ubound, lbound);
	      tmp = fold_build2_loc (input_location, PLUS_EXPR,
			       gfc_array_index_type, tmp, gfc_index_one_node);
	    }
          else
            tmp = ubound;

	  se->expr = fold_build3_loc (input_location, COND_EXPR,
				      gfc_array_index_type, cond,
				      tmp, gfc_index_zero_node);
	}
      else
	{
	  if (as->type == AS_ASSUMED_SIZE)
	    cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				    bound, build_int_cst (TREE_TYPE (bound),
							  arg->expr->rank - 1));
	  else
	    cond = logical_false_node;

	  cond1 = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				   logical_type_node, cond3, cond4);
	  cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
				  logical_type_node, cond, cond1);

	  se->expr = fold_build3_loc (input_location, COND_EXPR,
				      gfc_array_index_type, cond,
				      lbound, gfc_index_one_node);
	}
    }
  else
    {
      if (upper)
        {
	  size = fold_build2_loc (input_location, MINUS_EXPR,
				  gfc_array_index_type, ubound, lbound);
	  se->expr = fold_build2_loc (input_location, PLUS_EXPR,
				      gfc_array_index_type, size,
				  gfc_index_one_node);
	  se->expr = fold_build2_loc (input_location, MAX_EXPR,
				      gfc_array_index_type, se->expr,
				      gfc_index_zero_node);
	}
      else
	se->expr = gfc_index_one_node;
    }

  /* According to F2018 16.9.172, para 5, an assumed rank object, argument
     associated with and assumed size array, has the ubound of the final
     dimension set to -1 and UBOUND must return this.  */
  if (upper && as && as->type == AS_ASSUMED_RANK)
    {
      tree minus_one = build_int_cst (gfc_array_index_type, -1);
      tree rank = fold_convert (gfc_array_index_type,
				gfc_conv_descriptor_rank (desc));
      rank = fold_build2_loc (input_location, PLUS_EXPR,
			      gfc_array_index_type, rank, minus_one);
      /* Fix the expression to stop it from becoming even more complicated.  */
      se->expr = gfc_evaluate_now (se->expr, &se->pre);
      cond = fold_build2_loc (input_location, NE_EXPR,
			     logical_type_node, bound, rank);
      cond1 = fold_build2_loc (input_location, NE_EXPR,
			       logical_type_node, ubound, minus_one);
      cond = fold_build2_loc (input_location, TRUTH_OR_EXPR,
			      logical_type_node, cond, cond1);
      se->expr = fold_build3_loc (input_location, COND_EXPR,
				  gfc_array_index_type, cond,
				  se->expr, minus_one);
    }

  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = convert (type, se->expr);
}


static void
conv_intrinsic_cobound (gfc_se * se, gfc_expr * expr)
{
  gfc_actual_arglist *arg;
  gfc_actual_arglist *arg2;
  gfc_se argse;
  tree bound, resbound, resbound2, desc, cond, tmp;
  tree type;
  int corank;

  gcc_assert (expr->value.function.isym->id == GFC_ISYM_LCOBOUND
	      || expr->value.function.isym->id == GFC_ISYM_UCOBOUND
	      || expr->value.function.isym->id == GFC_ISYM_THIS_IMAGE);

  arg = expr->value.function.actual;
  arg2 = arg->next;

  gcc_assert (arg->expr->expr_type == EXPR_VARIABLE);
  corank = gfc_get_corank (arg->expr);

  gfc_init_se (&argse, NULL);
  argse.want_coarray = 1;

  gfc_conv_expr_descriptor (&argse, arg->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);
  desc = argse.expr;

  if (se->ss)
    {
      /* Create an implicit second parameter from the loop variable.  */
      gcc_assert (!arg2->expr);
      gcc_assert (corank > 0);
      gcc_assert (se->loop->dimen == 1);
      gcc_assert (se->ss->info->expr == expr);

      bound = se->loop->loopvar[0];
      bound = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			       bound, gfc_rank_cst[arg->expr->rank]);
      gfc_advance_se_ss_chain (se);
    }
  else
    {
      /* use the passed argument.  */
      gcc_assert (arg2->expr);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_type (&argse, arg2->expr, gfc_array_index_type);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      bound = argse.expr;

      if (INTEGER_CST_P (bound))
	{
	  if (wi::ltu_p (wi::to_wide (bound), 1)
	      || wi::gtu_p (wi::to_wide (bound),
			    GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))))
	    gfc_error ("%<dim%> argument of %s intrinsic at %L is not a valid "
		       "dimension index", expr->value.function.isym->name,
		       &expr->where);
	}
      else if (gfc_option.rtcheck & GFC_RTCHECK_BOUNDS)
        {
	  bound = gfc_evaluate_now (bound, &se->pre);
	  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				  bound, build_int_cst (TREE_TYPE (bound), 1));
	  tmp = gfc_rank_cst[GFC_TYPE_ARRAY_CORANK (TREE_TYPE (desc))];
	  tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
				 bound, tmp);
	  cond = fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
				  logical_type_node, cond, tmp);
	  gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
				   gfc_msg_fault);
	}


      /* Subtract 1 to get to zero based and add dimensions.  */
      switch (arg->expr->rank)
	{
	case 0:
	  bound = fold_build2_loc (input_location, MINUS_EXPR,
				   gfc_array_index_type, bound,
				   gfc_index_one_node);
	case 1:
	  break;
	default:
	  bound = fold_build2_loc (input_location, PLUS_EXPR,
				   gfc_array_index_type, bound,
				   gfc_rank_cst[arg->expr->rank - 1]);
	}
    }

  resbound = gfc_conv_descriptor_lbound_get (desc, bound);

  /* Handle UCOBOUND with special handling of the last codimension.  */
  if (expr->value.function.isym->id == GFC_ISYM_UCOBOUND)
    {
      /* Last codimension: For -fcoarray=single just return
	 the lcobound - otherwise add
	   ceiling (real (num_images ()) / real (size)) - 1
	 = (num_images () + size - 1) / size - 1
	 = (num_images - 1) / size(),
         where size is the product of the extent of all but the last
	 codimension.  */

      if (flag_coarray != GFC_FCOARRAY_SINGLE && corank > 1)
	{
          tree cosize;

	  cosize = gfc_conv_descriptor_cosize (desc, arg->expr->rank, corank);
	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
				     2, integer_zero_node,
				     build_int_cst (integer_type_node, -1));
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type,
				 fold_convert (gfc_array_index_type, tmp),
				 build_int_cst (gfc_array_index_type, 1));
	  tmp = fold_build2_loc (input_location, TRUNC_DIV_EXPR,
				 gfc_array_index_type, tmp,
				 fold_convert (gfc_array_index_type, cosize));
	  resbound = fold_build2_loc (input_location, PLUS_EXPR,
				      gfc_array_index_type, resbound, tmp);
	}
      else if (flag_coarray != GFC_FCOARRAY_SINGLE)
	{
	  /* ubound = lbound + num_images() - 1.  */
	  tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_num_images,
				     2, integer_zero_node,
				     build_int_cst (integer_type_node, -1));
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type,
				 fold_convert (gfc_array_index_type, tmp),
				 build_int_cst (gfc_array_index_type, 1));
	  resbound = fold_build2_loc (input_location, PLUS_EXPR,
				      gfc_array_index_type, resbound, tmp);
	}

      if (corank > 1)
	{
	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				  bound,
				  build_int_cst (TREE_TYPE (bound),
						 arg->expr->rank + corank - 1));

	  resbound2 = gfc_conv_descriptor_ubound_get (desc, bound);
	  se->expr = fold_build3_loc (input_location, COND_EXPR,
				      gfc_array_index_type, cond,
				      resbound, resbound2);
	}
      else
	se->expr = resbound;
    }
  else
    se->expr = resbound;

  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = convert (type, se->expr);
}


static void
conv_intrinsic_stride (gfc_se * se, gfc_expr * expr)
{
  gfc_actual_arglist *array_arg;
  gfc_actual_arglist *dim_arg;
  gfc_se argse;
  tree desc, tmp;

  array_arg = expr->value.function.actual;
  dim_arg = array_arg->next;

  gcc_assert (array_arg->expr->expr_type == EXPR_VARIABLE);

  gfc_init_se (&argse, NULL);
  gfc_conv_expr_descriptor (&argse, array_arg->expr);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);
  desc = argse.expr;

  gcc_assert (dim_arg->expr);
  gfc_init_se (&argse, NULL);
  gfc_conv_expr_type (&argse, dim_arg->expr, gfc_array_index_type);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			 argse.expr, gfc_index_one_node);
  se->expr = gfc_conv_descriptor_stride_get (desc, tmp);
}

static void
gfc_conv_intrinsic_abs (gfc_se * se, gfc_expr * expr)
{
  tree arg, cabs;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);

  switch (expr->value.function.actual->expr->ts.type)
    {
    case BT_INTEGER:
    case BT_REAL:
      se->expr = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (arg),
				  arg);
      break;

    case BT_COMPLEX:
      cabs = gfc_builtin_decl_for_float_kind (BUILT_IN_CABS, expr->ts.kind);
      se->expr = build_call_expr_loc (input_location, cabs, 1, arg);
      break;

    default:
      gcc_unreachable ();
    }
}


/* Create a complex value from one or two real components.  */

static void
gfc_conv_intrinsic_cmplx (gfc_se * se, gfc_expr * expr, int both)
{
  tree real;
  tree imag;
  tree type;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, args, num_args);
  real = convert (TREE_TYPE (type), args[0]);
  if (both)
    imag = convert (TREE_TYPE (type), args[1]);
  else if (TREE_CODE (TREE_TYPE (args[0])) == COMPLEX_TYPE)
    {
      imag = fold_build1_loc (input_location, IMAGPART_EXPR,
			      TREE_TYPE (TREE_TYPE (args[0])), args[0]);
      imag = convert (TREE_TYPE (type), imag);
    }
  else
    imag = build_real_from_int_cst (TREE_TYPE (type), integer_zero_node);

  se->expr = fold_build2_loc (input_location, COMPLEX_EXPR, type, real, imag);
}


/* Remainder function MOD(A, P) = A - INT(A / P) * P
                      MODULO(A, P) = A - FLOOR (A / P) * P

   The obvious algorithms above are numerically instable for large
   arguments, hence these intrinsics are instead implemented via calls
   to the fmod family of functions.  It is the responsibility of the
   user to ensure that the second argument is non-zero.  */

static void
gfc_conv_intrinsic_mod (gfc_se * se, gfc_expr * expr, int modulo)
{
  tree type;
  tree tmp;
  tree test;
  tree test2;
  tree fmod;
  tree zero;
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  switch (expr->ts.type)
    {
    case BT_INTEGER:
      /* Integer case is easy, we've got a builtin op.  */
      type = TREE_TYPE (args[0]);

      if (modulo)
       se->expr = fold_build2_loc (input_location, FLOOR_MOD_EXPR, type,
				   args[0], args[1]);
      else
       se->expr = fold_build2_loc (input_location, TRUNC_MOD_EXPR, type,
				   args[0], args[1]);
      break;

    case BT_REAL:
      fmod = NULL_TREE;
      /* Check if we have a builtin fmod.  */
      fmod = gfc_builtin_decl_for_float_kind (BUILT_IN_FMOD, expr->ts.kind);

      /* The builtin should always be available.  */
      gcc_assert (fmod != NULL_TREE);

      tmp = build_addr (fmod);
      se->expr = build_call_array_loc (input_location,
				       TREE_TYPE (TREE_TYPE (fmod)),
                                       tmp, 2, args);
      if (modulo == 0)
	return;

      type = TREE_TYPE (args[0]);

      args[0] = gfc_evaluate_now (args[0], &se->pre);
      args[1] = gfc_evaluate_now (args[1], &se->pre);

      /* Definition:
	 modulo = arg - floor (arg/arg2) * arg2

	 In order to calculate the result accurately, we use the fmod
	 function as follows.

	 res = fmod (arg, arg2);
	 if (res)
	   {
	     if ((arg < 0) xor (arg2 < 0))
	       res += arg2;
	   }
	 else
	   res = copysign (0., arg2);

	 => As two nested ternary exprs:

	 res = res ? (((arg < 0) xor (arg2 < 0)) ? res + arg2 : res)
	       : copysign (0., arg2);

      */

      zero = gfc_build_const (type, integer_zero_node);
      tmp = gfc_evaluate_now (se->expr, &se->pre);
      if (!flag_signed_zeros)
	{
	  test = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				  args[0], zero);
	  test2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				   args[1], zero);
	  test2 = fold_build2_loc (input_location, TRUTH_XOR_EXPR,
				   logical_type_node, test, test2);
	  test = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				  tmp, zero);
	  test = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				  logical_type_node, test, test2);
	  test = gfc_evaluate_now (test, &se->pre);
	  se->expr = fold_build3_loc (input_location, COND_EXPR, type, test,
				      fold_build2_loc (input_location,
						       PLUS_EXPR,
						       type, tmp, args[1]),
				      tmp);
	}
      else
	{
	  tree expr1, copysign, cscall;
	  copysign = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN,
						      expr->ts.kind);
	  test = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				  args[0], zero);
	  test2 = fold_build2_loc (input_location, LT_EXPR, logical_type_node,
				   args[1], zero);
	  test2 = fold_build2_loc (input_location, TRUTH_XOR_EXPR,
				   logical_type_node, test, test2);
	  expr1 = fold_build3_loc (input_location, COND_EXPR, type, test2,
				   fold_build2_loc (input_location,
						    PLUS_EXPR,
						    type, tmp, args[1]),
				   tmp);
	  test = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				  tmp, zero);
	  cscall = build_call_expr_loc (input_location, copysign, 2, zero,
					args[1]);
	  se->expr = fold_build3_loc (input_location, COND_EXPR, type, test,
				      expr1, cscall);
	}
      return;

    default:
      gcc_unreachable ();
    }
}

/* DSHIFTL(I,J,S) = (I << S) | (J >> (BITSIZE(J) - S))
   DSHIFTR(I,J,S) = (I << (BITSIZE(I) - S)) | (J >> S)
   where the right shifts are logical (i.e. 0's are shifted in).
   Because SHIFT_EXPR's want shifts strictly smaller than the integral
   type width, we have to special-case both S == 0 and S == BITSIZE(J):
     DSHIFTL(I,J,0) = I
     DSHIFTL(I,J,BITSIZE) = J
     DSHIFTR(I,J,0) = J
     DSHIFTR(I,J,BITSIZE) = I.  */

static void
gfc_conv_intrinsic_dshift (gfc_se * se, gfc_expr * expr, bool dshiftl)
{
  tree type, utype, stype, arg1, arg2, shift, res, left, right;
  tree args[3], cond, tmp;
  int bitsize;

  gfc_conv_intrinsic_function_args (se, expr, args, 3);

  gcc_assert (TREE_TYPE (args[0]) == TREE_TYPE (args[1]));
  type = TREE_TYPE (args[0]);
  bitsize = TYPE_PRECISION (type);
  utype = unsigned_type_for (type);
  stype = TREE_TYPE (args[2]);

  arg1 = gfc_evaluate_now (args[0], &se->pre);
  arg2 = gfc_evaluate_now (args[1], &se->pre);
  shift = gfc_evaluate_now (args[2], &se->pre);

  /* The generic case.  */
  tmp = fold_build2_loc (input_location, MINUS_EXPR, stype,
			 build_int_cst (stype, bitsize), shift);
  left = fold_build2_loc (input_location, LSHIFT_EXPR, type,
			  arg1, dshiftl ? shift : tmp);

  right = fold_build2_loc (input_location, RSHIFT_EXPR, utype,
			   fold_convert (utype, arg2), dshiftl ? tmp : shift);
  right = fold_convert (type, right);

  res = fold_build2_loc (input_location, BIT_IOR_EXPR, type, left, right);

  /* Special cases.  */
  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, shift,
			  build_int_cst (stype, 0));
  res = fold_build3_loc (input_location, COND_EXPR, type, cond,
			 dshiftl ? arg1 : arg2, res);

  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, shift,
			  build_int_cst (stype, bitsize));
  res = fold_build3_loc (input_location, COND_EXPR, type, cond,
			 dshiftl ? arg2 : arg1, res);

  se->expr = res;
}


/* Positive difference DIM (x, y) = ((x - y) < 0) ? 0 : x - y.  */

static void
gfc_conv_intrinsic_dim (gfc_se * se, gfc_expr * expr)
{
  tree val;
  tree tmp;
  tree type;
  tree zero;
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  type = TREE_TYPE (args[0]);

  val = fold_build2_loc (input_location, MINUS_EXPR, type, args[0], args[1]);
  val = gfc_evaluate_now (val, &se->pre);

  zero = gfc_build_const (type, integer_zero_node);
  tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node, val, zero);
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, zero, val);
}


/* SIGN(A, B) is absolute value of A times sign of B.
   The real value versions use library functions to ensure the correct
   handling of negative zero.  Integer case implemented as:
   SIGN(A, B) = { tmp = (A ^ B) >> C; (A + tmp) ^ tmp }
  */

static void
gfc_conv_intrinsic_sign (gfc_se * se, gfc_expr * expr)
{
  tree tmp;
  tree type;
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  if (expr->ts.type == BT_REAL)
    {
      tree abs;

      tmp = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);
      abs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);

      /* We explicitly have to ignore the minus sign. We do so by using
	 result = (arg1 == 0) ? abs(arg0) : copysign(arg0, arg1).  */
      if (!flag_sign_zero
	  && MODE_HAS_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (args[1]))))
	{
	  tree cond, zero;
	  zero = build_real_from_int_cst (TREE_TYPE (args[1]), integer_zero_node);
	  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				  args[1], zero);
	  se->expr = fold_build3_loc (input_location, COND_EXPR,
				  TREE_TYPE (args[0]), cond,
				  build_call_expr_loc (input_location, abs, 1,
						       args[0]),
				  build_call_expr_loc (input_location, tmp, 2,
						       args[0], args[1]));
	}
      else
        se->expr = build_call_expr_loc (input_location, tmp, 2,
					args[0], args[1]);
      return;
    }

  /* Having excluded floating point types, we know we are now dealing
     with signed integer types.  */
  type = TREE_TYPE (args[0]);

  /* Args[0] is used multiple times below.  */
  args[0] = gfc_evaluate_now (args[0], &se->pre);

  /* Construct (A ^ B) >> 31, which generates a bit mask of all zeros if
     the signs of A and B are the same, and of all ones if they differ.  */
  tmp = fold_build2_loc (input_location, BIT_XOR_EXPR, type, args[0], args[1]);
  tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, tmp,
			 build_int_cst (type, TYPE_PRECISION (type) - 1));
  tmp = gfc_evaluate_now (tmp, &se->pre);

  /* Construct (A + tmp) ^ tmp, which is A if tmp is zero, and -A if tmp]
     is all ones (i.e. -1).  */
  se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, type,
			      fold_build2_loc (input_location, PLUS_EXPR,
					       type, args[0], tmp), tmp);
}


/* Test for the presence of an optional argument.  */

static void
gfc_conv_intrinsic_present (gfc_se * se, gfc_expr * expr)
{
  gfc_expr *arg;

  arg = expr->value.function.actual->expr;
  gcc_assert (arg->expr_type == EXPR_VARIABLE);
  se->expr = gfc_conv_expr_present (arg->symtree->n.sym);
  se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Calculate the double precision product of two single precision values.  */

static void
gfc_conv_intrinsic_dprod (gfc_se * se, gfc_expr * expr)
{
  tree type;
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  /* Convert the args to double precision before multiplying.  */
  type = gfc_typenode_for_spec (&expr->ts);
  args[0] = convert (type, args[0]);
  args[1] = convert (type, args[1]);
  se->expr = fold_build2_loc (input_location, MULT_EXPR, type, args[0],
			      args[1]);
}


/* Return a length one character string containing an ascii character.  */

static void
gfc_conv_intrinsic_char (gfc_se * se, gfc_expr * expr)
{
  tree arg[2];
  tree var;
  tree type;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr);
  gfc_conv_intrinsic_function_args (se, expr, arg, num_args);

  type = gfc_get_char_type (expr->ts.kind);
  var = gfc_create_var (type, "char");

  arg[0] = fold_build1_loc (input_location, NOP_EXPR, type, arg[0]);
  gfc_add_modify (&se->pre, var, arg[0]);
  se->expr = gfc_build_addr_expr (build_pointer_type (type), var);
  se->string_length = build_int_cst (gfc_charlen_type_node, 1);
}


static void
gfc_conv_intrinsic_ctime (gfc_se * se, gfc_expr * expr)
{
  tree var;
  tree len;
  tree tmp;
  tree cond;
  tree fndecl;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr) + 2;
  args = XALLOCAVEC (tree, num_args);

  var = gfc_create_var (pchar_type_node, "pstr");
  len = gfc_create_var (gfc_charlen_type_node, "len");

  gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
  args[0] = gfc_build_addr_expr (NULL_TREE, var);
  args[1] = gfc_build_addr_expr (NULL_TREE, len);

  fndecl = build_addr (gfor_fndecl_ctime);
  tmp = build_call_array_loc (input_location,
			  TREE_TYPE (TREE_TYPE (gfor_fndecl_ctime)),
			  fndecl, num_args, args);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Free the temporary afterwards, if necessary.  */
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  len, build_int_cst (TREE_TYPE (len), 0));
  tmp = gfc_call_free (var);
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->post, tmp);

  se->expr = var;
  se->string_length = len;
}


static void
gfc_conv_intrinsic_fdate (gfc_se * se, gfc_expr * expr)
{
  tree var;
  tree len;
  tree tmp;
  tree cond;
  tree fndecl;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr) + 2;
  args = XALLOCAVEC (tree, num_args);

  var = gfc_create_var (pchar_type_node, "pstr");
  len = gfc_create_var (gfc_charlen_type_node, "len");

  gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
  args[0] = gfc_build_addr_expr (NULL_TREE, var);
  args[1] = gfc_build_addr_expr (NULL_TREE, len);

  fndecl = build_addr (gfor_fndecl_fdate);
  tmp = build_call_array_loc (input_location,
			  TREE_TYPE (TREE_TYPE (gfor_fndecl_fdate)),
			  fndecl, num_args, args);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Free the temporary afterwards, if necessary.  */
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  len, build_int_cst (TREE_TYPE (len), 0));
  tmp = gfc_call_free (var);
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->post, tmp);

  se->expr = var;
  se->string_length = len;
}


/* Generate a direct call to free() for the FREE subroutine.  */

static tree
conv_intrinsic_free (gfc_code *code)
{
  stmtblock_t block;
  gfc_se argse;
  tree arg, call;

  gfc_init_se (&argse, NULL);
  gfc_conv_expr (&argse, code->ext.actual->expr);
  arg = fold_convert (ptr_type_node, argse.expr);

  gfc_init_block (&block);
  call = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_FREE), 1, arg);
  gfc_add_expr_to_block (&block, call);
  return gfc_finish_block (&block);
}


/* Call the RANDOM_INIT library subroutine with a hidden argument for
   handling seeding on coarray images.  */

static tree
conv_intrinsic_random_init (gfc_code *code)
{
  stmtblock_t block;
  gfc_se se;
  tree arg1, arg2, arg3, tmp;
  tree logical4_type_node = gfc_get_logical_type (4);

  /* Make the function call.  */
  gfc_init_block (&block);
  gfc_init_se (&se, NULL);

  /* Convert REPEATABLE to a LOGICAL(4) entity.  */
  gfc_conv_expr (&se, code->ext.actual->expr);
  gfc_add_block_to_block (&block, &se.pre);
  arg1 = fold_convert (logical4_type_node, gfc_evaluate_now (se.expr, &block));
  gfc_add_block_to_block (&block, &se.post);

  /* Convert IMAGE_DISTINCT to a LOGICAL(4) entity.  */
  gfc_conv_expr (&se, code->ext.actual->next->expr);
  gfc_add_block_to_block (&block, &se.pre);
  arg2 = fold_convert (logical4_type_node, gfc_evaluate_now (se.expr, &block));
  gfc_add_block_to_block (&block, &se.post);

  /* Create the hidden argument.  For non-coarray codes and -fcoarray=single,
     simply set this to 0.  For -fcoarray=lib, generate a call to
     THIS_IMAGE() without arguments.  */
  arg3 = build_int_cst (gfc_get_int_type (4), 0);
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      arg3 = build_call_expr_loc (input_location, gfor_fndecl_caf_this_image,
				  1, arg3);
      se.expr = fold_convert (gfc_get_int_type (4), arg3);
    }

  tmp = build_call_expr_loc (input_location, gfor_fndecl_random_init, 3,
			     arg1, arg2, arg3);
  gfc_add_expr_to_block (&block, tmp);

  return gfc_finish_block (&block);
}


/* Call the SYSTEM_CLOCK library functions, handling the type and kind
   conversions.  */

static tree
conv_intrinsic_system_clock (gfc_code *code)
{
  stmtblock_t block;
  gfc_se count_se, count_rate_se, count_max_se;
  tree arg1 = NULL_TREE, arg2 = NULL_TREE, arg3 = NULL_TREE;
  tree tmp;
  int least;

  gfc_expr *count = code->ext.actual->expr;
  gfc_expr *count_rate = code->ext.actual->next->expr;
  gfc_expr *count_max = code->ext.actual->next->next->expr;

  /* Evaluate our arguments.  */
  if (count)
    {
      gfc_init_se (&count_se, NULL);
      gfc_conv_expr (&count_se, count);
    }

  if (count_rate)
    {
      gfc_init_se (&count_rate_se, NULL);
      gfc_conv_expr (&count_rate_se, count_rate);
    }

  if (count_max)
    {
      gfc_init_se (&count_max_se, NULL);
      gfc_conv_expr (&count_max_se, count_max);
    }

  /* Find the smallest kind found of the arguments.  */
  least = 16;
  least = (count && count->ts.kind < least) ? count->ts.kind : least;
  least = (count_rate && count_rate->ts.kind < least) ? count_rate->ts.kind
						      : least;
  least = (count_max && count_max->ts.kind < least) ? count_max->ts.kind
						    : least;

  /* Prepare temporary variables.  */

  if (count)
    {
      if (least >= 8)
	arg1 = gfc_create_var (gfc_get_int_type (8), "count");
      else if (least == 4)
	arg1 = gfc_create_var (gfc_get_int_type (4), "count");
      else if (count->ts.kind == 1)
        arg1 = gfc_conv_mpz_to_tree (gfc_integer_kinds[0].pedantic_min_int,
				     count->ts.kind);
      else
        arg1 = gfc_conv_mpz_to_tree (gfc_integer_kinds[1].pedantic_min_int,
				     count->ts.kind);
    }

  if (count_rate)
    {
      if (least >= 8)
	arg2 = gfc_create_var (gfc_get_int_type (8), "count_rate");
      else if (least == 4)
	arg2 = gfc_create_var (gfc_get_int_type (4), "count_rate");
      else
        arg2 = integer_zero_node;
    }

  if (count_max)
    {
      if (least >= 8)
	arg3 = gfc_create_var (gfc_get_int_type (8), "count_max");
      else if (least == 4)
	arg3 = gfc_create_var (gfc_get_int_type (4), "count_max");
      else
        arg3 = integer_zero_node;
    }

  /* Make the function call.  */
  gfc_init_block (&block);

if (least <= 2)
  {
    if (least == 1)
      {
	arg1 ? gfc_build_addr_expr (NULL_TREE, arg1)
	       : null_pointer_node;
	arg2 ? gfc_build_addr_expr (NULL_TREE, arg2)
	       : null_pointer_node;
	arg3 ? gfc_build_addr_expr (NULL_TREE, arg3)
	       : null_pointer_node;
      }

    if (least == 2)
      {
	arg1 ? gfc_build_addr_expr (NULL_TREE, arg1)
	       : null_pointer_node;
	arg2 ? gfc_build_addr_expr (NULL_TREE, arg2)
	       : null_pointer_node;
	arg3 ? gfc_build_addr_expr (NULL_TREE, arg3)
	       : null_pointer_node;
      }
  }
else
  {
    if (least == 4)
      {
	tmp = build_call_expr_loc (input_location,
		gfor_fndecl_system_clock4, 3,
		arg1 ? gfc_build_addr_expr (NULL_TREE, arg1)
		       : null_pointer_node,
		arg2 ? gfc_build_addr_expr (NULL_TREE, arg2)
		       : null_pointer_node,
		arg3 ? gfc_build_addr_expr (NULL_TREE, arg3)
		       : null_pointer_node);
	gfc_add_expr_to_block (&block, tmp);
      }
    /* Handle kind>=8, 10, or 16 arguments */
    if (least >= 8)
      {
	tmp = build_call_expr_loc (input_location,
		gfor_fndecl_system_clock8, 3,
		arg1 ? gfc_build_addr_expr (NULL_TREE, arg1)
		       : null_pointer_node,
		arg2 ? gfc_build_addr_expr (NULL_TREE, arg2)
		       : null_pointer_node,
		arg3 ? gfc_build_addr_expr (NULL_TREE, arg3)
		       : null_pointer_node);
	gfc_add_expr_to_block (&block, tmp);
      }
  }

  /* And store values back if needed.  */
  if (arg1 && arg1 != count_se.expr)
    gfc_add_modify (&block, count_se.expr,
		    fold_convert (TREE_TYPE (count_se.expr), arg1));
  if (arg2 && arg2 != count_rate_se.expr)
    gfc_add_modify (&block, count_rate_se.expr,
		    fold_convert (TREE_TYPE (count_rate_se.expr), arg2));
  if (arg3 && arg3 != count_max_se.expr)
    gfc_add_modify (&block, count_max_se.expr,
		    fold_convert (TREE_TYPE (count_max_se.expr), arg3));

  return gfc_finish_block (&block);
}


/* Return a character string containing the tty name.  */

static void
gfc_conv_intrinsic_ttynam (gfc_se * se, gfc_expr * expr)
{
  tree var;
  tree len;
  tree tmp;
  tree cond;
  tree fndecl;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr) + 2;
  args = XALLOCAVEC (tree, num_args);

  var = gfc_create_var (pchar_type_node, "pstr");
  len = gfc_create_var (gfc_charlen_type_node, "len");

  gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
  args[0] = gfc_build_addr_expr (NULL_TREE, var);
  args[1] = gfc_build_addr_expr (NULL_TREE, len);

  fndecl = build_addr (gfor_fndecl_ttynam);
  tmp = build_call_array_loc (input_location,
			  TREE_TYPE (TREE_TYPE (gfor_fndecl_ttynam)),
			  fndecl, num_args, args);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Free the temporary afterwards, if necessary.  */
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  len, build_int_cst (TREE_TYPE (len), 0));
  tmp = gfc_call_free (var);
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->post, tmp);

  se->expr = var;
  se->string_length = len;
}


/* Get the minimum/maximum value of all the parameters.
    minmax (a1, a2, a3, ...)
    {
      mvar = a1;
      mvar = COMP (mvar, a2)
      mvar = COMP (mvar, a3)
      ...
      return mvar;
    }
    Where COMP is MIN/MAX_EXPR for integral types or when we don't
    care about NaNs, or IFN_FMIN/MAX when the target has support for
    fast NaN-honouring min/max.  When neither holds expand a sequence
    of explicit comparisons.  */

/* TODO: Mismatching types can occur when specific names are used.
   These should be handled during resolution.  */
static void
gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree tmp;
  tree mvar;
  tree val;
  tree *args;
  tree type;
  gfc_actual_arglist *argexpr;
  unsigned int i, nargs;

  nargs = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, nargs);

  gfc_conv_intrinsic_function_args (se, expr, args, nargs);
  type = gfc_typenode_for_spec (&expr->ts);

  argexpr = expr->value.function.actual;
  if (TREE_TYPE (args[0]) != type)
    args[0] = convert (type, args[0]);
  /* Only evaluate the argument once.  */
  if (!VAR_P (args[0]) && !TREE_CONSTANT (args[0]))
    args[0] = gfc_evaluate_now (args[0], &se->pre);

  mvar = gfc_create_var (type, "M");
  gfc_add_modify (&se->pre, mvar, args[0]);

  for (i = 1, argexpr = argexpr->next; i < nargs; i++, argexpr = argexpr->next)
    {
      tree cond = NULL_TREE;
      val = args[i];

      /* Handle absent optional arguments by ignoring the comparison.  */
      if (argexpr->expr->expr_type == EXPR_VARIABLE
	  && argexpr->expr->symtree->n.sym->attr.optional
	  && TREE_CODE (val) == INDIRECT_REF)
	{
	  cond = fold_build2_loc (input_location,
				NE_EXPR, logical_type_node,
				TREE_OPERAND (val, 0),
			build_int_cst (TREE_TYPE (TREE_OPERAND (val, 0)), 0));
	}
      else if (!VAR_P (val) && !TREE_CONSTANT (val))
	/* Only evaluate the argument once.  */
	val = gfc_evaluate_now (val, &se->pre);

      tree calc;
      /* For floating point types, the question is what MAX(a, NaN) or
	 MIN(a, NaN) should return (where "a" is a normal number).
	 There are valid usecase for returning either one, but the
	 Fortran standard doesn't specify which one should be chosen.
	 Also, there is no consensus among other tested compilers.  In
	 short, it's a mess.  So lets just do whatever is fastest.  */
      tree_code code = op == GT_EXPR ? MAX_EXPR : MIN_EXPR;
      calc = fold_build2_loc (input_location, code, type,
			      convert (type, val), mvar);
      tmp = build2_v (MODIFY_EXPR, mvar, calc);

      if (cond != NULL_TREE)
	tmp = build3_v (COND_EXPR, cond, tmp,
			build_empty_stmt (input_location));
      gfc_add_expr_to_block (&se->pre, tmp);
    }
  se->expr = mvar;
}


/* Generate library calls for MIN and MAX intrinsics for character
   variables.  */
static void
gfc_conv_intrinsic_minmax_char (gfc_se * se, gfc_expr * expr, int op)
{
  tree *args;
  tree var, len, fndecl, tmp, cond, function;
  unsigned int nargs;

  nargs = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, nargs + 4);
  gfc_conv_intrinsic_function_args (se, expr, &args[4], nargs);

  /* Create the result variables.  */
  len = gfc_create_var (gfc_charlen_type_node, "len");
  args[0] = gfc_build_addr_expr (NULL_TREE, len);
  var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
  args[1] = gfc_build_addr_expr (ppvoid_type_node, var);
  args[2] = build_int_cst (integer_type_node, op);
  args[3] = build_int_cst (integer_type_node, nargs / 2);

  if (expr->ts.kind == 1)
    function = gfor_fndecl_string_minmax;
  else if (expr->ts.kind == 4)
    function = gfor_fndecl_string_minmax_char4;
  else
    gcc_unreachable ();

  /* Make the function call.  */
  fndecl = build_addr (function);
  tmp = build_call_array_loc (input_location,
			  TREE_TYPE (TREE_TYPE (function)), fndecl,
			  nargs + 4, args);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Free the temporary afterwards, if necessary.  */
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  len, build_int_cst (TREE_TYPE (len), 0));
  tmp = gfc_call_free (var);
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->post, tmp);

  se->expr = var;
  se->string_length = len;
}


/* Create a symbol node for this intrinsic.  The symbol from the frontend
   has the generic name.  */

static gfc_symbol *
gfc_get_symbol_for_expr (gfc_expr * expr, bool ignore_optional)
{
  gfc_symbol *sym;

  /* TODO: Add symbols for intrinsic function to the global namespace.  */
  gcc_assert (strlen (expr->value.function.name) <= GFC_MAX_SYMBOL_LEN - 5);
  sym = gfc_new_symbol (expr->value.function.name, NULL);

  sym->ts = expr->ts;
  sym->attr.external = 1;
  sym->attr.function = 1;
  sym->attr.always_explicit = 1;
  sym->attr.proc = PROC_INTRINSIC;
  sym->attr.flavor = FL_PROCEDURE;
  sym->result = sym;
  if (expr->rank > 0)
    {
      sym->attr.dimension = 1;
      sym->as = gfc_get_array_spec ();
      sym->as->type = AS_ASSUMED_SHAPE;
      sym->as->rank = expr->rank;
    }

  gfc_copy_formal_args_intr (sym, expr->value.function.isym,
			     ignore_optional ? expr->value.function.actual
					     : NULL);

  return sym;
}

/* Generate a call to an external intrinsic function.  */
static void
gfc_conv_intrinsic_funcall (gfc_se * se, gfc_expr * expr)
{
  gfc_symbol *sym;
  vec<tree, va_gc> *append_args;

  gcc_assert (!se->ss || se->ss->info->expr == expr);

  if (se->ss)
    gcc_assert (expr->rank > 0);
  else
    gcc_assert (expr->rank == 0);

  sym = gfc_get_symbol_for_expr (expr, se->ignore_optional);

  /* Calls to libgfortran_matmul need to be appended special arguments,
     to be able to call the BLAS ?gemm functions if required and possible.  */
  append_args = NULL;
  if (expr->value.function.isym->id == GFC_ISYM_MATMUL
      && !expr->external_blas
      && sym->ts.type != BT_LOGICAL)
    {
      tree cint = gfc_get_int_type (gfc_c_int_kind);

      if (flag_external_blas
	  && (sym->ts.type == BT_REAL || sym->ts.type == BT_COMPLEX)
	  && (sym->ts.kind == 4 || sym->ts.kind == 8))
	{
	  tree gemm_fndecl;

	  if (sym->ts.type == BT_REAL)
	    {
	      if (sym->ts.kind == 4)
		gemm_fndecl = gfor_fndecl_sgemm;
	      else
		gemm_fndecl = gfor_fndecl_dgemm;
	    }
	  else
	    {
	      if (sym->ts.kind == 4)
		gemm_fndecl = gfor_fndecl_cgemm;
	      else
		gemm_fndecl = gfor_fndecl_zgemm;
	    }

	  vec_alloc (append_args, 3);
	  append_args->quick_push (build_int_cst (cint, 1));
	  append_args->quick_push (build_int_cst (cint,
						  flag_blas_matmul_limit));
	  append_args->quick_push (gfc_build_addr_expr (NULL_TREE,
							gemm_fndecl));
	}
      else
	{
	  vec_alloc (append_args, 3);
	  append_args->quick_push (build_int_cst (cint, 0));
	  append_args->quick_push (build_int_cst (cint, 0));
	  append_args->quick_push (null_pointer_node);
	}
    }

  gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
			  append_args);
  gfc_free_symbol (sym);
}

/* ANY and ALL intrinsics. ANY->op == NE_EXPR, ALL->op == EQ_EXPR.
   Implemented as
    any(a)
    {
      forall (i=...)
        if (a[i] != 0)
          return 1
      end forall
      return 0
    }
    all(a)
    {
      forall (i=...)
        if (a[i] == 0)
          return 0
      end forall
      return 1
    }
 */
static void
gfc_conv_intrinsic_anyall (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree resvar;
  stmtblock_t block;
  stmtblock_t body;
  tree type;
  tree tmp;
  tree found;
  gfc_loopinfo loop;
  gfc_actual_arglist *actual;
  gfc_ss *arrayss;
  gfc_se arrayse;
  tree exit_label;

  if (se->ss)
    {
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  actual = expr->value.function.actual;
  type = gfc_typenode_for_spec (&expr->ts);
  /* Initialize the result.  */
  resvar = gfc_create_var (type, "test");
  if (op == EQ_EXPR)
    tmp = convert (type, boolean_true_node);
  else
    tmp = convert (type, boolean_false_node);
  gfc_add_modify (&se->pre, resvar, tmp);

  /* Walk the arguments.  */
  arrayss = gfc_walk_expr (actual->expr);
  gcc_assert (arrayss != gfc_ss_terminator);

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);
  exit_label = gfc_build_label_decl (NULL_TREE);
  TREE_USED (exit_label) = 1;
  gfc_add_ss_to_loop (&loop, arrayss);

  /* Initialize the loop.  */
  gfc_conv_ss_startstride (&loop);
  gfc_conv_loop_setup (&loop, &expr->where);

  gfc_mark_ss_chain_used (arrayss, 1);
  /* Generate the loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  /* If the condition matches then set the return value.  */
  gfc_start_block (&block);
  if (op == EQ_EXPR)
    tmp = convert (type, boolean_false_node);
  else
    tmp = convert (type, boolean_true_node);
  gfc_add_modify (&block, resvar, tmp);

  /* And break out of the loop.  */
  tmp = build1_v (GOTO_EXPR, exit_label);
  gfc_add_expr_to_block (&block, tmp);

  found = gfc_finish_block (&block);

  /* Check this element.  */
  gfc_init_se (&arrayse, NULL);
  gfc_copy_loopinfo_to_se (&arrayse, &loop);
  arrayse.ss = arrayss;
  gfc_conv_expr_val (&arrayse, actual->expr);

  gfc_add_block_to_block (&body, &arrayse.pre);
  tmp = fold_build2_loc (input_location, op, logical_type_node, arrayse.expr,
			 build_int_cst (TREE_TYPE (arrayse.expr), 0));
  tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&body, tmp);
  gfc_add_block_to_block (&body, &arrayse.post);

  gfc_trans_scalarizing_loops (&loop, &body);

  /* Add the exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&loop.pre, tmp);

  gfc_add_block_to_block (&se->pre, &loop.pre);
  gfc_add_block_to_block (&se->pre, &loop.post);
  gfc_cleanup_loop (&loop);

  se->expr = resvar;
}

/* COUNT(A) = Number of true elements in A.  */
static void
gfc_conv_intrinsic_count (gfc_se * se, gfc_expr * expr)
{
  tree resvar;
  tree type;
  stmtblock_t body;
  tree tmp;
  gfc_loopinfo loop;
  gfc_actual_arglist *actual;
  gfc_ss *arrayss;
  gfc_se arrayse;

  if (se->ss)
    {
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  actual = expr->value.function.actual;

  type = gfc_typenode_for_spec (&expr->ts);
  /* Initialize the result.  */
  resvar = gfc_create_var (type, "count");
  gfc_add_modify (&se->pre, resvar, build_int_cst (type, 0));

  /* Walk the arguments.  */
  arrayss = gfc_walk_expr (actual->expr);
  gcc_assert (arrayss != gfc_ss_terminator);

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);
  gfc_add_ss_to_loop (&loop, arrayss);

  /* Initialize the loop.  */
  gfc_conv_ss_startstride (&loop);
  gfc_conv_loop_setup (&loop, &expr->where);

  gfc_mark_ss_chain_used (arrayss, 1);
  /* Generate the loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (resvar),
			 resvar, build_int_cst (TREE_TYPE (resvar), 1));
  tmp = build2_v (MODIFY_EXPR, resvar, tmp);

  gfc_init_se (&arrayse, NULL);
  gfc_copy_loopinfo_to_se (&arrayse, &loop);
  arrayse.ss = arrayss;
  gfc_conv_expr_val (&arrayse, actual->expr);
  tmp = build3_v (COND_EXPR, arrayse.expr, tmp,
		  build_empty_stmt (input_location));

  gfc_add_block_to_block (&body, &arrayse.pre);
  gfc_add_expr_to_block (&body, tmp);
  gfc_add_block_to_block (&body, &arrayse.post);

  gfc_trans_scalarizing_loops (&loop, &body);

  gfc_add_block_to_block (&se->pre, &loop.pre);
  gfc_add_block_to_block (&se->pre, &loop.post);
  gfc_cleanup_loop (&loop);

  se->expr = resvar;
}


/* Update given gfc_se to have ss component pointing to the nested gfc_ss
   struct and return the corresponding loopinfo.  */

static gfc_loopinfo *
enter_nested_loop (gfc_se *se)
{
  se->ss = se->ss->nested_ss;
  gcc_assert (se->ss == se->ss->loop->ss);

  return se->ss->loop;
}

/* Build the condition for a mask, which may be optional.  */

static tree
conv_mask_condition (gfc_se *maskse, gfc_expr *maskexpr,
			 bool optional_mask)
{
  tree present;
  tree type;

  if (optional_mask)
    {
      type = TREE_TYPE (maskse->expr);
      present = gfc_conv_expr_present (maskexpr->symtree->n.sym);
      present = convert (type, present);
      present = fold_build1_loc (input_location, TRUTH_NOT_EXPR, type,
				 present);
      return fold_build2_loc (input_location, TRUTH_ORIF_EXPR,
			      type, present, maskse->expr);
    }
  else
    return maskse->expr;
}

/* Inline implementation of the sum and product intrinsics.  */
static void
gfc_conv_intrinsic_arith (gfc_se * se, gfc_expr * expr, enum tree_code op,
			  bool norm2)
{
  tree resvar;
  tree scale = NULL_TREE;
  tree type;
  stmtblock_t body;
  stmtblock_t block;
  tree tmp;
  gfc_loopinfo loop, *ploop;
  gfc_actual_arglist *arg_array, *arg_mask;
  gfc_ss *arrayss = NULL;
  gfc_ss *maskss = NULL;
  gfc_se arrayse;
  gfc_se maskse;
  gfc_se *parent_se;
  gfc_expr *arrayexpr;
  gfc_expr *maskexpr;
  bool optional_mask;

  if (expr->rank > 0)
    {
      gcc_assert (gfc_inline_intrinsic_function_p (expr));
      parent_se = se;
    }
  else
    parent_se = NULL;

  type = gfc_typenode_for_spec (&expr->ts);
  /* Initialize the result.  */
  resvar = gfc_create_var (type, "val");
  if (norm2)
    {
      /* result = 0.0;
	 scale = 1.0.  */
      scale = gfc_create_var (type, "scale");
      gfc_add_modify (&se->pre, scale,
		      gfc_build_const (type, integer_one_node));
      tmp = gfc_build_const (type, integer_zero_node);
    }
  else if (op == PLUS_EXPR || op == BIT_IOR_EXPR || op == BIT_XOR_EXPR)
    tmp = gfc_build_const (type, integer_zero_node);
  else if (op == NE_EXPR)
    /* PARITY.  */
    tmp = convert (type, boolean_false_node);
  else if (op == BIT_AND_EXPR)
    tmp = gfc_build_const (type, fold_build1_loc (input_location, NEGATE_EXPR,
						  type, integer_one_node));
  else
    tmp = gfc_build_const (type, integer_one_node);

  gfc_add_modify (&se->pre, resvar, tmp);

  arg_array = expr->value.function.actual;

  arrayexpr = arg_array->expr;

  if (op == NE_EXPR || norm2)
    {
      /* PARITY and NORM2.  */
      maskexpr = NULL;
      optional_mask = false;
    }
  else
    {
      arg_mask  = arg_array->next->next;
      gcc_assert (arg_mask != NULL);
      maskexpr = arg_mask->expr;
      optional_mask = maskexpr && maskexpr->expr_type == EXPR_VARIABLE
	&& maskexpr->symtree->n.sym->attr.dummy
	&& maskexpr->symtree->n.sym->attr.optional;
    }

  if (expr->rank == 0)
    {
      /* Walk the arguments.  */
      arrayss = gfc_walk_expr (arrayexpr);
      gcc_assert (arrayss != gfc_ss_terminator);

      if (maskexpr && maskexpr->rank > 0)
	{
	  maskss = gfc_walk_expr (maskexpr);
	  gcc_assert (maskss != gfc_ss_terminator);
	}
      else
	maskss = NULL;

      /* Initialize the scalarizer.  */
      gfc_init_loopinfo (&loop);

      /* We add the mask first because the number of iterations is
	 taken from the last ss, and this breaks if an absent
	 optional argument is used for mask.  */

      if (maskexpr && maskexpr->rank > 0)
	gfc_add_ss_to_loop (&loop, maskss);
      gfc_add_ss_to_loop (&loop, arrayss);

      /* Initialize the loop.  */
      gfc_conv_ss_startstride (&loop);
      gfc_conv_loop_setup (&loop, &expr->where);

      if (maskexpr && maskexpr->rank > 0)
	gfc_mark_ss_chain_used (maskss, 1);
      gfc_mark_ss_chain_used (arrayss, 1);

      ploop = &loop;
    }
  else
    /* All the work has been done in the parent loops.  */
    ploop = enter_nested_loop (se);

  gcc_assert (ploop);

  /* Generate the loop body.  */
  gfc_start_scalarized_body (ploop, &body);

  /* If we have a mask, only add this element if the mask is set.  */
  if (maskexpr && maskexpr->rank > 0)
    {
      gfc_init_se (&maskse, parent_se);
      gfc_copy_loopinfo_to_se (&maskse, ploop);
      if (expr->rank == 0)
	maskse.ss = maskss;
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_add_block_to_block (&body, &maskse.pre);

      gfc_start_block (&block);
    }
  else
    gfc_init_block (&block);

  /* Do the actual summation/product.  */
  gfc_init_se (&arrayse, parent_se);
  gfc_copy_loopinfo_to_se (&arrayse, ploop);
  if (expr->rank == 0)
    arrayse.ss = arrayss;
  gfc_conv_expr_val (&arrayse, arrayexpr);
  gfc_add_block_to_block (&block, &arrayse.pre);

  if (norm2)
    {
      /* if (x (i) != 0.0)
	   {
	     absX = abs(x(i))
	     if (absX > scale)
	       {
                 val = scale/absX;
		 result = 1.0 + result * val * val;
		 scale = absX;
	       }
	     else
	       {
                 val = absX/scale;
	         result += val * val;
	       }
	   }  */
      tree res1, res2, cond, absX, val;
      stmtblock_t ifblock1, ifblock2, ifblock3;

      gfc_init_block (&ifblock1);

      absX = gfc_create_var (type, "absX");
      gfc_add_modify (&ifblock1, absX,
		      fold_build1_loc (input_location, ABS_EXPR, type,
				       arrayse.expr));
      val = gfc_create_var (type, "val");
      gfc_add_expr_to_block (&ifblock1, val);

      gfc_init_block (&ifblock2);
      gfc_add_modify (&ifblock2, val,
		      fold_build2_loc (input_location, RDIV_EXPR, type, scale,
				       absX));
      res1 = fold_build2_loc (input_location, MULT_EXPR, type, val, val);
      res1 = fold_build2_loc (input_location, MULT_EXPR, type, resvar, res1);
      res1 = fold_build2_loc (input_location, PLUS_EXPR, type, res1,
			      gfc_build_const (type, integer_one_node));
      gfc_add_modify (&ifblock2, resvar, res1);
      gfc_add_modify (&ifblock2, scale, absX);
      res1 = gfc_finish_block (&ifblock2);

      gfc_init_block (&ifblock3);
      gfc_add_modify (&ifblock3, val,
		      fold_build2_loc (input_location, RDIV_EXPR, type, absX,
				       scale));
      res2 = fold_build2_loc (input_location, MULT_EXPR, type, val, val);
      res2 = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, res2);
      gfc_add_modify (&ifblock3, resvar, res2);
      res2 = gfc_finish_block (&ifblock3);

      cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			      absX, scale);
      tmp = build3_v (COND_EXPR, cond, res1, res2);
      gfc_add_expr_to_block (&ifblock1, tmp);
      tmp = gfc_finish_block (&ifblock1);

      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			      arrayse.expr,
			      gfc_build_const (type, integer_zero_node));

      tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tmp);
    }
  else
    {
      tmp = fold_build2_loc (input_location, op, type, resvar, arrayse.expr);
      gfc_add_modify (&block, resvar, tmp);
    }

  gfc_add_block_to_block (&block, &arrayse.post);

  if (maskexpr && maskexpr->rank > 0)
    {
      /* We enclose the above in if (mask) {...} .  If the mask is an
	 optional argument, generate
	 IF (.NOT. PRESENT(MASK) .OR. MASK(I)).  */
      tree ifmask;
      tmp = gfc_finish_block (&block);
      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      tmp = build3_v (COND_EXPR, ifmask, tmp,
		      build_empty_stmt (input_location));
    }
  else
    tmp = gfc_finish_block (&block);
  gfc_add_expr_to_block (&body, tmp);

  gfc_trans_scalarizing_loops (ploop, &body);

  /* For a scalar mask, enclose the loop in an if statement.  */
  if (maskexpr && maskexpr->rank == 0)
    {
      gfc_init_block (&block);
      gfc_add_block_to_block (&block, &ploop->pre);
      gfc_add_block_to_block (&block, &ploop->post);
      tmp = gfc_finish_block (&block);

      if (expr->rank > 0)
	{
	  tmp = build3_v (COND_EXPR, se->ss->info->data.scalar.value, tmp,
			  build_empty_stmt (input_location));
	  gfc_advance_se_ss_chain (se);
	}
      else
	{
	  tree ifmask;

	  gcc_assert (expr->rank == 0);
	  gfc_init_se (&maskse, NULL);
	  gfc_conv_expr_val (&maskse, maskexpr);
	  ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
	  tmp = build3_v (COND_EXPR, ifmask, tmp,
			  build_empty_stmt (input_location));
	}

      gfc_add_expr_to_block (&block, tmp);
      gfc_add_block_to_block (&se->pre, &block);
      gcc_assert (se->post.head == NULL);
    }
  else
    {
      gfc_add_block_to_block (&se->pre, &ploop->pre);
      gfc_add_block_to_block (&se->pre, &ploop->post);
    }

  if (expr->rank == 0)
    gfc_cleanup_loop (ploop);

  if (norm2)
    {
      /* result = scale * sqrt(result).  */
      tree sqrt;
      sqrt = gfc_builtin_decl_for_float_kind (BUILT_IN_SQRT, expr->ts.kind);
      resvar = build_call_expr_loc (input_location,
				    sqrt, 1, resvar);
      resvar = fold_build2_loc (input_location, MULT_EXPR, type, scale, resvar);
    }

  se->expr = resvar;
}


/* Inline implementation of the dot_product intrinsic. This function
   is based on gfc_conv_intrinsic_arith (the previous function).  */
static void
gfc_conv_intrinsic_dot_product (gfc_se * se, gfc_expr * expr)
{
  tree resvar;
  tree type;
  stmtblock_t body;
  stmtblock_t block;
  tree tmp;
  gfc_loopinfo loop;
  gfc_actual_arglist *actual;
  gfc_ss *arrayss1, *arrayss2;
  gfc_se arrayse1, arrayse2;
  gfc_expr *arrayexpr1, *arrayexpr2;

  type = gfc_typenode_for_spec (&expr->ts);

  /* Initialize the result.  */
  resvar = gfc_create_var (type, "val");
  if (expr->ts.type == BT_LOGICAL)
    tmp = build_int_cst (type, 0);
  else
    tmp = gfc_build_const (type, integer_zero_node);

  gfc_add_modify (&se->pre, resvar, tmp);

  /* Walk argument #1.  */
  actual = expr->value.function.actual;
  arrayexpr1 = actual->expr;
  arrayss1 = gfc_walk_expr (arrayexpr1);
  gcc_assert (arrayss1 != gfc_ss_terminator);

  /* Walk argument #2.  */
  actual = actual->next;
  arrayexpr2 = actual->expr;
  arrayss2 = gfc_walk_expr (arrayexpr2);
  gcc_assert (arrayss2 != gfc_ss_terminator);

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);
  gfc_add_ss_to_loop (&loop, arrayss1);
  gfc_add_ss_to_loop (&loop, arrayss2);

  /* Initialize the loop.  */
  gfc_conv_ss_startstride (&loop);
  gfc_conv_loop_setup (&loop, &expr->where);

  gfc_mark_ss_chain_used (arrayss1, 1);
  gfc_mark_ss_chain_used (arrayss2, 1);

  /* Generate the loop body.  */
  gfc_start_scalarized_body (&loop, &body);
  gfc_init_block (&block);

  /* Make the tree expression for [conjg(]array1[)].  */
  gfc_init_se (&arrayse1, NULL);
  gfc_copy_loopinfo_to_se (&arrayse1, &loop);
  arrayse1.ss = arrayss1;
  gfc_conv_expr_val (&arrayse1, arrayexpr1);
  if (expr->ts.type == BT_COMPLEX)
    arrayse1.expr = fold_build1_loc (input_location, CONJ_EXPR, type,
				     arrayse1.expr);
  gfc_add_block_to_block (&block, &arrayse1.pre);

  /* Make the tree expression for array2.  */
  gfc_init_se (&arrayse2, NULL);
  gfc_copy_loopinfo_to_se (&arrayse2, &loop);
  arrayse2.ss = arrayss2;
  gfc_conv_expr_val (&arrayse2, arrayexpr2);
  gfc_add_block_to_block (&block, &arrayse2.pre);

  /* Do the actual product and sum.  */
  if (expr->ts.type == BT_LOGICAL)
    {
      tmp = fold_build2_loc (input_location, TRUTH_AND_EXPR, type,
			     arrayse1.expr, arrayse2.expr);
      tmp = fold_build2_loc (input_location, TRUTH_OR_EXPR, type, resvar, tmp);
    }
  else
    {
      tmp = fold_build2_loc (input_location, MULT_EXPR, type, arrayse1.expr,
			     arrayse2.expr);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, type, resvar, tmp);
    }
  gfc_add_modify (&block, resvar, tmp);

  /* Finish up the loop block and the loop.  */
  tmp = gfc_finish_block (&block);
  gfc_add_expr_to_block (&body, tmp);

  gfc_trans_scalarizing_loops (&loop, &body);
  gfc_add_block_to_block (&se->pre, &loop.pre);
  gfc_add_block_to_block (&se->pre, &loop.post);
  gfc_cleanup_loop (&loop);

  se->expr = resvar;
}


/* Emit code for minloc or maxloc intrinsic.  There are many different cases
   we need to handle.  For performance reasons we sometimes create two
   loops instead of one, where the second one is much simpler.
   Examples for minloc intrinsic:
   1) Result is an array, a call is generated
   2) Array mask is used and NaNs need to be supported:
      limit = Infinity;
      pos = 0;
      S = from;
      while (S <= to) {
	if (mask[S]) {
	  if (pos == 0) pos = S + (1 - from);
	  if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
	}
	S++;
      }
      goto lab2;
      lab1:;
      while (S <= to) {
	if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
	S++;
      }
      lab2:;
   3) NaNs need to be supported, but it is known at compile time or cheaply
      at runtime whether array is nonempty or not:
      limit = Infinity;
      pos = 0;
      S = from;
      while (S <= to) {
	if (a[S] <= limit) { limit = a[S]; pos = S + (1 - from); goto lab1; }
	S++;
      }
      if (from <= to) pos = 1;
      goto lab2;
      lab1:;
      while (S <= to) {
	if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
	S++;
      }
      lab2:;
   4) NaNs aren't supported, array mask is used:
      limit = infinities_supported ? Infinity : huge (limit);
      pos = 0;
      S = from;
      while (S <= to) {
	if (mask[S]) { limit = a[S]; pos = S + (1 - from); goto lab1; }
	S++;
      }
      goto lab2;
      lab1:;
      while (S <= to) {
	if (mask[S]) if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
	S++;
      }
      lab2:;
   5) Same without array mask:
      limit = infinities_supported ? Infinity : huge (limit);
      pos = (from <= to) ? 1 : 0;
      S = from;
      while (S <= to) {
	if (a[S] < limit) { limit = a[S]; pos = S + (1 - from); }
	S++;
      }
   For 3) and 5), if mask is scalar, this all goes into a conditional,
   setting pos = 0; in the else branch.

   Since we now also support the BACK argument, instead of using
   if (a[S] < limit), we now use

   if (back)
     cond = a[S] <= limit;
   else
     cond = a[S] < limit;
   if (cond) {
     ....

     The optimizer is smart enough to move the condition out of the loop.
     The are now marked as unlikely to for further speedup.  */

static void
gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  stmtblock_t body;
  stmtblock_t block;
  stmtblock_t ifblock;
  stmtblock_t elseblock;
  tree limit;
  tree type;
  tree tmp;
  tree cond;
  tree elsetmp;
  tree ifbody;
  tree offset;
  tree nonempty;
  tree lab1, lab2;
  tree b_if, b_else;
  gfc_loopinfo loop;
  gfc_actual_arglist *actual;
  gfc_ss *arrayss;
  gfc_ss *maskss;
  gfc_se arrayse;
  gfc_se maskse;
  gfc_expr *arrayexpr;
  gfc_expr *maskexpr;
  gfc_expr *backexpr;
  gfc_se backse;
  tree pos;
  int n;
  bool optional_mask;

  actual = expr->value.function.actual;

  /* The last argument, BACK, is passed by value. Ensure that
     by setting its name to %VAL. */
  for (gfc_actual_arglist *a = actual; a; a = a->next)
    {
      if (a->next == NULL)
	a->name = "%VAL";
    }

  if (se->ss)
    {
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  arrayexpr = actual->expr;

  /* Special case for character maxloc.  Remove unneeded actual
     arguments, then call a library function.  */

  if (arrayexpr->ts.type == BT_CHARACTER)
    {
      gfc_actual_arglist *a, *b;
      a = actual;
      while (a->next)
	{
	  b = a->next;
	  if (b->expr == NULL || strcmp (b->name, "dim") == 0)
	    {
	      a->next = b->next;
	      b->next = NULL;
	      gfc_free_actual_arglist (b);
	    }
	  else
	    a = b;
	}
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  /* Initialize the result.  */
  pos = gfc_create_var (gfc_array_index_type, "pos");
  offset = gfc_create_var (gfc_array_index_type, "offset");
  type = gfc_typenode_for_spec (&expr->ts);

  /* Walk the arguments.  */
  arrayss = gfc_walk_expr (arrayexpr);
  gcc_assert (arrayss != gfc_ss_terminator);

  actual = actual->next->next;
  gcc_assert (actual);
  maskexpr = actual->expr;
  optional_mask = maskexpr && maskexpr->expr_type == EXPR_VARIABLE
    && maskexpr->symtree->n.sym->attr.dummy
    && maskexpr->symtree->n.sym->attr.optional;
  backexpr = actual->next->next->expr;
  nonempty = NULL;
  if (maskexpr && maskexpr->rank != 0)
    {
      maskss = gfc_walk_expr (maskexpr);
      gcc_assert (maskss != gfc_ss_terminator);
    }
  else
    {
      mpz_t asize;
      if (gfc_array_size (arrayexpr, &asize))
	{
	  nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
	  mpz_clear (asize);
	  nonempty = fold_build2_loc (input_location, GT_EXPR,
				      logical_type_node, nonempty,
				      gfc_index_zero_node);
	}
      maskss = NULL;
    }

  limit = gfc_create_var (gfc_typenode_for_spec (&arrayexpr->ts), "limit");
  switch (arrayexpr->ts.type)
    {
    case BT_REAL:
      tmp = gfc_build_inf_or_huge (TREE_TYPE (limit), arrayexpr->ts.kind);
      break;

    case BT_INTEGER:
      n = gfc_validate_kind (arrayexpr->ts.type, arrayexpr->ts.kind, false);
      tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
				  arrayexpr->ts.kind);
      break;

    default:
      gcc_unreachable ();
    }

  /* We start with the most negative possible value for MAXLOC, and the most
     positive possible value for MINLOC. The most negative possible value is
     -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
     possible value is HUGE in both cases.  */
  if (op == GT_EXPR)
    tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
  if (op == GT_EXPR && arrayexpr->ts.type == BT_INTEGER)
    tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp), tmp,
			   build_int_cst (TREE_TYPE (tmp), 1));

  gfc_add_modify (&se->pre, limit, tmp);

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);

  /* We add the mask first because the number of iterations is taken
     from the last ss, and this breaks if an absent optional argument
     is used for mask.  */

  if (maskss)
    gfc_add_ss_to_loop (&loop, maskss);

  gfc_add_ss_to_loop (&loop, arrayss);

  /* Initialize the loop.  */
  gfc_conv_ss_startstride (&loop);

  /* The code generated can have more than one loop in sequence (see the
     comment at the function header).  This doesn't work well with the
     scalarizer, which changes arrays' offset when the scalarization loops
     are generated (see gfc_trans_preloop_setup).  Fortunately, {min,max}loc
     are  currently inlined in the scalar case only (for which loop is of rank
     one).  As there is no dependency to care about in that case, there is no
     temporary, so that we can use the scalarizer temporary code to handle
     multiple loops.  Thus, we set temp_dim here, we call gfc_mark_ss_chain_used
     with flag=3 later, and we use gfc_trans_scalarized_loop_boundary even later
     to restore offset.
     TODO: this prevents inlining of rank > 0 minmaxloc calls, so this
     should eventually go away.  We could either create two loops properly,
     or find another way to save/restore the array offsets between the two
     loops (without conflicting with temporary management), or use a single
     loop minmaxloc implementation.  See PR 31067.  */
  loop.temp_dim = loop.dimen;
  gfc_conv_loop_setup (&loop, &expr->where);

  gcc_assert (loop.dimen == 1);
  if (nonempty == NULL && maskss == NULL && loop.from[0] && loop.to[0])
    nonempty = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
				loop.from[0], loop.to[0]);

  lab1 = NULL;
  lab2 = NULL;
  /* Initialize the position to zero, following Fortran 2003.  We are free
     to do this because Fortran 95 allows the result of an entirely false
     mask to be processor dependent.  If we know at compile time the array
     is non-empty and no MASK is used, we can initialize to 1 to simplify
     the inner loop.  */
  if (nonempty != NULL && !HONOR_NANS (DECL_MODE (limit)))
    gfc_add_modify (&loop.pre, pos,
		    fold_build3_loc (input_location, COND_EXPR,
				     gfc_array_index_type,
				     nonempty, gfc_index_one_node,
				     gfc_index_zero_node));
  else
    {
      gfc_add_modify (&loop.pre, pos, gfc_index_zero_node);
      lab1 = gfc_build_label_decl (NULL_TREE);
      TREE_USED (lab1) = 1;
      lab2 = gfc_build_label_decl (NULL_TREE);
      TREE_USED (lab2) = 1;
    }

  /* An offset must be added to the loop
     counter to obtain the required position.  */
  gcc_assert (loop.from[0]);

  tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			 gfc_index_one_node, loop.from[0]);
  gfc_add_modify (&loop.pre, offset, tmp);

  gfc_mark_ss_chain_used (arrayss, lab1 ? 3 : 1);
  if (maskss)
    gfc_mark_ss_chain_used (maskss, lab1 ? 3 : 1);
  /* Generate the loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  /* If we have a mask, only check this element if the mask is set.  */
  if (maskss)
    {
      gfc_init_se (&maskse, NULL);
      gfc_copy_loopinfo_to_se (&maskse, &loop);
      maskse.ss = maskss;
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_add_block_to_block (&body, &maskse.pre);

      gfc_start_block (&block);
    }
  else
    gfc_init_block (&block);

  /* Compare with the current limit.  */
  gfc_init_se (&arrayse, NULL);
  gfc_copy_loopinfo_to_se (&arrayse, &loop);
  arrayse.ss = arrayss;
  gfc_conv_expr_val (&arrayse, arrayexpr);
  gfc_add_block_to_block (&block, &arrayse.pre);

  gfc_init_se (&backse, NULL);
  gfc_conv_expr_val (&backse, backexpr);
  gfc_add_block_to_block (&block, &backse.pre);

  /* We do the following if this is a more extreme value.  */
  gfc_start_block (&ifblock);

  /* Assign the value to the limit...  */
  gfc_add_modify (&ifblock, limit, arrayse.expr);

  if (nonempty == NULL && HONOR_NANS (DECL_MODE (limit)))
    {
      stmtblock_t ifblock2;
      tree ifbody2;

      gfc_start_block (&ifblock2);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
			     loop.loopvar[0], offset);
      gfc_add_modify (&ifblock2, pos, tmp);
      ifbody2 = gfc_finish_block (&ifblock2);
      cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, pos,
			      gfc_index_zero_node);
      tmp = build3_v (COND_EXPR, cond, ifbody2,
		      build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tmp);
    }

  tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
			 loop.loopvar[0], offset);
  gfc_add_modify (&ifblock, pos, tmp);

  if (lab1)
    gfc_add_expr_to_block (&ifblock, build1_v (GOTO_EXPR, lab1));

  ifbody = gfc_finish_block (&ifblock);

  if (!lab1 || HONOR_NANS (DECL_MODE (limit)))
    {
      if (lab1)
	cond = fold_build2_loc (input_location,
				op == GT_EXPR ? GE_EXPR : LE_EXPR,
				logical_type_node, arrayse.expr, limit);
      else
	{
	  tree ifbody2, elsebody2;

	  /* We switch to > or >= depending on the value of the BACK argument. */
	  cond = gfc_create_var (logical_type_node, "cond");

	  gfc_start_block (&ifblock);
	  b_if = fold_build2_loc (input_location, op == GT_EXPR ? GE_EXPR : LE_EXPR,
				  logical_type_node, arrayse.expr, limit);

	  gfc_add_modify (&ifblock, cond, b_if);
	  ifbody2 = gfc_finish_block (&ifblock);

	  gfc_start_block (&elseblock);
	  b_else = fold_build2_loc (input_location, op, logical_type_node,
				    arrayse.expr, limit);

	  gfc_add_modify (&elseblock, cond, b_else);
	  elsebody2 = gfc_finish_block (&elseblock);

	  tmp = fold_build3_loc (input_location, COND_EXPR, logical_type_node,
				 backse.expr, ifbody2, elsebody2);

	  gfc_add_expr_to_block (&block, tmp);
	}

      cond = gfc_unlikely (cond, PRED_BUILTIN_EXPECT);
      ifbody = build3_v (COND_EXPR, cond, ifbody,
			 build_empty_stmt (input_location));
    }
  gfc_add_expr_to_block (&block, ifbody);

  if (maskss)
    {
      /* We enclose the above in if (mask) {...}.  If the mask is an
	 optional argument, generate IF (.NOT. PRESENT(MASK)
	 .OR. MASK(I)). */

      tree ifmask;
      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      tmp = gfc_finish_block (&block);
      tmp = build3_v (COND_EXPR, ifmask, tmp,
		      build_empty_stmt (input_location));
    }
  else
    tmp = gfc_finish_block (&block);
  gfc_add_expr_to_block (&body, tmp);

  if (lab1)
    {
      gfc_trans_scalarized_loop_boundary (&loop, &body);

      if (HONOR_NANS (DECL_MODE (limit)))
	{
	  if (nonempty != NULL)
	    {
	      ifbody = build2_v (MODIFY_EXPR, pos, gfc_index_one_node);
	      tmp = build3_v (COND_EXPR, nonempty, ifbody,
			      build_empty_stmt (input_location));
	      gfc_add_expr_to_block (&loop.code[0], tmp);
	    }
	}

      gfc_add_expr_to_block (&loop.code[0], build1_v (GOTO_EXPR, lab2));
      gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab1));

      /* If we have a mask, only check this element if the mask is set.  */
      if (maskss)
	{
	  gfc_init_se (&maskse, NULL);
	  gfc_copy_loopinfo_to_se (&maskse, &loop);
	  maskse.ss = maskss;
	  gfc_conv_expr_val (&maskse, maskexpr);
	  gfc_add_block_to_block (&body, &maskse.pre);

	  gfc_start_block (&block);
	}
      else
	gfc_init_block (&block);

      /* Compare with the current limit.  */
      gfc_init_se (&arrayse, NULL);
      gfc_copy_loopinfo_to_se (&arrayse, &loop);
      arrayse.ss = arrayss;
      gfc_conv_expr_val (&arrayse, arrayexpr);
      gfc_add_block_to_block (&block, &arrayse.pre);

      /* We do the following if this is a more extreme value.  */
      gfc_start_block (&ifblock);

      /* Assign the value to the limit...  */
      gfc_add_modify (&ifblock, limit, arrayse.expr);

      tmp = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (pos),
			     loop.loopvar[0], offset);
      gfc_add_modify (&ifblock, pos, tmp);

      ifbody = gfc_finish_block (&ifblock);

      /* We switch to > or >= depending on the value of the BACK argument. */
      {
	tree ifbody2, elsebody2;

	cond = gfc_create_var (logical_type_node, "cond");

	gfc_start_block (&ifblock);
	b_if = fold_build2_loc (input_location, op == GT_EXPR ? GE_EXPR : LE_EXPR,
				logical_type_node, arrayse.expr, limit);

	gfc_add_modify (&ifblock, cond, b_if);
	ifbody2 = gfc_finish_block (&ifblock);

	gfc_start_block (&elseblock);
	b_else = fold_build2_loc (input_location, op, logical_type_node,
				  arrayse.expr, limit);

	gfc_add_modify (&elseblock, cond, b_else);
	elsebody2 = gfc_finish_block (&elseblock);

	tmp = fold_build3_loc (input_location, COND_EXPR, logical_type_node,
			       backse.expr, ifbody2, elsebody2);
      }

      gfc_add_expr_to_block (&block, tmp);
      cond = gfc_unlikely (cond, PRED_BUILTIN_EXPECT);
      tmp = build3_v (COND_EXPR, cond, ifbody,
		      build_empty_stmt (input_location));

      gfc_add_expr_to_block (&block, tmp);

      if (maskss)
	{
	  /* We enclose the above in if (mask) {...}.  If the mask is
	 an optional argument, generate IF (.NOT. PRESENT(MASK)
	 .OR. MASK(I)).*/

	  tree ifmask;
	  ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
	  tmp = gfc_finish_block (&block);
	  tmp = build3_v (COND_EXPR, ifmask, tmp,
			  build_empty_stmt (input_location));
	}
      else
	tmp = gfc_finish_block (&block);
      gfc_add_expr_to_block (&body, tmp);
      /* Avoid initializing loopvar[0] again, it should be left where
	 it finished by the first loop.  */
      loop.from[0] = loop.loopvar[0];
    }

  gfc_trans_scalarizing_loops (&loop, &body);

  if (lab2)
    gfc_add_expr_to_block (&loop.pre, build1_v (LABEL_EXPR, lab2));

  /* For a scalar mask, enclose the loop in an if statement.  */
  if (maskexpr && maskss == NULL)
    {
      tree ifmask;

      gfc_init_se (&maskse, NULL);
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_init_block (&block);
      gfc_add_block_to_block (&block, &loop.pre);
      gfc_add_block_to_block (&block, &loop.post);
      tmp = gfc_finish_block (&block);

      /* For the else part of the scalar mask, just initialize
	 the pos variable the same way as above.  */

      gfc_init_block (&elseblock);
      gfc_add_modify (&elseblock, pos, gfc_index_zero_node);
      elsetmp = gfc_finish_block (&elseblock);
      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      tmp = build3_v (COND_EXPR, ifmask, tmp, elsetmp);
      gfc_add_expr_to_block (&block, tmp);
      gfc_add_block_to_block (&se->pre, &block);
    }
  else
    {
      gfc_add_block_to_block (&se->pre, &loop.pre);
      gfc_add_block_to_block (&se->pre, &loop.post);
    }
  gfc_cleanup_loop (&loop);

  se->expr = convert (type, pos);
}

/* Emit code for findloc.  */

static void
gfc_conv_intrinsic_findloc (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *array_arg, *value_arg, *dim_arg, *mask_arg,
    *kind_arg, *back_arg;
  gfc_expr *value_expr;
  int ikind;
  tree resvar;
  stmtblock_t block;
  stmtblock_t body;
  stmtblock_t loopblock;
  tree type;
  tree tmp;
  tree found;
  tree forward_branch;
  tree back_branch;
  gfc_loopinfo loop;
  gfc_ss *arrayss;
  gfc_ss *maskss;
  gfc_se arrayse;
  gfc_se valuese;
  gfc_se maskse;
  gfc_se backse;
  tree exit_label;
  gfc_expr *maskexpr;
  tree offset;
  int i;
  bool optional_mask;

  array_arg = expr->value.function.actual;
  value_arg = array_arg->next;
  dim_arg   = value_arg->next;
  mask_arg  = dim_arg->next;
  kind_arg  = mask_arg->next;
  back_arg  = kind_arg->next;

  /* Remove kind and set ikind.  */
  if (kind_arg->expr)
    {
      ikind = mpz_get_si (kind_arg->expr->value.integer);
      gfc_free_expr (kind_arg->expr);
      kind_arg->expr = NULL;
    }
  else
    ikind = gfc_default_integer_kind;

  value_expr = value_arg->expr;

  /* Unless it's a string, pass VALUE by value.  */
  if (value_expr->ts.type != BT_CHARACTER)
    value_arg->name = "%VAL";

  /* Pass BACK argument by value.  */
  back_arg->name = "%VAL";

  /* Call the library if we have a character function or if
     rank > 0.  */
  if (se->ss || array_arg->expr->ts.type == BT_CHARACTER)
    {
      se->ignore_optional = 1;
      if (expr->rank == 0)
	{
	  /* Remove dim argument.  */
	  gfc_free_expr (dim_arg->expr);
	  dim_arg->expr = NULL;
	}
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  type = gfc_get_int_type (ikind);

  /* Initialize the result.  */
  resvar = gfc_create_var (gfc_array_index_type, "pos");
  gfc_add_modify (&se->pre, resvar, build_int_cst (gfc_array_index_type, 0));
  offset = gfc_create_var (gfc_array_index_type, "offset");

  maskexpr = mask_arg->expr;
  optional_mask = maskexpr && maskexpr->expr_type == EXPR_VARIABLE
    && maskexpr->symtree->n.sym->attr.dummy
    && maskexpr->symtree->n.sym->attr.optional;

  /*  Generate two loops, one for BACK=.true. and one for BACK=.false.  */

  for (i = 0 ; i < 2; i++)
    {
      /* Walk the arguments.  */
      arrayss = gfc_walk_expr (array_arg->expr);
      gcc_assert (arrayss != gfc_ss_terminator);

      if (maskexpr && maskexpr->rank != 0)
	{
	  maskss = gfc_walk_expr (maskexpr);
	  gcc_assert (maskss != gfc_ss_terminator);
	}
      else
	maskss = NULL;

      /* Initialize the scalarizer.  */
      gfc_init_loopinfo (&loop);
      exit_label = gfc_build_label_decl (NULL_TREE);
      TREE_USED (exit_label) = 1;

      /* We add the mask first because the number of iterations is
	 taken from the last ss, and this breaks if an absent
	 optional argument is used for mask.  */

      if (maskss)
	gfc_add_ss_to_loop (&loop, maskss);
      gfc_add_ss_to_loop (&loop, arrayss);

      /* Initialize the loop.  */
      gfc_conv_ss_startstride (&loop);
      gfc_conv_loop_setup (&loop, &expr->where);

      /* Calculate the offset.  */
      tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			     gfc_index_one_node, loop.from[0]);
      gfc_add_modify (&loop.pre, offset, tmp);

      gfc_mark_ss_chain_used (arrayss, 1);
      if (maskss)
	gfc_mark_ss_chain_used (maskss, 1);

      /* The first loop is for BACK=.true.  */
      if (i == 0)
	loop.reverse[0] = GFC_REVERSE_SET;

      /* Generate the loop body.  */
      gfc_start_scalarized_body (&loop, &body);

      /* If we have an array mask, only add the element if it is
	 set.  */
      if (maskss)
	{
	  gfc_init_se (&maskse, NULL);
	  gfc_copy_loopinfo_to_se (&maskse, &loop);
	  maskse.ss = maskss;
	  gfc_conv_expr_val (&maskse, maskexpr);
	  gfc_add_block_to_block (&body, &maskse.pre);
	}

      /* If the condition matches then set the return value.  */
      gfc_start_block (&block);

      /* Add the offset.  */
      tmp = fold_build2_loc (input_location, PLUS_EXPR,
			     TREE_TYPE (resvar),
			     loop.loopvar[0], offset);
      gfc_add_modify (&block, resvar, tmp);
      /* And break out of the loop.  */
      tmp = build1_v (GOTO_EXPR, exit_label);
      gfc_add_expr_to_block (&block, tmp);

      found = gfc_finish_block (&block);

      /* Check this element.  */
      gfc_init_se (&arrayse, NULL);
      gfc_copy_loopinfo_to_se (&arrayse, &loop);
      arrayse.ss = arrayss;
      gfc_conv_expr_val (&arrayse, array_arg->expr);
      gfc_add_block_to_block (&body, &arrayse.pre);

      gfc_init_se (&valuese, NULL);
      gfc_conv_expr_val (&valuese, value_arg->expr);
      gfc_add_block_to_block (&body, &valuese.pre);

      tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			     arrayse.expr, valuese.expr);

      tmp = build3_v (COND_EXPR, tmp, found, build_empty_stmt (input_location));
      if (maskss)
	{
	  /* We enclose the above in if (mask) {...}.  If the mask is
	     an optional argument, generate IF (.NOT. PRESENT(MASK)
	     .OR. MASK(I)). */

	  tree ifmask;
	  ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
	  tmp = build3_v (COND_EXPR, ifmask, tmp,
			  build_empty_stmt (input_location));
	}

      gfc_add_expr_to_block (&body, tmp);
      gfc_add_block_to_block (&body, &arrayse.post);

      gfc_trans_scalarizing_loops (&loop, &body);

      /* Add the exit label.  */
      tmp = build1_v (LABEL_EXPR, exit_label);
      gfc_add_expr_to_block (&loop.pre, tmp);
      gfc_start_block (&loopblock);
      gfc_add_block_to_block (&loopblock, &loop.pre);
      gfc_add_block_to_block (&loopblock, &loop.post);
      if (i == 0)
	forward_branch = gfc_finish_block (&loopblock);
      else
	back_branch = gfc_finish_block (&loopblock);

      gfc_cleanup_loop (&loop);
    }

  /* Enclose the two loops in an IF statement.  */

  gfc_init_se (&backse, NULL);
  gfc_conv_expr_val (&backse, back_arg->expr);
  gfc_add_block_to_block (&se->pre, &backse.pre);
  tmp = build3_v (COND_EXPR, backse.expr, forward_branch, back_branch);

  /* For a scalar mask, enclose the loop in an if statement.  */
  if (maskexpr && maskss == NULL)
    {
      tree ifmask;
      tree if_stmt;

      gfc_init_se (&maskse, NULL);
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_init_block (&block);
      gfc_add_expr_to_block (&block, maskse.expr);
      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      if_stmt = build3_v (COND_EXPR, ifmask, tmp,
			  build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, if_stmt);
      tmp = gfc_finish_block (&block);
    }

  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = convert (type, resvar);

}

/* Emit code for minval or maxval intrinsic.  There are many different cases
   we need to handle.  For performance reasons we sometimes create two
   loops instead of one, where the second one is much simpler.
   Examples for minval intrinsic:
   1) Result is an array, a call is generated
   2) Array mask is used and NaNs need to be supported, rank 1:
      limit = Infinity;
      nonempty = false;
      S = from;
      while (S <= to) {
	if (mask[S]) { nonempty = true; if (a[S] <= limit) goto lab; }
	S++;
      }
      limit = nonempty ? NaN : huge (limit);
      lab:
      while (S <= to) { if(mask[S]) limit = min (a[S], limit); S++; }
   3) NaNs need to be supported, but it is known at compile time or cheaply
      at runtime whether array is nonempty or not, rank 1:
      limit = Infinity;
      S = from;
      while (S <= to) { if (a[S] <= limit) goto lab; S++; }
      limit = (from <= to) ? NaN : huge (limit);
      lab:
      while (S <= to) { limit = min (a[S], limit); S++; }
   4) Array mask is used and NaNs need to be supported, rank > 1:
      limit = Infinity;
      nonempty = false;
      fast = false;
      S1 = from1;
      while (S1 <= to1) {
	S2 = from2;
	while (S2 <= to2) {
	  if (mask[S1][S2]) {
	    if (fast) limit = min (a[S1][S2], limit);
	    else {
	      nonempty = true;
	      if (a[S1][S2] <= limit) {
		limit = a[S1][S2];
		fast = true;
	      }
	    }
	  }
	  S2++;
	}
	S1++;
      }
      if (!fast)
	limit = nonempty ? NaN : huge (limit);
   5) NaNs need to be supported, but it is known at compile time or cheaply
      at runtime whether array is nonempty or not, rank > 1:
      limit = Infinity;
      fast = false;
      S1 = from1;
      while (S1 <= to1) {
	S2 = from2;
	while (S2 <= to2) {
	  if (fast) limit = min (a[S1][S2], limit);
	  else {
	    if (a[S1][S2] <= limit) {
	      limit = a[S1][S2];
	      fast = true;
	    }
	  }
	  S2++;
	}
	S1++;
      }
      if (!fast)
	limit = (nonempty_array) ? NaN : huge (limit);
   6) NaNs aren't supported, but infinities are.  Array mask is used:
      limit = Infinity;
      nonempty = false;
      S = from;
      while (S <= to) {
	if (mask[S]) { nonempty = true; limit = min (a[S], limit); }
	S++;
      }
      limit = nonempty ? limit : huge (limit);
   7) Same without array mask:
      limit = Infinity;
      S = from;
      while (S <= to) { limit = min (a[S], limit); S++; }
      limit = (from <= to) ? limit : huge (limit);
   8) Neither NaNs nor infinities are supported (-ffast-math or BT_INTEGER):
      limit = huge (limit);
      S = from;
      while (S <= to) { limit = min (a[S], limit); S++); }
      (or
      while (S <= to) { if (mask[S]) limit = min (a[S], limit); S++; }
      with array mask instead).
   For 3), 5), 7) and 8), if mask is scalar, this all goes into a conditional,
   setting limit = huge (limit); in the else branch.  */

static void
gfc_conv_intrinsic_minmaxval (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree limit;
  tree type;
  tree tmp;
  tree ifbody;
  tree nonempty;
  tree nonempty_var;
  tree lab;
  tree fast;
  tree huge_cst = NULL, nan_cst = NULL;
  stmtblock_t body;
  stmtblock_t block, block2;
  gfc_loopinfo loop;
  gfc_actual_arglist *actual;
  gfc_ss *arrayss;
  gfc_ss *maskss;
  gfc_se arrayse;
  gfc_se maskse;
  gfc_expr *arrayexpr;
  gfc_expr *maskexpr;
  int n;
  bool optional_mask;

  if (se->ss)
    {
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }

  actual = expr->value.function.actual;
  arrayexpr = actual->expr;

  if (arrayexpr->ts.type == BT_CHARACTER)
    {
      gfc_actual_arglist *a2, *a3;
      a2 = actual->next;  /* dim */
      a3 = a2->next;      /* mask */
      if (a2->expr == NULL || expr->rank == 0)
	{
	  if (a3->expr == NULL)
	    actual->next = NULL;
	  else
	    {
	      actual->next = a3;
	      a2->next = NULL;
	    }
	  gfc_free_actual_arglist (a2);
	}
      else
	if (a3->expr == NULL)
	  {
	    a2->next = NULL;
	    gfc_free_actual_arglist (a3);
	  }
      gfc_conv_intrinsic_funcall (se, expr);
      return;
    }
  type = gfc_typenode_for_spec (&expr->ts);
  /* Initialize the result.  */
  limit = gfc_create_var (type, "limit");
  n = gfc_validate_kind (expr->ts.type, expr->ts.kind, false);
  switch (expr->ts.type)
    {
    case BT_REAL:
      huge_cst = gfc_conv_mpfr_to_tree (gfc_real_kinds[n].huge,
					expr->ts.kind, 0);
      if (HONOR_INFINITIES (DECL_MODE (limit)))
	{
	  REAL_VALUE_TYPE real;
	  real_inf (&real);
	  tmp = build_real (type, real);
	}
      else
	tmp = huge_cst;
      if (HONOR_NANS (DECL_MODE (limit)))
	nan_cst = gfc_build_nan (type, "");
      break;

    case BT_INTEGER:
      tmp = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge, expr->ts.kind);
      break;

    default:
      gcc_unreachable ();
    }

  /* We start with the most negative possible value for MAXVAL, and the most
     positive possible value for MINVAL. The most negative possible value is
     -HUGE for BT_REAL and (-HUGE - 1) for BT_INTEGER; the most positive
     possible value is HUGE in both cases.  */
  if (op == GT_EXPR)
    {
      tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (tmp), tmp);
      if (huge_cst)
	huge_cst = fold_build1_loc (input_location, NEGATE_EXPR,
				    TREE_TYPE (huge_cst), huge_cst);
    }

  if (op == GT_EXPR && expr->ts.type == BT_INTEGER)
    tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp),
			   tmp, build_int_cst (type, 1));

  gfc_add_modify (&se->pre, limit, tmp);

  /* Walk the arguments.  */
  arrayss = gfc_walk_expr (arrayexpr);
  gcc_assert (arrayss != gfc_ss_terminator);

  actual = actual->next->next;
  gcc_assert (actual);
  maskexpr = actual->expr;
  optional_mask = maskexpr && maskexpr->expr_type == EXPR_VARIABLE
    && maskexpr->symtree->n.sym->attr.dummy
    && maskexpr->symtree->n.sym->attr.optional;
  nonempty = NULL;
  if (maskexpr && maskexpr->rank != 0)
    {
      maskss = gfc_walk_expr (maskexpr);
      gcc_assert (maskss != gfc_ss_terminator);
    }
  else
    {
      mpz_t asize;
      if (gfc_array_size (arrayexpr, &asize))
	{
	  nonempty = gfc_conv_mpz_to_tree (asize, gfc_index_integer_kind);
	  mpz_clear (asize);
	  nonempty = fold_build2_loc (input_location, GT_EXPR,
				      logical_type_node, nonempty,
				      gfc_index_zero_node);
	}
      maskss = NULL;
    }

  /* Initialize the scalarizer.  */
  gfc_init_loopinfo (&loop);

  /* We add the mask first because the number of iterations is taken
     from the last ss, and this breaks if an absent optional argument
     is used for mask.  */

  if (maskss)
    gfc_add_ss_to_loop (&loop, maskss);
  gfc_add_ss_to_loop (&loop, arrayss);

  /* Initialize the loop.  */
  gfc_conv_ss_startstride (&loop);

  /* The code generated can have more than one loop in sequence (see the
     comment at the function header).  This doesn't work well with the
     scalarizer, which changes arrays' offset when the scalarization loops
     are generated (see gfc_trans_preloop_setup).  Fortunately, {min,max}val
     are  currently inlined in the scalar case only.  As there is no dependency
     to care about in that case, there is no temporary, so that we can use the
     scalarizer temporary code to handle multiple loops.  Thus, we set temp_dim
     here, we call gfc_mark_ss_chain_used with flag=3 later, and we use
     gfc_trans_scalarized_loop_boundary even later to restore offset.
     TODO: this prevents inlining of rank > 0 minmaxval calls, so this
     should eventually go away.  We could either create two loops properly,
     or find another way to save/restore the array offsets between the two
     loops (without conflicting with temporary management), or use a single
     loop minmaxval implementation.  See PR 31067.  */
  loop.temp_dim = loop.dimen;
  gfc_conv_loop_setup (&loop, &expr->where);

  if (nonempty == NULL && maskss == NULL
      && loop.dimen == 1 && loop.from[0] && loop.to[0])
    nonempty = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
				loop.from[0], loop.to[0]);
  nonempty_var = NULL;
  if (nonempty == NULL
      && (HONOR_INFINITIES (DECL_MODE (limit))
	  || HONOR_NANS (DECL_MODE (limit))))
    {
      nonempty_var = gfc_create_var (logical_type_node, "nonempty");
      gfc_add_modify (&se->pre, nonempty_var, logical_false_node);
      nonempty = nonempty_var;
    }
  lab = NULL;
  fast = NULL;
  if (HONOR_NANS (DECL_MODE (limit)))
    {
      if (loop.dimen == 1)
	{
	  lab = gfc_build_label_decl (NULL_TREE);
	  TREE_USED (lab) = 1;
	}
      else
	{
	  fast = gfc_create_var (logical_type_node, "fast");
	  gfc_add_modify (&se->pre, fast, logical_false_node);
	}
    }

  gfc_mark_ss_chain_used (arrayss, lab ? 3 : 1);
  if (maskss)
    gfc_mark_ss_chain_used (maskss, lab ? 3 : 1);
  /* Generate the loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  /* If we have a mask, only add this element if the mask is set.  */
  if (maskss)
    {
      gfc_init_se (&maskse, NULL);
      gfc_copy_loopinfo_to_se (&maskse, &loop);
      maskse.ss = maskss;
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_add_block_to_block (&body, &maskse.pre);

      gfc_start_block (&block);
    }
  else
    gfc_init_block (&block);

  /* Compare with the current limit.  */
  gfc_init_se (&arrayse, NULL);
  gfc_copy_loopinfo_to_se (&arrayse, &loop);
  arrayse.ss = arrayss;
  gfc_conv_expr_val (&arrayse, arrayexpr);
  gfc_add_block_to_block (&block, &arrayse.pre);

  gfc_init_block (&block2);

  if (nonempty_var)
    gfc_add_modify (&block2, nonempty_var, logical_true_node);

  if (HONOR_NANS (DECL_MODE (limit)))
    {
      tmp = fold_build2_loc (input_location, op == GT_EXPR ? GE_EXPR : LE_EXPR,
			     logical_type_node, arrayse.expr, limit);
      if (lab)
	ifbody = build1_v (GOTO_EXPR, lab);
      else
	{
	  stmtblock_t ifblock;

	  gfc_init_block (&ifblock);
	  gfc_add_modify (&ifblock, limit, arrayse.expr);
	  gfc_add_modify (&ifblock, fast, logical_true_node);
	  ifbody = gfc_finish_block (&ifblock);
	}
      tmp = build3_v (COND_EXPR, tmp, ifbody,
		      build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block2, tmp);
    }
  else
    {
      /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
	 signed zeros.  */
      tmp = fold_build2_loc (input_location,
			     op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
			     type, arrayse.expr, limit);
      gfc_add_modify (&block2, limit, tmp);
    }

  if (fast)
    {
      tree elsebody = gfc_finish_block (&block2);

      /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
	 signed zeros.  */
      if (HONOR_NANS (DECL_MODE (limit)))
	{
	  tmp = fold_build2_loc (input_location, op, logical_type_node,
				 arrayse.expr, limit);
	  ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
	  ifbody = build3_v (COND_EXPR, tmp, ifbody,
			     build_empty_stmt (input_location));
	}
      else
	{
	  tmp = fold_build2_loc (input_location,
				 op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
				 type, arrayse.expr, limit);
	  ifbody = build2_v (MODIFY_EXPR, limit, tmp);
	}
      tmp = build3_v (COND_EXPR, fast, ifbody, elsebody);
      gfc_add_expr_to_block (&block, tmp);
    }
  else
    gfc_add_block_to_block (&block, &block2);

  gfc_add_block_to_block (&block, &arrayse.post);

  tmp = gfc_finish_block (&block);
  if (maskss)
    {
      /* We enclose the above in if (mask) {...}.  If the mask is an
	 optional argument, generate IF (.NOT. PRESENT(MASK)
	 .OR. MASK(I)).  */
      tree ifmask;
      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      tmp = build3_v (COND_EXPR, ifmask, tmp,
		      build_empty_stmt (input_location));
    }
  gfc_add_expr_to_block (&body, tmp);

  if (lab)
    {
      gfc_trans_scalarized_loop_boundary (&loop, &body);

      tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
			     nan_cst, huge_cst);
      gfc_add_modify (&loop.code[0], limit, tmp);
      gfc_add_expr_to_block (&loop.code[0], build1_v (LABEL_EXPR, lab));

      /* If we have a mask, only add this element if the mask is set.  */
      if (maskss)
	{
	  gfc_init_se (&maskse, NULL);
	  gfc_copy_loopinfo_to_se (&maskse, &loop);
	  maskse.ss = maskss;
	  gfc_conv_expr_val (&maskse, maskexpr);
	  gfc_add_block_to_block (&body, &maskse.pre);

	  gfc_start_block (&block);
	}
      else
	gfc_init_block (&block);

      /* Compare with the current limit.  */
      gfc_init_se (&arrayse, NULL);
      gfc_copy_loopinfo_to_se (&arrayse, &loop);
      arrayse.ss = arrayss;
      gfc_conv_expr_val (&arrayse, arrayexpr);
      gfc_add_block_to_block (&block, &arrayse.pre);

      /* MIN_EXPR/MAX_EXPR has unspecified behavior with NaNs or
	 signed zeros.  */
      if (HONOR_NANS (DECL_MODE (limit)))
	{
	  tmp = fold_build2_loc (input_location, op, logical_type_node,
				 arrayse.expr, limit);
	  ifbody = build2_v (MODIFY_EXPR, limit, arrayse.expr);
	  tmp = build3_v (COND_EXPR, tmp, ifbody,
			  build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&block, tmp);
	}
      else
	{
	  tmp = fold_build2_loc (input_location,
				 op == GT_EXPR ? MAX_EXPR : MIN_EXPR,
				 type, arrayse.expr, limit);
	  gfc_add_modify (&block, limit, tmp);
	}

      gfc_add_block_to_block (&block, &arrayse.post);

      tmp = gfc_finish_block (&block);
      if (maskss)
	/* We enclose the above in if (mask) {...}.  */
	{
	  tree ifmask;
	  ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
	  tmp = build3_v (COND_EXPR, ifmask, tmp,
			  build_empty_stmt (input_location));
	}

      gfc_add_expr_to_block (&body, tmp);
      /* Avoid initializing loopvar[0] again, it should be left where
	 it finished by the first loop.  */
      loop.from[0] = loop.loopvar[0];
    }
  gfc_trans_scalarizing_loops (&loop, &body);

  if (fast)
    {
      tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty,
			     nan_cst, huge_cst);
      ifbody = build2_v (MODIFY_EXPR, limit, tmp);
      tmp = build3_v (COND_EXPR, fast, build_empty_stmt (input_location),
		      ifbody);
      gfc_add_expr_to_block (&loop.pre, tmp);
    }
  else if (HONOR_INFINITIES (DECL_MODE (limit)) && !lab)
    {
      tmp = fold_build3_loc (input_location, COND_EXPR, type, nonempty, limit,
			     huge_cst);
      gfc_add_modify (&loop.pre, limit, tmp);
    }

  /* For a scalar mask, enclose the loop in an if statement.  */
  if (maskexpr && maskss == NULL)
    {
      tree else_stmt;
      tree ifmask;

      gfc_init_se (&maskse, NULL);
      gfc_conv_expr_val (&maskse, maskexpr);
      gfc_init_block (&block);
      gfc_add_block_to_block (&block, &loop.pre);
      gfc_add_block_to_block (&block, &loop.post);
      tmp = gfc_finish_block (&block);

      if (HONOR_INFINITIES (DECL_MODE (limit)))
	else_stmt = build2_v (MODIFY_EXPR, limit, huge_cst);
      else
	else_stmt = build_empty_stmt (input_location);

      ifmask = conv_mask_condition (&maskse, maskexpr, optional_mask);
      tmp = build3_v (COND_EXPR, ifmask, tmp, else_stmt);
      gfc_add_expr_to_block (&block, tmp);
      gfc_add_block_to_block (&se->pre, &block);
    }
  else
    {
      gfc_add_block_to_block (&se->pre, &loop.pre);
      gfc_add_block_to_block (&se->pre, &loop.post);
    }

  gfc_cleanup_loop (&loop);

  se->expr = limit;
}

/* BTEST (i, pos) = (i & (1 << pos)) != 0.  */
static void
gfc_conv_intrinsic_btest (gfc_se * se, gfc_expr * expr)
{
  tree args[2];
  tree type;
  tree tmp;

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  type = TREE_TYPE (args[0]);

  tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
			 build_int_cst (type, 1), args[1]);
  tmp = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], tmp);
  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
			 build_int_cst (type, 0));
  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = convert (type, tmp);
}


/* Generate code for BGE, BGT, BLE and BLT intrinsics.  */
static void
gfc_conv_intrinsic_bitcomp (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  /* Convert both arguments to the unsigned type of the same size.  */
  args[0] = fold_convert (unsigned_type_for (TREE_TYPE (args[0])), args[0]);
  args[1] = fold_convert (unsigned_type_for (TREE_TYPE (args[1])), args[1]);

  /* If they have unequal type size, convert to the larger one.  */
  if (TYPE_PRECISION (TREE_TYPE (args[0]))
      > TYPE_PRECISION (TREE_TYPE (args[1])))
    args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
  else if (TYPE_PRECISION (TREE_TYPE (args[1]))
	   > TYPE_PRECISION (TREE_TYPE (args[0])))
    args[0] = fold_convert (TREE_TYPE (args[1]), args[0]);

  /* Now, we compare them.  */
  se->expr = fold_build2_loc (input_location, op, logical_type_node,
			      args[0], args[1]);
}


/* Generate code to perform the specified operation.  */
static void
gfc_conv_intrinsic_bitop (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  se->expr = fold_build2_loc (input_location, op, TREE_TYPE (args[0]),
			      args[0], args[1]);
}

/* Bitwise not.  */
static void
gfc_conv_intrinsic_not (gfc_se * se, gfc_expr * expr)
{
  tree arg;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  se->expr = fold_build1_loc (input_location, BIT_NOT_EXPR,
			      TREE_TYPE (arg), arg);
}

/* Set or clear a single bit.  */
static void
gfc_conv_intrinsic_singlebitop (gfc_se * se, gfc_expr * expr, int set)
{
  tree args[2];
  tree type;
  tree tmp;
  enum tree_code op;

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  type = TREE_TYPE (args[0]);

  tmp = fold_build2_loc (input_location, LSHIFT_EXPR, type,
			 build_int_cst (type, 1), args[1]);
  if (set)
    op = BIT_IOR_EXPR;
  else
    {
      op = BIT_AND_EXPR;
      tmp = fold_build1_loc (input_location, BIT_NOT_EXPR, type, tmp);
    }
  se->expr = fold_build2_loc (input_location, op, type, args[0], tmp);
}

/* Extract a sequence of bits.
    IBITS(I, POS, LEN) = (I >> POS) & ~((~0) << LEN).  */
static void
gfc_conv_intrinsic_ibits (gfc_se * se, gfc_expr * expr)
{
  tree args[3];
  tree type;
  tree tmp;
  tree mask;

  gfc_conv_intrinsic_function_args (se, expr, args, 3);
  type = TREE_TYPE (args[0]);

  mask = build_int_cst (type, -1);
  mask = fold_build2_loc (input_location, LSHIFT_EXPR, type, mask, args[2]);
  mask = fold_build1_loc (input_location, BIT_NOT_EXPR, type, mask);

  tmp = fold_build2_loc (input_location, RSHIFT_EXPR, type, args[0], args[1]);

  se->expr = fold_build2_loc (input_location, BIT_AND_EXPR, type, tmp, mask);
}

static void
gfc_conv_intrinsic_shape (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *s, *k;
  gfc_expr *e;
  gfc_array_spec *as;
  gfc_ss *ss;

  /* Remove the KIND argument, if present. */
  s = expr->value.function.actual;
  k = s->next;
  e = k->expr;
  gfc_free_expr (e);
  k->expr = NULL;

  gfc_conv_intrinsic_funcall (se, expr);

  as = gfc_get_full_arrayspec_from_expr (s->expr);;
  ss = gfc_walk_expr (s->expr);

  /* According to F2018 16.9.172, para 5, an assumed rank entity, argument
     associated with an assumed size array, has the ubound of the final
     dimension set to -1 and SHAPE must return this.  */
  if (as && as->type == AS_ASSUMED_RANK
      && se->expr && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))
      && ss && ss->info->type == GFC_SS_SECTION)
    {
      tree desc, rank, minus_one, cond, ubound, tmp;
      stmtblock_t block;
      gfc_se ase;

      minus_one = build_int_cst (gfc_array_index_type, -1);

      /* Recover the descriptor for the array.  */
      gfc_init_se (&ase, NULL);
      ase.descriptor_only = 1;
      gfc_conv_expr_lhs (&ase, ss->info->expr);

      /* Obtain rank-1 so that we can address both descriptors.  */
      rank = gfc_conv_descriptor_rank (ase.expr);
      rank = fold_convert (gfc_array_index_type, rank);
      rank = fold_build2_loc (input_location, PLUS_EXPR,
			      gfc_array_index_type,
			      rank, minus_one);
      rank = gfc_evaluate_now (rank, &se->pre);

      /* The ubound for the final dimension will be tested for being -1.  */
      ubound = gfc_conv_descriptor_ubound_get (ase.expr, rank);
      ubound = gfc_evaluate_now (ubound, &se->pre);
      cond = fold_build2_loc (input_location, EQ_EXPR,
			     logical_type_node,
			     ubound, minus_one);

      /* Obtain the last element of the result from the library shape
	 intrinsic and set it to -1 if that is the value of ubound.  */
      desc = se->expr;
      tmp = gfc_conv_array_data (desc);
      tmp = build_fold_indirect_ref_loc (input_location, tmp);
      tmp = gfc_build_array_ref (tmp, rank, NULL, NULL);

      gfc_init_block (&block);
      gfc_add_modify (&block, tmp, build_int_cst (TREE_TYPE (tmp), -1));

      cond = build3_v (COND_EXPR, cond,
		       gfc_finish_block (&block),
		       build_empty_stmt (input_location));
      gfc_add_expr_to_block (&se->pre, cond);
    }

}

static void
gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
			  bool arithmetic)
{
  tree args[2], type, num_bits, cond;
  tree bigshift;

  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  args[0] = gfc_evaluate_now (args[0], &se->pre);
  args[1] = gfc_evaluate_now (args[1], &se->pre);
  type = TREE_TYPE (args[0]);

  if (!arithmetic)
    args[0] = fold_convert (unsigned_type_for (type), args[0]);
  else
    gcc_assert (right_shift);

  se->expr = fold_build2_loc (input_location,
			      right_shift ? RSHIFT_EXPR : LSHIFT_EXPR,
			      TREE_TYPE (args[0]), args[0], args[1]);

  if (!arithmetic)
    se->expr = fold_convert (type, se->expr);

  if (!arithmetic)
    bigshift = build_int_cst (type, 0);
  else
    {
      tree nonneg = fold_build2_loc (input_location, GE_EXPR,
				     logical_type_node, args[0],
				     build_int_cst (TREE_TYPE (args[0]), 0));
      bigshift = fold_build3_loc (input_location, COND_EXPR, type, nonneg,
				  build_int_cst (type, 0),
				  build_int_cst (type, -1));
    }

  /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
     gcc requires a shift width < BIT_SIZE(I), so we have to catch this
     special case.  */
  num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
  cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
			  args[1], num_bits);

  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
			      bigshift, se->expr);
}

/* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
                        ? 0
	 	        : ((shift >= 0) ? i << shift : i >> -shift)
   where all shifts are logical shifts.  */
static void
gfc_conv_intrinsic_ishft (gfc_se * se, gfc_expr * expr)
{
  tree args[2];
  tree type;
  tree utype;
  tree tmp;
  tree width;
  tree num_bits;
  tree cond;
  tree lshift;
  tree rshift;

  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  args[0] = gfc_evaluate_now (args[0], &se->pre);
  args[1] = gfc_evaluate_now (args[1], &se->pre);

  type = TREE_TYPE (args[0]);
  utype = unsigned_type_for (type);

  width = fold_build1_loc (input_location, ABS_EXPR, TREE_TYPE (args[1]),
			   args[1]);

  /* Left shift if positive.  */
  lshift = fold_build2_loc (input_location, LSHIFT_EXPR, type, args[0], width);

  /* Right shift if negative.
     We convert to an unsigned type because we want a logical shift.
     The standard doesn't define the case of shifting negative
     numbers, and we try to be compatible with other compilers, most
     notably g77, here.  */
  rshift = fold_convert (type, fold_build2_loc (input_location, RSHIFT_EXPR,
				    utype, convert (utype, args[0]), width));

  tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node, args[1],
			 build_int_cst (TREE_TYPE (args[1]), 0));
  tmp = fold_build3_loc (input_location, COND_EXPR, type, tmp, lshift, rshift);

  /* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
     gcc requires a shift width < BIT_SIZE(I), so we have to catch this
     special case.  */
  num_bits = build_int_cst (TREE_TYPE (args[1]), TYPE_PRECISION (type));
  cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node, width,
			  num_bits);
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
			      build_int_cst (type, 0), tmp);
}


/* Circular shift.  AKA rotate or barrel shift.  */

static void
gfc_conv_intrinsic_ishftc (gfc_se * se, gfc_expr * expr)
{
  tree *args;
  tree type;
  tree tmp;
  tree lrot;
  tree rrot;
  tree zero;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);

  gfc_conv_intrinsic_function_args (se, expr, args, num_args);

  if (num_args == 3)
    {
      /* Use a library function for the 3 parameter version.  */
      tree int4type = gfc_get_int_type (4);

      type = TREE_TYPE (args[0]);
      /* We convert the first argument to at least 4 bytes, and
	 convert back afterwards.  This removes the need for library
	 functions for all argument sizes, and function will be
	 aligned to at least 32 bits, so there's no loss.  */
      if (expr->ts.kind < 4)
	args[0] = convert (int4type, args[0]);

      /* Convert the SHIFT and SIZE args to INTEGER*4 otherwise we would
         need loads of library  functions.  They cannot have values >
	 BIT_SIZE (I) so the conversion is safe.  */
      args[1] = convert (int4type, args[1]);
      args[2] = convert (int4type, args[2]);

      switch (expr->ts.kind)
	{
	case 1:
	case 2:
	case 4:
	  tmp = gfor_fndecl_math_ishftc4;
	  break;
	case 8:
	  tmp = gfor_fndecl_math_ishftc8;
	  break;
	case 16:
	  tmp = gfor_fndecl_math_ishftc16;
	  break;
	default:
	  gcc_unreachable ();
	}
      se->expr = build_call_expr_loc (input_location,
				      tmp, 3, args[0], args[1], args[2]);
      /* Convert the result back to the original type, if we extended
	 the first argument's width above.  */
      if (expr->ts.kind < 4)
	se->expr = convert (type, se->expr);

      return;
    }
  type = TREE_TYPE (args[0]);

  /* Evaluate arguments only once.  */
  args[0] = gfc_evaluate_now (args[0], &se->pre);
  args[1] = gfc_evaluate_now (args[1], &se->pre);

  /* Rotate left if positive.  */
  lrot = fold_build2_loc (input_location, LROTATE_EXPR, type, args[0], args[1]);

  /* Rotate right if negative.  */
  tmp = fold_build1_loc (input_location, NEGATE_EXPR, TREE_TYPE (args[1]),
			 args[1]);
  rrot = fold_build2_loc (input_location,RROTATE_EXPR, type, args[0], tmp);

  zero = build_int_cst (TREE_TYPE (args[1]), 0);
  tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node, args[1],
			 zero);
  rrot = fold_build3_loc (input_location, COND_EXPR, type, tmp, lrot, rrot);

  /* Do nothing if shift == 0.  */
  tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, args[1],
			 zero);
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, tmp, args[0],
			      rrot);
}


/* LEADZ (i) = (i == 0) ? BIT_SIZE (i)
			: __builtin_clz(i) - (BIT_SIZE('int') - BIT_SIZE(i))

   The conditional expression is necessary because the result of LEADZ(0)
   is defined, but the result of __builtin_clz(0) is undefined for most
   targets.

   For INTEGER kinds smaller than the C 'int' type, we have to subtract the
   difference in bit size between the argument of LEADZ and the C int.  */

static void
gfc_conv_intrinsic_leadz (gfc_se * se, gfc_expr * expr)
{
  tree arg;
  tree arg_type;
  tree cond;
  tree result_type;
  tree leadz;
  tree bit_size;
  tree tmp;
  tree func;
  int s, argsize;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  argsize = TYPE_PRECISION (TREE_TYPE (arg));

  /* Which variant of __builtin_clz* should we call?  */
  if (argsize <= INT_TYPE_SIZE)
    {
      arg_type = unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CLZ);
    }
  else if (argsize <= LONG_TYPE_SIZE)
    {
      arg_type = long_unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CLZL);
    }
  else if (argsize <= LONG_LONG_TYPE_SIZE)
    {
      arg_type = long_long_unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CLZLL);
    }
  else
    {
      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
      arg_type = gfc_build_uint_type (argsize);
      func = NULL_TREE;
    }

  /* Convert the actual argument twice: first, to the unsigned type of the
     same size; then, to the proper argument type for the built-in
     function.  But the return type is of the default INTEGER kind.  */
  arg = fold_convert (gfc_build_uint_type (argsize), arg);
  arg = fold_convert (arg_type, arg);
  arg = gfc_evaluate_now (arg, &se->pre);
  result_type = gfc_get_int_type (gfc_default_integer_kind);

  /* Compute LEADZ for the case i .ne. 0.  */
  if (func)
    {
      s = TYPE_PRECISION (arg_type) - argsize;
      tmp = fold_convert (result_type,
			  build_call_expr_loc (input_location, func,
					       1, arg));
      leadz = fold_build2_loc (input_location, MINUS_EXPR, result_type,
			       tmp, build_int_cst (result_type, s));
    }
  else
    {
      /* We end up here if the argument type is larger than 'long long'.
	 We generate this code:

	    if (x & (ULL_MAX << ULL_SIZE) != 0)
	      return clzll ((unsigned long long) (x >> ULLSIZE));
	    else
	      return ULL_SIZE + clzll ((unsigned long long) x);
	 where ULL_MAX is the largest value that a ULL_MAX can hold
	 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
	 is the bit-size of the long long type (64 in this example).  */
      tree ullsize, ullmax, tmp1, tmp2, btmp;

      ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
      ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
				long_long_unsigned_type_node,
				build_int_cst (long_long_unsigned_type_node,
					       0));

      cond = fold_build2_loc (input_location, LSHIFT_EXPR, arg_type,
			      fold_convert (arg_type, ullmax), ullsize);
      cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type,
			      arg, cond);
      cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			      cond, build_int_cst (arg_type, 0));

      tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
			      arg, ullsize);
      tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
      btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
      tmp1 = fold_convert (result_type,
			   build_call_expr_loc (input_location, btmp, 1, tmp1));

      tmp2 = fold_convert (long_long_unsigned_type_node, arg);
      btmp = builtin_decl_explicit (BUILT_IN_CLZLL);
      tmp2 = fold_convert (result_type,
			   build_call_expr_loc (input_location, btmp, 1, tmp2));
      tmp2 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
			      tmp2, ullsize);

      leadz = fold_build3_loc (input_location, COND_EXPR, result_type,
			       cond, tmp1, tmp2);
    }

  /* Build BIT_SIZE.  */
  bit_size = build_int_cst (result_type, argsize);

  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			  arg, build_int_cst (arg_type, 0));
  se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
			      bit_size, leadz);
}


/* TRAILZ(i) = (i == 0) ? BIT_SIZE (i) : __builtin_ctz(i)

   The conditional expression is necessary because the result of TRAILZ(0)
   is defined, but the result of __builtin_ctz(0) is undefined for most
   targets.  */

static void
gfc_conv_intrinsic_trailz (gfc_se * se, gfc_expr *expr)
{
  tree arg;
  tree arg_type;
  tree cond;
  tree result_type;
  tree trailz;
  tree bit_size;
  tree func;
  int argsize;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  argsize = TYPE_PRECISION (TREE_TYPE (arg));

  /* Which variant of __builtin_ctz* should we call?  */
  if (argsize <= INT_TYPE_SIZE)
    {
      arg_type = unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CTZ);
    }
  else if (argsize <= LONG_TYPE_SIZE)
    {
      arg_type = long_unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CTZL);
    }
  else if (argsize <= LONG_LONG_TYPE_SIZE)
    {
      arg_type = long_long_unsigned_type_node;
      func = builtin_decl_explicit (BUILT_IN_CTZLL);
    }
  else
    {
      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);
      arg_type = gfc_build_uint_type (argsize);
      func = NULL_TREE;
    }

  /* Convert the actual argument twice: first, to the unsigned type of the
     same size; then, to the proper argument type for the built-in
     function.  But the return type is of the default INTEGER kind.  */
  arg = fold_convert (gfc_build_uint_type (argsize), arg);
  arg = fold_convert (arg_type, arg);
  arg = gfc_evaluate_now (arg, &se->pre);
  result_type = gfc_get_int_type (gfc_default_integer_kind);

  /* Compute TRAILZ for the case i .ne. 0.  */
  if (func)
    trailz = fold_convert (result_type, build_call_expr_loc (input_location,
							     func, 1, arg));
  else
    {
      /* We end up here if the argument type is larger than 'long long'.
	 We generate this code:

	    if ((x & ULL_MAX) == 0)
	      return ULL_SIZE + ctzll ((unsigned long long) (x >> ULLSIZE));
	    else
	      return ctzll ((unsigned long long) x);

	 where ULL_MAX is the largest value that a ULL_MAX can hold
	 (0xFFFFFFFFFFFFFFFF for a 64-bit long long type), and ULLSIZE
	 is the bit-size of the long long type (64 in this example).  */
      tree ullsize, ullmax, tmp1, tmp2, btmp;

      ullsize = build_int_cst (result_type, LONG_LONG_TYPE_SIZE);
      ullmax = fold_build1_loc (input_location, BIT_NOT_EXPR,
				long_long_unsigned_type_node,
				build_int_cst (long_long_unsigned_type_node, 0));

      cond = fold_build2_loc (input_location, BIT_AND_EXPR, arg_type, arg,
			      fold_convert (arg_type, ullmax));
      cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, cond,
			      build_int_cst (arg_type, 0));

      tmp1 = fold_build2_loc (input_location, RSHIFT_EXPR, arg_type,
			      arg, ullsize);
      tmp1 = fold_convert (long_long_unsigned_type_node, tmp1);
      btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
      tmp1 = fold_convert (result_type,
			   build_call_expr_loc (input_location, btmp, 1, tmp1));
      tmp1 = fold_build2_loc (input_location, PLUS_EXPR, result_type,
			      tmp1, ullsize);

      tmp2 = fold_convert (long_long_unsigned_type_node, arg);
      btmp = builtin_decl_explicit (BUILT_IN_CTZLL);
      tmp2 = fold_convert (result_type,
			   build_call_expr_loc (input_location, btmp, 1, tmp2));

      trailz = fold_build3_loc (input_location, COND_EXPR, result_type,
				cond, tmp1, tmp2);
    }

  /* Build BIT_SIZE.  */
  bit_size = build_int_cst (result_type, argsize);

  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			  arg, build_int_cst (arg_type, 0));
  se->expr = fold_build3_loc (input_location, COND_EXPR, result_type, cond,
			      bit_size, trailz);
}

/* Using __builtin_popcount for POPCNT and __builtin_parity for POPPAR;
   for types larger than "long long", we call the long long built-in for
   the lower and higher bits and combine the result.  */

static void
gfc_conv_intrinsic_popcnt_poppar (gfc_se * se, gfc_expr *expr, int parity)
{
  tree arg;
  tree arg_type;
  tree result_type;
  tree func;
  int argsize;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  argsize = TYPE_PRECISION (TREE_TYPE (arg));
  result_type = gfc_get_int_type (gfc_default_integer_kind);

  /* Which variant of the builtin should we call?  */
  if (argsize <= INT_TYPE_SIZE)
    {
      arg_type = unsigned_type_node;
      func = builtin_decl_explicit (parity
				    ? BUILT_IN_PARITY
				    : BUILT_IN_POPCOUNT);
    }
  else if (argsize <= LONG_TYPE_SIZE)
    {
      arg_type = long_unsigned_type_node;
      func = builtin_decl_explicit (parity
				    ? BUILT_IN_PARITYL
				    : BUILT_IN_POPCOUNTL);
    }
  else if (argsize <= LONG_LONG_TYPE_SIZE)
    {
      arg_type = long_long_unsigned_type_node;
      func = builtin_decl_explicit (parity
				    ? BUILT_IN_PARITYLL
				    : BUILT_IN_POPCOUNTLL);
    }
  else
    {
      /* Our argument type is larger than 'long long', which mean none
	 of the POPCOUNT builtins covers it.  We thus call the 'long long'
	 variant multiple times, and add the results.  */
      tree utype, arg2, call1, call2;

      /* For now, we only cover the case where argsize is twice as large
	 as 'long long'.  */
      gcc_assert (argsize == 2 * LONG_LONG_TYPE_SIZE);

      func = builtin_decl_explicit (parity
				    ? BUILT_IN_PARITYLL
				    : BUILT_IN_POPCOUNTLL);

      /* Convert it to an integer, and store into a variable.  */
      utype = gfc_build_uint_type (argsize);
      arg = fold_convert (utype, arg);
      arg = gfc_evaluate_now (arg, &se->pre);

      /* Call the builtin twice.  */
      call1 = build_call_expr_loc (input_location, func, 1,
				   fold_convert (long_long_unsigned_type_node,
						 arg));

      arg2 = fold_build2_loc (input_location, RSHIFT_EXPR, utype, arg,
			      build_int_cst (utype, LONG_LONG_TYPE_SIZE));
      call2 = build_call_expr_loc (input_location, func, 1,
				   fold_convert (long_long_unsigned_type_node,
						 arg2));

      /* Combine the results.  */
      if (parity)
	se->expr = fold_build2_loc (input_location, BIT_XOR_EXPR, result_type,
				    call1, call2);
      else
	se->expr = fold_build2_loc (input_location, PLUS_EXPR, result_type,
				    call1, call2);

      return;
    }

  /* Convert the actual argument twice: first, to the unsigned type of the
     same size; then, to the proper argument type for the built-in
     function.  */
  arg = fold_convert (gfc_build_uint_type (argsize), arg);
  arg = fold_convert (arg_type, arg);

  se->expr = fold_convert (result_type,
			   build_call_expr_loc (input_location, func, 1, arg));
}


/* Process an intrinsic with unspecified argument-types that has an optional
   argument (which could be of type character), e.g. EOSHIFT.  For those, we
   need to append the string length of the optional argument if it is not
   present and the type is really character.
   primary specifies the position (starting at 1) of the non-optional argument
   specifying the type and optional gives the position of the optional
   argument in the arglist.  */

static void
conv_generic_with_optional_char_arg (gfc_se* se, gfc_expr* expr,
				     unsigned primary, unsigned optional)
{
  gfc_actual_arglist* prim_arg;
  gfc_actual_arglist* opt_arg;
  unsigned cur_pos;
  gfc_actual_arglist* arg;
  gfc_symbol* sym;
  vec<tree, va_gc> *append_args;

  /* Find the two arguments given as position.  */
  cur_pos = 0;
  prim_arg = NULL;
  opt_arg = NULL;
  for (arg = expr->value.function.actual; arg; arg = arg->next)
    {
      ++cur_pos;

      if (cur_pos == primary)
	prim_arg = arg;
      if (cur_pos == optional)
	opt_arg = arg;

      if (cur_pos >= primary && cur_pos >= optional)
	break;
    }
  gcc_assert (prim_arg);
  gcc_assert (prim_arg->expr);
  gcc_assert (opt_arg);

  /* If we do have type CHARACTER and the optional argument is really absent,
     append a dummy 0 as string length.  */
  append_args = NULL;
  if (prim_arg->expr->ts.type == BT_CHARACTER && !opt_arg->expr)
    {
      tree dummy;

      dummy = build_int_cst (gfc_charlen_type_node, 0);
      vec_alloc (append_args, 1);
      append_args->quick_push (dummy);
    }

  /* Build the call itself.  */
  gcc_assert (!se->ignore_optional);
  sym = gfc_get_symbol_for_expr (expr, false);
  gfc_conv_procedure_call (se, sym, expr->value.function.actual, expr,
			  append_args);
  gfc_free_symbol (sym);
}

/* The length of a character string.  */
static void
gfc_conv_intrinsic_len (gfc_se * se, gfc_expr * expr)
{
  tree len;
  tree type;
  tree decl;
  gfc_symbol *sym;
  gfc_se argse;
  gfc_expr *arg;

  gcc_assert (!se->ss);

  arg = expr->value.function.actual->expr;

  type = gfc_typenode_for_spec (&expr->ts);
  switch (arg->expr_type)
    {
    case EXPR_CONSTANT:
      len = build_int_cst (gfc_charlen_type_node, arg->value.character.length);
      break;

    case EXPR_ARRAY:
      /* Obtain the string length from the function used by
         trans-array.c(gfc_trans_array_constructor).  */
      len = NULL_TREE;
      get_array_ctor_strlen (&se->pre, arg->value.constructor, &len);
      break;

    case EXPR_VARIABLE:
      if (arg->ref == NULL
	    || (arg->ref->next == NULL && arg->ref->type == REF_ARRAY))
	{
	  /* This doesn't catch all cases.
	     See http://gcc.gnu.org/ml/fortran/2004-06/msg00165.html
	     and the surrounding thread.  */
	  sym = arg->symtree->n.sym;
	  decl = gfc_get_symbol_decl (sym);
	  if (decl == current_function_decl && sym->attr.function
		&& (sym->result == sym))
	    decl = gfc_get_fake_result_decl (sym, 0);

	  len = sym->ts.u.cl->backend_decl;
	  gcc_assert (len);
	  break;
	}

      /* Fall through.  */

    default:
      gfc_init_se (&argse, se);
      if (arg->rank == 0)
	gfc_conv_expr (&argse, arg);
      else
	gfc_conv_expr_descriptor (&argse, arg);
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      len = argse.string_length;
      break;
    }
  se->expr = convert (type, len);
}

/* The length of a character string not including trailing blanks.  */
static void
gfc_conv_intrinsic_len_trim (gfc_se * se, gfc_expr * expr)
{
  int kind = expr->value.function.actual->expr->ts.kind;
  tree args[2], type, fndecl;

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  type = gfc_typenode_for_spec (&expr->ts);

  if (kind == 1)
    fndecl = gfor_fndecl_string_len_trim;
  else if (kind == 4)
    fndecl = gfor_fndecl_string_len_trim_char4;
  else
    gcc_unreachable ();

  se->expr = build_call_expr_loc (input_location,
			      fndecl, 2, args[0], args[1]);
  se->expr = convert (type, se->expr);
}


/* Returns the starting position of a substring within a string.  */

static void
gfc_conv_intrinsic_index_scan_verify (gfc_se * se, gfc_expr * expr,
				      tree function)
{
  tree logical4_type_node = gfc_get_logical_type (4);
  tree type;
  tree fndecl;
  tree *args;
  unsigned int num_args;

  args = XALLOCAVEC (tree, 5);

  /* Get number of arguments; characters count double due to the
     string length argument. Kind= is not passed to the library
     and thus ignored.  */
  if (expr->value.function.actual->next->next->expr == NULL)
    num_args = 4;
  else
    num_args = 5;

  gfc_conv_intrinsic_function_args (se, expr, args, num_args);
  type = gfc_typenode_for_spec (&expr->ts);

  if (num_args == 4)
    args[4] = build_int_cst (logical4_type_node, 0);
  else
    args[4] = convert (logical4_type_node, args[4]);

  fndecl = build_addr (function);
  se->expr = build_call_array_loc (input_location,
			       TREE_TYPE (TREE_TYPE (function)), fndecl,
			       5, args);
  se->expr = convert (type, se->expr);

}

/* The ascii value for a single character.  */
static void
gfc_conv_intrinsic_ichar (gfc_se * se, gfc_expr * expr)
{
  tree args[3], type, pchartype;
  int nargs;

  nargs = gfc_intrinsic_argument_list_length (expr);
  gfc_conv_intrinsic_function_args (se, expr, args, nargs);
  gcc_assert (POINTER_TYPE_P (TREE_TYPE (args[1])));
  pchartype = gfc_get_pchar_type (expr->value.function.actual->expr->ts.kind);
  args[1] = fold_build1_loc (input_location, NOP_EXPR, pchartype, args[1]);
  type = gfc_typenode_for_spec (&expr->ts);

  se->expr = build_fold_indirect_ref_loc (input_location,
				      args[1]);
  se->expr = convert (type, se->expr);
}


/* Intrinsic ISNAN calls __builtin_isnan.  */

static void
gfc_conv_intrinsic_isnan (gfc_se * se, gfc_expr * expr)
{
  tree arg;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  se->expr = build_call_expr_loc (input_location,
				  builtin_decl_explicit (BUILT_IN_ISNAN),
				  1, arg);
  STRIP_TYPE_NOPS (se->expr);
  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Intrinsics IS_IOSTAT_END and IS_IOSTAT_EOR just need to compare
   their argument against a constant integer value.  */

static void
gfc_conv_has_intvalue (gfc_se * se, gfc_expr * expr, const int value)
{
  tree arg;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  se->expr = fold_build2_loc (input_location, EQ_EXPR,
			      gfc_typenode_for_spec (&expr->ts),
			      arg, build_int_cst (TREE_TYPE (arg), value));
}



/* MERGE (tsource, fsource, mask) = mask ? tsource : fsource.  */

static void
gfc_conv_intrinsic_merge (gfc_se * se, gfc_expr * expr)
{
  tree tsource;
  tree fsource;
  tree mask;
  tree type;
  tree len, len2;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);

  gfc_conv_intrinsic_function_args (se, expr, args, num_args);
  if (expr->ts.type != BT_CHARACTER)
    {
      tsource = args[0];
      fsource = args[1];
      mask = args[2];
    }
  else
    {
      /* We do the same as in the non-character case, but the argument
	 list is different because of the string length arguments. We
	 also have to set the string length for the result.  */
      len = args[0];
      tsource = args[1];
      len2 = args[2];
      fsource = args[3];
      mask = args[4];

      gfc_trans_same_strlen_check ("MERGE intrinsic", &expr->where, len, len2,
				   &se->pre);
      se->string_length = len;
    }
  type = TREE_TYPE (tsource);
  se->expr = fold_build3_loc (input_location, COND_EXPR, type, mask, tsource,
			      fold_convert (type, fsource));
}


/* MERGE_BITS (I, J, MASK) = (I & MASK) | (I & (~MASK)).  */

static void
gfc_conv_intrinsic_merge_bits (gfc_se * se, gfc_expr * expr)
{
  tree args[3], mask, type;

  gfc_conv_intrinsic_function_args (se, expr, args, 3);
  mask = gfc_evaluate_now (args[2], &se->pre);

  type = TREE_TYPE (args[0]);
  gcc_assert (TREE_TYPE (args[1]) == type);
  gcc_assert (TREE_TYPE (mask) == type);

  args[0] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[0], mask);
  args[1] = fold_build2_loc (input_location, BIT_AND_EXPR, type, args[1],
			     fold_build1_loc (input_location, BIT_NOT_EXPR,
					      type, mask));
  se->expr = fold_build2_loc (input_location, BIT_IOR_EXPR, type,
			      args[0], args[1]);
}


/* MASKL(n)  =  n == 0 ? 0 : (~0) << (BIT_SIZE - n)
   MASKR(n)  =  n == BIT_SIZE ? ~0 : ~((~0) << n)  */

static void
gfc_conv_intrinsic_mask (gfc_se * se, gfc_expr * expr, int left)
{
  tree arg, allones, type, utype, res, cond, bitsize;
  int i;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  type = gfc_get_int_type (expr->ts.kind);
  utype = unsigned_type_for (type);

  i = gfc_validate_kind (BT_INTEGER, expr->ts.kind, false);
  bitsize = build_int_cst (TREE_TYPE (arg), gfc_integer_kinds[i].bit_size);

  allones = fold_build1_loc (input_location, BIT_NOT_EXPR, utype,
			     build_int_cst (utype, 0));

  if (left)
    {
      /* Left-justified mask.  */
      res = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (arg),
			     bitsize, arg);
      res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
			     fold_convert (utype, res));

      /* Special case arg == 0, because SHIFT_EXPR wants a shift strictly
	 smaller than type width.  */
      cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, arg,
			      build_int_cst (TREE_TYPE (arg), 0));
      res = fold_build3_loc (input_location, COND_EXPR, utype, cond,
			     build_int_cst (utype, 0), res);
    }
  else
    {
      /* Right-justified mask.  */
      res = fold_build2_loc (input_location, LSHIFT_EXPR, utype, allones,
			     fold_convert (utype, arg));
      res = fold_build1_loc (input_location, BIT_NOT_EXPR, utype, res);

      /* Special case agr == bit_size, because SHIFT_EXPR wants a shift
	 strictly smaller than type width.  */
      cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
			      arg, bitsize);
      res = fold_build3_loc (input_location, COND_EXPR, utype,
			     cond, allones, res);
    }

  se->expr = fold_convert (type, res);
}


/* FRACTION (s) is translated into:
     isfinite (s) ? frexp (s, &dummy_int) : NaN  */
static void
gfc_conv_intrinsic_fraction (gfc_se * se, gfc_expr * expr)
{
  tree arg, type, tmp, res, frexp, cond;

  frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  cond = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_ISFINITE),
			      1, arg);

  tmp = gfc_create_var (integer_type_node, NULL);
  res = build_call_expr_loc (input_location, frexp, 2,
			     fold_convert (type, arg),
			     gfc_build_addr_expr (NULL_TREE, tmp));
  res = fold_convert (type, res);

  se->expr = fold_build3_loc (input_location, COND_EXPR, type,
			      cond, res, gfc_build_nan (type, ""));
}


/* NEAREST (s, dir) is translated into
     tmp = copysign (HUGE_VAL, dir);
     return nextafter (s, tmp);
 */
static void
gfc_conv_intrinsic_nearest (gfc_se * se, gfc_expr * expr)
{
  tree args[2], type, tmp, nextafter, copysign, huge_val;

  nextafter = gfc_builtin_decl_for_float_kind (BUILT_IN_NEXTAFTER, expr->ts.kind);
  copysign = gfc_builtin_decl_for_float_kind (BUILT_IN_COPYSIGN, expr->ts.kind);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, args, 2);

  huge_val = gfc_build_inf_or_huge (type, expr->ts.kind);
  tmp = build_call_expr_loc (input_location, copysign, 2, huge_val,
			     fold_convert (type, args[1]));
  se->expr = build_call_expr_loc (input_location, nextafter, 2,
				  fold_convert (type, args[0]), tmp);
  se->expr = fold_convert (type, se->expr);
}


/* SPACING (s) is translated into
    int e;
    if (!isfinite (s))
      res = NaN;
    else if (s == 0)
      res = tiny;
    else
    {
      frexp (s, &e);
      e = e - prec;
      e = MAX_EXPR (e, emin);
      res = scalbn (1., e);
    }
    return res;

 where prec is the precision of s, gfc_real_kinds[k].digits,
       emin is min_exponent - 1, gfc_real_kinds[k].min_exponent - 1,
   and tiny is tiny(s), gfc_real_kinds[k].tiny.  */

static void
gfc_conv_intrinsic_spacing (gfc_se * se, gfc_expr * expr)
{
  tree arg, type, prec, emin, tiny, res, e;
  tree cond, nan, tmp, frexp, scalbn;
  int k;
  stmtblock_t block;

  k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
  prec = build_int_cst (integer_type_node, gfc_real_kinds[k].digits);
  emin = build_int_cst (integer_type_node, gfc_real_kinds[k].min_exponent - 1);
  tiny = gfc_conv_mpfr_to_tree (gfc_real_kinds[k].tiny, expr->ts.kind, 0);

  frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
  scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  type = gfc_typenode_for_spec (&expr->ts);
  e = gfc_create_var (integer_type_node, NULL);
  res = gfc_create_var (type, NULL);


  /* Build the block for s /= 0.  */
  gfc_start_block (&block);
  tmp = build_call_expr_loc (input_location, frexp, 2, arg,
			     gfc_build_addr_expr (NULL_TREE, e));
  gfc_add_expr_to_block (&block, tmp);

  tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node, e,
			 prec);
  gfc_add_modify (&block, e, fold_build2_loc (input_location, MAX_EXPR,
					      integer_type_node, tmp, emin));

  tmp = build_call_expr_loc (input_location, scalbn, 2,
			 build_real_from_int_cst (type, integer_one_node), e);
  gfc_add_modify (&block, res, tmp);

  /* Finish by building the IF statement for value zero.  */
  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, arg,
			  build_real_from_int_cst (type, integer_zero_node));
  tmp = build3_v (COND_EXPR, cond, build2_v (MODIFY_EXPR, res, tiny),
		  gfc_finish_block (&block));

  /* And deal with infinities and NaNs.  */
  cond = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_ISFINITE),
			      1, arg);
  nan = gfc_build_nan (type, "");
  tmp = build3_v (COND_EXPR, cond, tmp, build2_v (MODIFY_EXPR, res, nan));

  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = res;
}


/* RRSPACING (s) is translated into
      int e;
      real x;
      x = fabs (s);
      if (isfinite (x))
      {
	if (x != 0)
	{
	  frexp (s, &e);
	  x = scalbn (x, precision - e);
	}
      }
      else
        x = NaN;
      return x;

 where precision is gfc_real_kinds[k].digits.  */

static void
gfc_conv_intrinsic_rrspacing (gfc_se * se, gfc_expr * expr)
{
  tree arg, type, e, x, cond, nan, stmt, tmp, frexp, scalbn, fabs;
  int prec, k;
  stmtblock_t block;

  k = gfc_validate_kind (BT_REAL, expr->ts.kind, false);
  prec = gfc_real_kinds[k].digits;

  frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
  scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);
  fabs = gfc_builtin_decl_for_float_kind (BUILT_IN_FABS, expr->ts.kind);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  e = gfc_create_var (integer_type_node, NULL);
  x = gfc_create_var (type, NULL);
  gfc_add_modify (&se->pre, x,
		  build_call_expr_loc (input_location, fabs, 1, arg));


  gfc_start_block (&block);
  tmp = build_call_expr_loc (input_location, frexp, 2, arg,
			     gfc_build_addr_expr (NULL_TREE, e));
  gfc_add_expr_to_block (&block, tmp);

  tmp = fold_build2_loc (input_location, MINUS_EXPR, integer_type_node,
			 build_int_cst (integer_type_node, prec), e);
  tmp = build_call_expr_loc (input_location, scalbn, 2, x, tmp);
  gfc_add_modify (&block, x, tmp);
  stmt = gfc_finish_block (&block);

  /* if (x != 0) */
  cond = fold_build2_loc (input_location, NE_EXPR, logical_type_node, x,
			  build_real_from_int_cst (type, integer_zero_node));
  tmp = build3_v (COND_EXPR, cond, stmt, build_empty_stmt (input_location));

  /* And deal with infinities and NaNs.  */
  cond = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_ISFINITE),
			      1, x);
  nan = gfc_build_nan (type, "");
  tmp = build3_v (COND_EXPR, cond, tmp, build2_v (MODIFY_EXPR, x, nan));

  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = fold_convert (type, x);
}


/* SCALE (s, i) is translated into scalbn (s, i).  */
static void
gfc_conv_intrinsic_scale (gfc_se * se, gfc_expr * expr)
{
  tree args[2], type, scalbn;

  scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  se->expr = build_call_expr_loc (input_location, scalbn, 2,
				  fold_convert (type, args[0]),
				  fold_convert (integer_type_node, args[1]));
  se->expr = fold_convert (type, se->expr);
}


/* SET_EXPONENT (s, i) is translated into
   isfinite(s) ? scalbn (frexp (s, &dummy_int), i) : NaN  */
static void
gfc_conv_intrinsic_set_exponent (gfc_se * se, gfc_expr * expr)
{
  tree args[2], type, tmp, frexp, scalbn, cond, nan, res;

  frexp = gfc_builtin_decl_for_float_kind (BUILT_IN_FREXP, expr->ts.kind);
  scalbn = gfc_builtin_decl_for_float_kind (BUILT_IN_SCALBN, expr->ts.kind);

  type = gfc_typenode_for_spec (&expr->ts);
  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  args[0] = gfc_evaluate_now (args[0], &se->pre);

  tmp = gfc_create_var (integer_type_node, NULL);
  tmp = build_call_expr_loc (input_location, frexp, 2,
			     fold_convert (type, args[0]),
			     gfc_build_addr_expr (NULL_TREE, tmp));
  res = build_call_expr_loc (input_location, scalbn, 2, tmp,
			     fold_convert (integer_type_node, args[1]));
  res = fold_convert (type, res);

  /* Call to isfinite */
  cond = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_ISFINITE),
			      1, args[0]);
  nan = gfc_build_nan (type, "");

  se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
			      res, nan);
}


static void
gfc_conv_intrinsic_size (gfc_se * se, gfc_expr * expr)
{
  gfc_actual_arglist *actual;
  tree arg1;
  tree type;
  tree fncall0;
  tree fncall1;
  gfc_se argse;
  gfc_expr *e;
  gfc_symbol *sym = NULL;

  gfc_init_se (&argse, NULL);
  actual = expr->value.function.actual;

  if (actual->expr->ts.type == BT_CLASS)
    gfc_add_class_array_ref (actual->expr);

  e = actual->expr;

  /* These are emerging from the interface mapping, when a class valued
     function appears as the rhs in a realloc on assign statement, where
     the size of the result is that of one of the actual arguments.  */
  if (e->expr_type == EXPR_VARIABLE
      && e->symtree->n.sym->ns == NULL /* This is distinctive!  */
      && e->symtree->n.sym->ts.type == BT_CLASS
      && e->ref && e->ref->type == REF_COMPONENT
      && strcmp (e->ref->u.c.component->name, "_data") == 0)
    sym = e->symtree->n.sym;

  argse.data_not_needed = 1;
  if (gfc_is_class_array_function (e))
    {
      /* For functions that return a class array conv_expr_descriptor is not
	 able to get the descriptor right.  Therefore this special case.  */
      gfc_conv_expr_reference (&argse, e);
      argse.expr = gfc_build_addr_expr (NULL_TREE,
					gfc_class_data_get (argse.expr));
    }
  else if (sym && sym->backend_decl)
    {
      gcc_assert (GFC_CLASS_TYPE_P (TREE_TYPE (sym->backend_decl)));
      argse.expr = sym->backend_decl;
      argse.expr = gfc_build_addr_expr (NULL_TREE,
					gfc_class_data_get (argse.expr));
    }
  else
    {
      argse.want_pointer = 1;
      gfc_conv_expr_descriptor (&argse, actual->expr);
    }
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);
  arg1 = gfc_evaluate_now (argse.expr, &se->pre);

  /* Build the call to size0.  */
  fncall0 = build_call_expr_loc (input_location,
			     gfor_fndecl_size0, 1, arg1);

  actual = actual->next;

  if (actual->expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_type (&argse, actual->expr,
			  gfc_array_index_type);
      gfc_add_block_to_block (&se->pre, &argse.pre);

      /* Unusually, for an intrinsic, size does not exclude
	 an optional arg2, so we must test for it.  */
      if (actual->expr->expr_type == EXPR_VARIABLE
	    && actual->expr->symtree->n.sym->attr.dummy
	    && actual->expr->symtree->n.sym->attr.optional)
	{
	  tree tmp;
	  /* Build the call to size1.  */
	  fncall1 = build_call_expr_loc (input_location,
				     gfor_fndecl_size1, 2,
				     arg1, argse.expr);

	  gfc_init_se (&argse, NULL);
	  argse.want_pointer = 1;
	  argse.data_not_needed = 1;
	  gfc_conv_expr (&argse, actual->expr);
	  gfc_add_block_to_block (&se->pre, &argse.pre);
	  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				 argse.expr, null_pointer_node);
	  tmp = gfc_evaluate_now (tmp, &se->pre);
	  se->expr = fold_build3_loc (input_location, COND_EXPR,
				      pvoid_type_node, tmp, fncall1, fncall0);
	}
      else
	{
	  se->expr = NULL_TREE;
	  argse.expr = fold_build2_loc (input_location, MINUS_EXPR,
					gfc_array_index_type,
					argse.expr, gfc_index_one_node);
	}
    }
  else if (expr->value.function.actual->expr->rank == 1)
    {
      argse.expr = gfc_index_zero_node;
      se->expr = NULL_TREE;
    }
  else
    se->expr = fncall0;

  if (se->expr == NULL_TREE)
    {
      tree ubound, lbound;

      arg1 = build_fold_indirect_ref_loc (input_location,
				      arg1);
      ubound = gfc_conv_descriptor_ubound_get (arg1, argse.expr);
      lbound = gfc_conv_descriptor_lbound_get (arg1, argse.expr);
      se->expr = fold_build2_loc (input_location, MINUS_EXPR,
				  gfc_array_index_type, ubound, lbound);
      se->expr = fold_build2_loc (input_location, PLUS_EXPR,
				  gfc_array_index_type,
				  se->expr, gfc_index_one_node);
      se->expr = fold_build2_loc (input_location, MAX_EXPR,
				  gfc_array_index_type, se->expr,
				  gfc_index_zero_node);
    }

  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = convert (type, se->expr);
}


/* Helper function to compute the size of a character variable,
   excluding the terminating null characters.  The result has
   gfc_array_index_type type.  */

tree
size_of_string_in_bytes (int kind, tree string_length)
{
  tree bytesize;
  int i = gfc_validate_kind (BT_CHARACTER, kind, false);

  bytesize = build_int_cst (gfc_array_index_type,
			    gfc_character_kinds[i].bit_size / 8);

  return fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			  bytesize,
			  fold_convert (gfc_array_index_type, string_length));
}


static void
gfc_conv_intrinsic_sizeof (gfc_se *se, gfc_expr *expr)
{
  gfc_expr *arg;
  gfc_se argse;
  tree source_bytes;
  tree tmp;
  tree lower;
  tree upper;
  tree byte_size;
  tree field;
  int n;

  gfc_init_se (&argse, NULL);
  arg = expr->value.function.actual->expr;

  if (arg->rank || arg->ts.type == BT_ASSUMED)
    gfc_conv_expr_descriptor (&argse, arg);
  else
    gfc_conv_expr_reference (&argse, arg);

  if (arg->ts.type == BT_ASSUMED)
    {
      /* This only works if an array descriptor has been passed; thus, extract
	 the size from the descriptor.  */
      gcc_assert (TYPE_PRECISION (gfc_array_index_type)
		  == TYPE_PRECISION (size_type_node));
      tmp = arg->symtree->n.sym->backend_decl;
      tmp = DECL_LANG_SPECIFIC (tmp)
	    && GFC_DECL_SAVED_DESCRIPTOR (tmp) != NULL_TREE
	    ? GFC_DECL_SAVED_DESCRIPTOR (tmp) : tmp;
      if (POINTER_TYPE_P (TREE_TYPE (tmp)))
	tmp = build_fold_indirect_ref_loc (input_location, tmp);

      tmp = gfc_conv_descriptor_dtype (tmp);
      field = gfc_advance_chain (TYPE_FIELDS (get_dtype_type_node ()),
				 GFC_DTYPE_ELEM_LEN);
      tmp = fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field),
			     tmp, field, NULL_TREE);

      byte_size = fold_convert (gfc_array_index_type, tmp);
    }
  else if (arg->ts.type == BT_CLASS)
    {
      /* Conv_expr_descriptor returns a component_ref to _data component of the
	 class object.  The class object may be a non-pointer object, e.g.
	 located on the stack, or a memory location pointed to, e.g. a
	 parameter, i.e., an indirect_ref.  */
      if (arg->rank < 0
	  || (arg->rank > 0 && !VAR_P (argse.expr)
	      && ((INDIRECT_REF_P (TREE_OPERAND (argse.expr, 0))
		   && GFC_DECL_CLASS (TREE_OPERAND (
					TREE_OPERAND (argse.expr, 0), 0)))
		  || GFC_DECL_CLASS (TREE_OPERAND (argse.expr, 0)))))
	byte_size = gfc_class_vtab_size_get (TREE_OPERAND (argse.expr, 0));
      else if (arg->rank > 0
	       || (arg->rank == 0
		   && arg->ref && arg->ref->type == REF_COMPONENT))
	/* The scalarizer added an additional temp.  To get the class' vptr
	   one has to look at the original backend_decl.  */
	byte_size = gfc_class_vtab_size_get (
	      GFC_DECL_SAVED_DESCRIPTOR (arg->symtree->n.sym->backend_decl));
      else
	byte_size = gfc_class_vtab_size_get (argse.expr);
    }
  else
    {
      if (arg->ts.type == BT_CHARACTER)
	byte_size = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
      else
	{
	  if (arg->rank == 0)
	    byte_size = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
								argse.expr));
	  else
	    byte_size = gfc_get_element_type (TREE_TYPE (argse.expr));
	  byte_size = fold_convert (gfc_array_index_type,
				    size_in_bytes (byte_size));
	}
    }

  if (arg->rank == 0)
    se->expr = byte_size;
  else
    {
      source_bytes = gfc_create_var (gfc_array_index_type, "bytes");
      gfc_add_modify (&argse.pre, source_bytes, byte_size);

      if (arg->rank == -1)
	{
	  tree cond, loop_var, exit_label;
          stmtblock_t body;

	  tmp = fold_convert (gfc_array_index_type,
			      gfc_conv_descriptor_rank (argse.expr));
	  loop_var = gfc_create_var (gfc_array_index_type, "i");
	  gfc_add_modify (&argse.pre, loop_var, gfc_index_zero_node);
          exit_label = gfc_build_label_decl (NULL_TREE);

	  /* Create loop:
	     for (;;)
		{
		  if (i >= rank)
		    goto exit;
		  source_bytes = source_bytes * array.dim[i].extent;
		  i = i + 1;
		}
	      exit:  */
	  gfc_start_block (&body);
	  cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node,
				  loop_var, tmp);
	  tmp = build1_v (GOTO_EXPR, exit_label);
	  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
				 cond, tmp, build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&body, tmp);

	  lower = gfc_conv_descriptor_lbound_get (argse.expr, loop_var);
	  upper = gfc_conv_descriptor_ubound_get (argse.expr, loop_var);
	  tmp = gfc_conv_array_extent_dim (lower, upper, NULL);
	  tmp = fold_build2_loc (input_location, MULT_EXPR,
				 gfc_array_index_type, tmp, source_bytes);
	  gfc_add_modify (&body, source_bytes, tmp);

	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, loop_var,
				 gfc_index_one_node);
	  gfc_add_modify_loc (input_location, &body, loop_var, tmp);

	  tmp = gfc_finish_block (&body);

	  tmp = fold_build1_loc (input_location, LOOP_EXPR, void_type_node,
				 tmp);
	  gfc_add_expr_to_block (&argse.pre, tmp);

	  tmp = build1_v (LABEL_EXPR, exit_label);
	  gfc_add_expr_to_block (&argse.pre, tmp);
	}
      else
	{
	  /* Obtain the size of the array in bytes.  */
	  for (n = 0; n < arg->rank; n++)
	    {
	      tree idx;
	      idx = gfc_rank_cst[n];
	      lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
	      upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
	      tmp = gfc_conv_array_extent_dim (lower, upper, NULL);
	      tmp = fold_build2_loc (input_location, MULT_EXPR,
				     gfc_array_index_type, tmp, source_bytes);
	      gfc_add_modify (&argse.pre, source_bytes, tmp);
	    }
	}
      se->expr = source_bytes;
    }

  gfc_add_block_to_block (&se->pre, &argse.pre);
}


static void
gfc_conv_intrinsic_storage_size (gfc_se *se, gfc_expr *expr)
{
  gfc_expr *arg;
  gfc_se argse;
  tree type, result_type, tmp;

  arg = expr->value.function.actual->expr;

  gfc_init_se (&argse, NULL);
  result_type = gfc_get_int_type (expr->ts.kind);

  if (arg->rank == 0)
    {
      if (arg->ts.type == BT_CLASS)
	{
	  gfc_add_vptr_component (arg);
	  gfc_add_size_component (arg);
	  gfc_conv_expr (&argse, arg);
	  tmp = fold_convert (result_type, argse.expr);
	  goto done;
	}

      gfc_conv_expr_reference (&argse, arg);
      type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
						     argse.expr));
    }
  else
    {
      argse.want_pointer = 0;
      gfc_conv_expr_descriptor (&argse, arg);
      if (arg->ts.type == BT_CLASS)
	{
	  if (arg->rank > 0)
	    tmp = gfc_class_vtab_size_get (
		 GFC_DECL_SAVED_DESCRIPTOR (arg->symtree->n.sym->backend_decl));
	  else
	    tmp = gfc_class_vtab_size_get (TREE_OPERAND (argse.expr, 0));
	  tmp = fold_convert (result_type, tmp);
	  goto done;
	}
      type = gfc_get_element_type (TREE_TYPE (argse.expr));
    }

  /* Obtain the argument's word length.  */
  if (arg->ts.type == BT_CHARACTER)
    tmp = size_of_string_in_bytes (arg->ts.kind, argse.string_length);
  else
    tmp = size_in_bytes (type);
  tmp = fold_convert (result_type, tmp);

done:
  se->expr = fold_build2_loc (input_location, MULT_EXPR, result_type, tmp,
			      build_int_cst (result_type, BITS_PER_UNIT));
  gfc_add_block_to_block (&se->pre, &argse.pre);
}


/* Intrinsic string comparison functions.  */

static void
gfc_conv_intrinsic_strcmp (gfc_se * se, gfc_expr * expr, enum tree_code op)
{
  tree args[4];

  gfc_conv_intrinsic_function_args (se, expr, args, 4);

  se->expr
    = gfc_build_compare_string (args[0], args[1], args[2], args[3],
				expr->value.function.actual->expr->ts.kind,
				op);
  se->expr = fold_build2_loc (input_location, op,
			      gfc_typenode_for_spec (&expr->ts), se->expr,
			      build_int_cst (TREE_TYPE (se->expr), 0));
}

/* Generate a call to the adjustl/adjustr library function.  */
static void
gfc_conv_intrinsic_adjust (gfc_se * se, gfc_expr * expr, tree fndecl)
{
  tree args[3];
  tree len;
  tree type;
  tree var;
  tree tmp;

  gfc_conv_intrinsic_function_args (se, expr, &args[1], 2);
  len = args[1];

  type = TREE_TYPE (args[2]);
  var = gfc_conv_string_tmp (se, type, len);
  args[0] = var;

  tmp = build_call_expr_loc (input_location,
			 fndecl, 3, args[0], args[1], args[2]);
  gfc_add_expr_to_block (&se->pre, tmp);
  se->expr = var;
  se->string_length = len;
}


/* Generate code for the TRANSFER intrinsic:
	For scalar results:
	  DEST = TRANSFER (SOURCE, MOLD)
	where:
	  typeof<DEST> = typeof<MOLD>
	and:
	  MOLD is scalar.

	For array results:
	  DEST(1:N) = TRANSFER (SOURCE, MOLD[, SIZE])
	where:
	  typeof<DEST> = typeof<MOLD>
	and:
	  N = min (sizeof (SOURCE(:)), sizeof (DEST(:)),
	      sizeof (DEST(0) * SIZE).  */
static void
gfc_conv_intrinsic_transfer (gfc_se * se, gfc_expr * expr)
{
  tree tmp;
  tree tmpdecl;
  tree ptr;
  tree extent;
  tree source;
  tree source_type;
  tree source_bytes;
  tree mold_type;
  tree dest_word_len;
  tree size_words;
  tree size_bytes;
  tree upper;
  tree lower;
  tree stmt;
  tree class_ref = NULL_TREE;
  gfc_actual_arglist *arg;
  gfc_se argse;
  gfc_array_info *info;
  stmtblock_t block;
  int n;
  bool scalar_mold;
  gfc_expr *source_expr, *mold_expr, *class_expr;

  info = NULL;
  if (se->loop)
    info = &se->ss->info->data.array;

  /* Convert SOURCE.  The output from this stage is:-
	source_bytes = length of the source in bytes
	source = pointer to the source data.  */
  arg = expr->value.function.actual;
  source_expr = arg->expr;

  /* Ensure double transfer through LOGICAL preserves all
     the needed bits.  */
  if (arg->expr->expr_type == EXPR_FUNCTION
	&& arg->expr->value.function.esym == NULL
	&& arg->expr->value.function.isym != NULL
	&& arg->expr->value.function.isym->id == GFC_ISYM_TRANSFER
	&& arg->expr->ts.type == BT_LOGICAL
	&& expr->ts.type != arg->expr->ts.type)
    arg->expr->value.function.name = "__transfer_in_transfer";

  gfc_init_se (&argse, NULL);

  source_bytes = gfc_create_var (gfc_array_index_type, NULL);

  /* Obtain the pointer to source and the length of source in bytes.  */
  if (arg->expr->rank == 0)
    {
      gfc_conv_expr_reference (&argse, arg->expr);
      if (arg->expr->ts.type == BT_CLASS)
	{
	  tmp = build_fold_indirect_ref_loc (input_location, argse.expr);
	  if (GFC_CLASS_TYPE_P (TREE_TYPE (tmp)))
	    source = gfc_class_data_get (tmp);
	  else
	    {
	      /* Array elements are evaluated as a reference to the data.
		 To obtain the vptr for the element size, the argument
		 expression must be stripped to the class reference and
		 re-evaluated. The pre and post blocks are not needed.  */
	      gcc_assert (arg->expr->expr_type == EXPR_VARIABLE);
	      source = argse.expr;
	      class_expr = gfc_find_and_cut_at_last_class_ref (arg->expr);
	      gfc_init_se (&argse, NULL);
	      gfc_conv_expr (&argse, class_expr);
	      class_ref = argse.expr;
	    }
	}
      else
	source = argse.expr;

      /* Obtain the source word length.  */
      switch (arg->expr->ts.type)
	{
	case BT_CHARACTER:
	  tmp = size_of_string_in_bytes (arg->expr->ts.kind,
					 argse.string_length);
	  break;
	case BT_CLASS:
	  if (class_ref != NULL_TREE)
	    tmp = gfc_class_vtab_size_get (class_ref);
	  else
	    tmp = gfc_class_vtab_size_get (argse.expr);
	  break;
	default:
	  source_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
								source));
	  tmp = fold_convert (gfc_array_index_type,
			      size_in_bytes (source_type));
	  break;
	}
    }
  else
    {
      argse.want_pointer = 0;
      gfc_conv_expr_descriptor (&argse, arg->expr);
      source = gfc_conv_descriptor_data_get (argse.expr);
      source_type = gfc_get_element_type (TREE_TYPE (argse.expr));

      /* Repack the source if not simply contiguous.  */
      if (!gfc_is_simply_contiguous (arg->expr, false, true))
	{
	  tmp = gfc_build_addr_expr (NULL_TREE, argse.expr);

	  if (warn_array_temporaries)
	    gfc_warning (OPT_Warray_temporaries,
			 "Creating array temporary at %L", &expr->where);

	  source = build_call_expr_loc (input_location,
				    gfor_fndecl_in_pack, 1, tmp);
	  source = gfc_evaluate_now (source, &argse.pre);

	  /* Free the temporary.  */
	  gfc_start_block (&block);
	  tmp = gfc_call_free (source);
	  gfc_add_expr_to_block (&block, tmp);
	  stmt = gfc_finish_block (&block);

	  /* Clean up if it was repacked.  */
	  gfc_init_block (&block);
	  tmp = gfc_conv_array_data (argse.expr);
	  tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				 source, tmp);
	  tmp = build3_v (COND_EXPR, tmp, stmt,
			  build_empty_stmt (input_location));
	  gfc_add_expr_to_block (&block, tmp);
	  gfc_add_block_to_block (&block, &se->post);
	  gfc_init_block (&se->post);
	  gfc_add_block_to_block (&se->post, &block);
	}

      /* Obtain the source word length.  */
      if (arg->expr->ts.type == BT_CHARACTER)
	tmp = size_of_string_in_bytes (arg->expr->ts.kind,
				       argse.string_length);
      else
	tmp = fold_convert (gfc_array_index_type,
			    size_in_bytes (source_type));

      /* Obtain the size of the array in bytes.  */
      extent = gfc_create_var (gfc_array_index_type, NULL);
      for (n = 0; n < arg->expr->rank; n++)
	{
	  tree idx;
	  idx = gfc_rank_cst[n];
	  gfc_add_modify (&argse.pre, source_bytes, tmp);
	  lower = gfc_conv_descriptor_lbound_get (argse.expr, idx);
	  upper = gfc_conv_descriptor_ubound_get (argse.expr, idx);
	  tmp = fold_build2_loc (input_location, MINUS_EXPR,
				 gfc_array_index_type, upper, lower);
	  gfc_add_modify (&argse.pre, extent, tmp);
	  tmp = fold_build2_loc (input_location, PLUS_EXPR,
				 gfc_array_index_type, extent,
				 gfc_index_one_node);
	  tmp = fold_build2_loc (input_location, MULT_EXPR,
				 gfc_array_index_type, tmp, source_bytes);
	}
    }

  gfc_add_modify (&argse.pre, source_bytes, tmp);
  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);

  /* Now convert MOLD.  The outputs are:
	mold_type = the TREE type of MOLD
	dest_word_len = destination word length in bytes.  */
  arg = arg->next;
  mold_expr = arg->expr;

  gfc_init_se (&argse, NULL);

  scalar_mold = arg->expr->rank == 0;

  if (arg->expr->rank == 0)
    {
      gfc_conv_expr_reference (&argse, arg->expr);
      mold_type = TREE_TYPE (build_fold_indirect_ref_loc (input_location,
							  argse.expr));
    }
  else
    {
      gfc_init_se (&argse, NULL);
      argse.want_pointer = 0;
      gfc_conv_expr_descriptor (&argse, arg->expr);
      mold_type = gfc_get_element_type (TREE_TYPE (argse.expr));
    }

  gfc_add_block_to_block (&se->pre, &argse.pre);
  gfc_add_block_to_block (&se->post, &argse.post);

  if (strcmp (expr->value.function.name, "__transfer_in_transfer") == 0)
    {
      /* If this TRANSFER is nested in another TRANSFER, use a type
	 that preserves all bits.  */
      if (arg->expr->ts.type == BT_LOGICAL)
	mold_type = gfc_get_int_type (arg->expr->ts.kind);
    }

  /* Obtain the destination word length.  */
  switch (arg->expr->ts.type)
    {
    case BT_CHARACTER:
      tmp = size_of_string_in_bytes (arg->expr->ts.kind, argse.string_length);
      mold_type = gfc_get_character_type_len (arg->expr->ts.kind, tmp);
      break;
    case BT_CLASS:
      tmp = gfc_class_vtab_size_get (argse.expr);
      break;
    default:
      tmp = fold_convert (gfc_array_index_type, size_in_bytes (mold_type));
      break;
    }
  dest_word_len = gfc_create_var (gfc_array_index_type, NULL);
  gfc_add_modify (&se->pre, dest_word_len, tmp);

  /* Finally convert SIZE, if it is present.  */
  arg = arg->next;
  size_words = gfc_create_var (gfc_array_index_type, NULL);

  if (arg->expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_reference (&argse, arg->expr);
      tmp = convert (gfc_array_index_type,
		     build_fold_indirect_ref_loc (input_location,
					      argse.expr));
      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
    }
  else
    tmp = NULL_TREE;

  /* Separate array and scalar results.  */
  if (scalar_mold && tmp == NULL_TREE)
    goto scalar_transfer;

  size_bytes = gfc_create_var (gfc_array_index_type, NULL);
  if (tmp != NULL_TREE)
    tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type,
			   tmp, dest_word_len);
  else
    tmp = source_bytes;

  gfc_add_modify (&se->pre, size_bytes, tmp);
  gfc_add_modify (&se->pre, size_words,
		       fold_build2_loc (input_location, CEIL_DIV_EXPR,
					gfc_array_index_type,
					size_bytes, dest_word_len));

  /* Evaluate the bounds of the result.  If the loop range exists, we have
     to check if it is too large.  If so, we modify loop->to be consistent
     with min(size, size(source)).  Otherwise, size is made consistent with
     the loop range, so that the right number of bytes is transferred.*/
  n = se->loop->order[0];
  if (se->loop->to[n] != NULL_TREE)
    {
      tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			     se->loop->to[n], se->loop->from[n]);
      tmp = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			     tmp, gfc_index_one_node);
      tmp = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
			 tmp, size_words);
      gfc_add_modify (&se->pre, size_words, tmp);
      gfc_add_modify (&se->pre, size_bytes,
			   fold_build2_loc (input_location, MULT_EXPR,
					    gfc_array_index_type,
					    size_words, dest_word_len));
      upper = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type,
			       size_words, se->loop->from[n]);
      upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			       upper, gfc_index_one_node);
    }
  else
    {
      upper = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			       size_words, gfc_index_one_node);
      se->loop->from[n] = gfc_index_zero_node;
    }

  se->loop->to[n] = upper;

  /* Build a destination descriptor, using the pointer, source, as the
     data field.  */
  gfc_trans_create_temp_array (&se->pre, &se->post, se->ss, mold_type,
			       NULL_TREE, false, true, false, &expr->where);

  /* Cast the pointer to the result.  */
  tmp = gfc_conv_descriptor_data_get (info->descriptor);
  tmp = fold_convert (pvoid_type_node, tmp);

  /* Use memcpy to do the transfer.  */
  tmp
    = build_call_expr_loc (input_location,
			   builtin_decl_explicit (BUILT_IN_MEMCPY), 3, tmp,
			   fold_convert (pvoid_type_node, source),
			   fold_convert (size_type_node,
					 fold_build2_loc (input_location,
							  MIN_EXPR,
							  gfc_array_index_type,
							  size_bytes,
							  source_bytes)));
  gfc_add_expr_to_block (&se->pre, tmp);

  se->expr = info->descriptor;
  if (expr->ts.type == BT_CHARACTER)
    se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len);

  return;

/* Deal with scalar results.  */
scalar_transfer:
  extent = fold_build2_loc (input_location, MIN_EXPR, gfc_array_index_type,
			    dest_word_len, source_bytes);
  extent = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
			    extent, gfc_index_zero_node);

  if (expr->ts.type == BT_CHARACTER)
    {
      tree direct, indirect, free;

      ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
      tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
				"transfer");

      /* If source is longer than the destination, use a pointer to
	 the source directly.  */
      gfc_init_block (&block);
      gfc_add_modify (&block, tmpdecl, ptr);
      direct = gfc_finish_block (&block);

      /* Otherwise, allocate a string with the length of the destination
	 and copy the source into it.  */
      gfc_init_block (&block);
      tmp = gfc_get_pchar_type (expr->ts.kind);
      tmp = gfc_call_malloc (&block, tmp, dest_word_len);
      gfc_add_modify (&block, tmpdecl,
		      fold_convert (TREE_TYPE (ptr), tmp));
      tmp = build_call_expr_loc (input_location,
			     builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
			     fold_convert (pvoid_type_node, tmpdecl),
			     fold_convert (pvoid_type_node, ptr),
			     fold_convert (size_type_node, extent));
      gfc_add_expr_to_block (&block, tmp);
      indirect = gfc_finish_block (&block);

      /* Wrap it up with the condition.  */
      tmp = fold_build2_loc (input_location, LE_EXPR, logical_type_node,
			     dest_word_len, source_bytes);
      tmp = build3_v (COND_EXPR, tmp, direct, indirect);
      gfc_add_expr_to_block (&se->pre, tmp);

      /* Free the temporary string, if necessary.  */
      free = gfc_call_free (tmpdecl);
      tmp = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			     dest_word_len, source_bytes);
      tmp = build3_v (COND_EXPR, tmp, free, build_empty_stmt (input_location));
      gfc_add_expr_to_block (&se->post, tmp);

      se->expr = tmpdecl;
      se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len);
    }
  else
    {
      tmpdecl = gfc_create_var (mold_type, "transfer");

      ptr = convert (build_pointer_type (mold_type), source);

      /* For CLASS results, allocate the needed memory first.  */
      if (mold_expr->ts.type == BT_CLASS)
	{
	  tree cdata;
	  cdata = gfc_class_data_get (tmpdecl);
	  tmp = gfc_call_malloc (&se->pre, TREE_TYPE (cdata), dest_word_len);
	  gfc_add_modify (&se->pre, cdata, tmp);
	}

      /* Use memcpy to do the transfer.  */
      if (mold_expr->ts.type == BT_CLASS)
	tmp = gfc_class_data_get (tmpdecl);
      else
	tmp = gfc_build_addr_expr (NULL_TREE, tmpdecl);

      tmp = build_call_expr_loc (input_location,
			     builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
			     fold_convert (pvoid_type_node, tmp),
			     fold_convert (pvoid_type_node, ptr),
			     fold_convert (size_type_node, extent));
      gfc_add_expr_to_block (&se->pre, tmp);

      /* For CLASS results, set the _vptr.  */
      if (mold_expr->ts.type == BT_CLASS)
	{
	  tree vptr;
	  gfc_symbol *vtab;
	  vptr = gfc_class_vptr_get (tmpdecl);
	  vtab = gfc_find_derived_vtab (source_expr->ts.u.derived);
	  gcc_assert (vtab);
	  tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
	  gfc_add_modify (&se->pre, vptr, fold_convert (TREE_TYPE (vptr), tmp));
	}

      se->expr = tmpdecl;
    }
}


/* Generate a call to caf_is_present.  */

static tree
trans_caf_is_present (gfc_se *se, gfc_expr *expr)
{
  tree caf_reference, caf_decl, token, image_index;

  /* Compile the reference chain.  */
  caf_reference = conv_expr_ref_to_caf_ref (&se->pre, expr);
  gcc_assert (caf_reference != NULL_TREE);

  caf_decl = gfc_get_tree_for_caf_expr (expr);
  if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
    caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);
  image_index = gfc_caf_get_image_index (&se->pre, expr, caf_decl);
  gfc_get_caf_token_offset (se, &token, NULL, caf_decl, NULL,
			    expr);

  return build_call_expr_loc (input_location, gfor_fndecl_caf_is_present,
			      3, token, image_index, caf_reference);
}


/* Test whether this ref-chain refs this image only.  */

static bool
caf_this_image_ref (gfc_ref *ref)
{
  for ( ; ref; ref = ref->next)
    if (ref->type == REF_ARRAY && ref->u.ar.codimen)
      return ref->u.ar.dimen_type[ref->u.ar.dimen] == DIMEN_THIS_IMAGE;

  return false;
}


/* Generate code for the ALLOCATED intrinsic.
   Generate inline code that directly check the address of the argument.  */

static void
gfc_conv_allocated (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *arg1;
  gfc_se arg1se;
  tree tmp;
  symbol_attribute caf_attr;

  gfc_init_se (&arg1se, NULL);
  arg1 = expr->value.function.actual;

  if (arg1->expr->ts.type == BT_CLASS)
    {
      /* Make sure that class array expressions have both a _data
	 component reference and an array reference....  */
      if (CLASS_DATA (arg1->expr)->attr.dimension)
	gfc_add_class_array_ref (arg1->expr);
      /* .... whilst scalars only need the _data component.  */
      else
	gfc_add_data_component (arg1->expr);
    }

  /* When arg1 references an allocatable component in a coarray, then call
     the caf-library function caf_is_present ().  */
  if (flag_coarray == GFC_FCOARRAY_LIB && arg1->expr->expr_type == EXPR_FUNCTION
      && arg1->expr->value.function.isym
      && arg1->expr->value.function.isym->id == GFC_ISYM_CAF_GET)
    caf_attr = gfc_caf_attr (arg1->expr->value.function.actual->expr);
  else
    gfc_clear_attr (&caf_attr);
  if (flag_coarray == GFC_FCOARRAY_LIB && caf_attr.codimension
      && !caf_this_image_ref (arg1->expr->value.function.actual->expr->ref))
    tmp = trans_caf_is_present (se, arg1->expr->value.function.actual->expr);
  else
    {
      if (arg1->expr->rank == 0)
	{
	  /* Allocatable scalar.  */
	  arg1se.want_pointer = 1;
	  gfc_conv_expr (&arg1se, arg1->expr);
	  tmp = arg1se.expr;
	}
      else
	{
	  /* Allocatable array.  */
	  arg1se.descriptor_only = 1;
	  gfc_conv_expr_descriptor (&arg1se, arg1->expr);
	  tmp = gfc_conv_descriptor_data_get (arg1se.expr);
	}

      tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp,
			     fold_convert (TREE_TYPE (tmp), null_pointer_node));
    }

  /* Components of pointer array references sometimes come back with a pre block.  */
  if (arg1se.pre.head)
    gfc_add_block_to_block (&se->pre, &arg1se.pre);

  se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
}


/* Generate code for the ASSOCIATED intrinsic.
   If both POINTER and TARGET are arrays, generate a call to library function
   _gfor_associated, and pass descriptors of POINTER and TARGET to it.
   In other cases, generate inline code that directly compare the address of
   POINTER with the address of TARGET.  */

static void
gfc_conv_associated (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *arg1;
  gfc_actual_arglist *arg2;
  gfc_se arg1se;
  gfc_se arg2se;
  tree tmp2;
  tree tmp;
  tree nonzero_charlen;
  tree nonzero_arraylen;
  gfc_ss *ss;
  bool scalar;

  gfc_init_se (&arg1se, NULL);
  gfc_init_se (&arg2se, NULL);
  arg1 = expr->value.function.actual;
  arg2 = arg1->next;

  /* Check whether the expression is a scalar or not; we cannot use
     arg1->expr->rank as it can be nonzero for proc pointers.  */
  ss = gfc_walk_expr (arg1->expr);
  scalar = ss == gfc_ss_terminator;
  if (!scalar)
    gfc_free_ss_chain (ss);

  if (!arg2->expr)
    {
      /* No optional target.  */
      if (scalar)
        {
	  /* A pointer to a scalar.  */
	  arg1se.want_pointer = 1;
	  gfc_conv_expr (&arg1se, arg1->expr);
	  if (arg1->expr->symtree->n.sym->attr.proc_pointer
	      && arg1->expr->symtree->n.sym->attr.dummy)
	    arg1se.expr = build_fold_indirect_ref_loc (input_location,
						       arg1se.expr);
  	  if (arg1->expr->ts.type == BT_CLASS)
	    {
	      tmp2 = gfc_class_data_get (arg1se.expr);
	      if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (tmp2)))
		tmp2 = gfc_conv_descriptor_data_get (tmp2);
	    }
	  else
	    tmp2 = arg1se.expr;
        }
      else
        {
          /* A pointer to an array.  */
          gfc_conv_expr_descriptor (&arg1se, arg1->expr);
          tmp2 = gfc_conv_descriptor_data_get (arg1se.expr);
        }
      gfc_add_block_to_block (&se->pre, &arg1se.pre);
      gfc_add_block_to_block (&se->post, &arg1se.post);
      tmp = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp2,
			     fold_convert (TREE_TYPE (tmp2), null_pointer_node));
      se->expr = tmp;
    }
  else
    {
      /* An optional target.  */
      if (arg2->expr->ts.type == BT_CLASS)
	gfc_add_data_component (arg2->expr);

      nonzero_charlen = NULL_TREE;
      if (arg1->expr->ts.type == BT_CHARACTER)
	nonzero_charlen = fold_build2_loc (input_location, NE_EXPR,
					   logical_type_node,
					   arg1->expr->ts.u.cl->backend_decl,
					   build_zero_cst
					   (TREE_TYPE (arg1->expr->ts.u.cl->backend_decl)));
      if (scalar)
        {
	  /* A pointer to a scalar.  */
	  arg1se.want_pointer = 1;
	  gfc_conv_expr (&arg1se, arg1->expr);
	  if (arg1->expr->symtree->n.sym->attr.proc_pointer
	      && arg1->expr->symtree->n.sym->attr.dummy)
	    arg1se.expr = build_fold_indirect_ref_loc (input_location,
						       arg1se.expr);
	  if (arg1->expr->ts.type == BT_CLASS)
	    arg1se.expr = gfc_class_data_get (arg1se.expr);

	  arg2se.want_pointer = 1;
	  gfc_conv_expr (&arg2se, arg2->expr);
	  if (arg2->expr->symtree->n.sym->attr.proc_pointer
	      && arg2->expr->symtree->n.sym->attr.dummy)
	    arg2se.expr = build_fold_indirect_ref_loc (input_location,
						       arg2se.expr);
	  gfc_add_block_to_block (&se->pre, &arg1se.pre);
	  gfc_add_block_to_block (&se->post, &arg1se.post);
	  gfc_add_block_to_block (&se->pre, &arg2se.pre);
	  gfc_add_block_to_block (&se->post, &arg2se.post);
          tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				 arg1se.expr, arg2se.expr);
          tmp2 = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				  arg1se.expr, null_pointer_node);
          se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				      logical_type_node, tmp, tmp2);
        }
      else
        {
	  /* An array pointer of zero length is not associated if target is
	     present.  */
	  arg1se.descriptor_only = 1;
	  gfc_conv_expr_lhs (&arg1se, arg1->expr);
	  if (arg1->expr->rank == -1)
	    {
	      tmp = gfc_conv_descriptor_rank (arg1se.expr);
	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
				     TREE_TYPE (tmp), tmp, gfc_index_one_node);
	    }
	  else
	    tmp = gfc_rank_cst[arg1->expr->rank - 1];
	  tmp = gfc_conv_descriptor_stride_get (arg1se.expr, tmp);
	  nonzero_arraylen = fold_build2_loc (input_location, NE_EXPR,
					      logical_type_node, tmp,
					      build_int_cst (TREE_TYPE (tmp), 0));

	  /* A pointer to an array, call library function _gfor_associated.  */
	  arg1se.want_pointer = 1;
	  gfc_conv_expr_descriptor (&arg1se, arg1->expr);
	  gfc_add_block_to_block (&se->pre, &arg1se.pre);
	  gfc_add_block_to_block (&se->post, &arg1se.post);

	  arg2se.want_pointer = 1;
	  gfc_conv_expr_descriptor (&arg2se, arg2->expr);
	  gfc_add_block_to_block (&se->pre, &arg2se.pre);
	  gfc_add_block_to_block (&se->post, &arg2se.post);
	  se->expr = build_call_expr_loc (input_location,
				      gfor_fndecl_associated, 2,
				      arg1se.expr, arg2se.expr);
	  se->expr = convert (logical_type_node, se->expr);
	  se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				      logical_type_node, se->expr,
				      nonzero_arraylen);
        }

      /* If target is present zero character length pointers cannot
	 be associated.  */
      if (nonzero_charlen != NULL_TREE)
	se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				    logical_type_node,
				    se->expr, nonzero_charlen);
    }

  se->expr = convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Generate code for the SAME_TYPE_AS intrinsic.
   Generate inline code that directly checks the vindices.  */

static void
gfc_conv_same_type_as (gfc_se *se, gfc_expr *expr)
{
  gfc_expr *a, *b;
  gfc_se se1, se2;
  tree tmp;
  tree conda = NULL_TREE, condb = NULL_TREE;

  gfc_init_se (&se1, NULL);
  gfc_init_se (&se2, NULL);

  a = expr->value.function.actual->expr;
  b = expr->value.function.actual->next->expr;

  if (UNLIMITED_POLY (a))
    {
      tmp = gfc_class_vptr_get (a->symtree->n.sym->backend_decl);
      conda = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			       tmp, build_int_cst (TREE_TYPE (tmp), 0));
    }

  if (UNLIMITED_POLY (b))
    {
      tmp = gfc_class_vptr_get (b->symtree->n.sym->backend_decl);
      condb = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			       tmp, build_int_cst (TREE_TYPE (tmp), 0));
    }

  if (a->ts.type == BT_CLASS)
    {
      gfc_add_vptr_component (a);
      gfc_add_hash_component (a);
    }
  else if (a->ts.type == BT_DERIVED)
    a = gfc_get_int_expr (gfc_default_integer_kind, NULL,
			  a->ts.u.derived->hash_value);

  if (b->ts.type == BT_CLASS)
    {
      gfc_add_vptr_component (b);
      gfc_add_hash_component (b);
    }
  else if (b->ts.type == BT_DERIVED)
    b = gfc_get_int_expr (gfc_default_integer_kind, NULL,
			  b->ts.u.derived->hash_value);

  gfc_conv_expr (&se1, a);
  gfc_conv_expr (&se2, b);

  tmp = fold_build2_loc (input_location, EQ_EXPR,
			 logical_type_node, se1.expr,
			 fold_convert (TREE_TYPE (se1.expr), se2.expr));

  if (conda)
    tmp = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
			   logical_type_node, conda, tmp);

  if (condb)
    tmp = fold_build2_loc (input_location, TRUTH_ANDIF_EXPR,
			   logical_type_node, condb, tmp);

  se->expr = convert (gfc_typenode_for_spec (&expr->ts), tmp);
}


/* Generate code for SELECTED_CHAR_KIND (NAME) intrinsic function.  */

static void
gfc_conv_intrinsic_sc_kind (gfc_se *se, gfc_expr *expr)
{
  tree args[2];

  gfc_conv_intrinsic_function_args (se, expr, args, 2);
  se->expr = build_call_expr_loc (input_location,
			      gfor_fndecl_sc_kind, 2, args[0], args[1]);
  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Generate code for SELECTED_INT_KIND (R) intrinsic function.  */

static void
gfc_conv_intrinsic_si_kind (gfc_se *se, gfc_expr *expr)
{
  tree arg, type;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);

  /* The argument to SELECTED_INT_KIND is INTEGER(4).  */
  type = gfc_get_int_type (4);
  arg = gfc_build_addr_expr (NULL_TREE, fold_convert (type, arg));

  /* Convert it to the required type.  */
  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = build_call_expr_loc (input_location,
			      gfor_fndecl_si_kind, 1, arg);
  se->expr = fold_convert (type, se->expr);
}


/* Generate code for SELECTED_REAL_KIND (P, R, RADIX) intrinsic function.  */

static void
gfc_conv_intrinsic_sr_kind (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *actual;
  tree type;
  gfc_se argse;
  vec<tree, va_gc> *args = NULL;

  for (actual = expr->value.function.actual; actual; actual = actual->next)
    {
      gfc_init_se (&argse, se);

      /* Pass a NULL pointer for an absent arg.  */
      if (actual->expr == NULL)
        argse.expr = null_pointer_node;
      else
	{
	  gfc_typespec ts;
          gfc_clear_ts (&ts);

	  if (actual->expr->ts.kind != gfc_c_int_kind)
	    {
  	      /* The arguments to SELECTED_REAL_KIND are INTEGER(4).  */
	      ts.type = BT_INTEGER;
	      ts.kind = gfc_c_int_kind;
	      gfc_convert_type (actual->expr, &ts, 2);
	    }
	  gfc_conv_expr_reference (&argse, actual->expr);
	}

      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      vec_safe_push (args, argse.expr);
    }

  /* Convert it to the required type.  */
  type = gfc_typenode_for_spec (&expr->ts);
  se->expr = build_call_expr_loc_vec (input_location,
				      gfor_fndecl_sr_kind, args);
  se->expr = fold_convert (type, se->expr);
}


/* Generate code for TRIM (A) intrinsic function.  */

static void
gfc_conv_intrinsic_trim (gfc_se * se, gfc_expr * expr)
{
  tree var;
  tree len;
  tree addr;
  tree tmp;
  tree cond;
  tree fndecl;
  tree function;
  tree *args;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr) + 2;
  args = XALLOCAVEC (tree, num_args);

  var = gfc_create_var (gfc_get_pchar_type (expr->ts.kind), "pstr");
  addr = gfc_build_addr_expr (ppvoid_type_node, var);
  len = gfc_create_var (gfc_charlen_type_node, "len");

  gfc_conv_intrinsic_function_args (se, expr, &args[2], num_args - 2);
  args[0] = gfc_build_addr_expr (NULL_TREE, len);
  args[1] = addr;

  if (expr->ts.kind == 1)
    function = gfor_fndecl_string_trim;
  else if (expr->ts.kind == 4)
    function = gfor_fndecl_string_trim_char4;
  else
    gcc_unreachable ();

  fndecl = build_addr (function);
  tmp = build_call_array_loc (input_location,
			  TREE_TYPE (TREE_TYPE (function)), fndecl,
			  num_args, args);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Free the temporary afterwards, if necessary.  */
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  len, build_int_cst (TREE_TYPE (len), 0));
  tmp = gfc_call_free (var);
  tmp = build3_v (COND_EXPR, cond, tmp, build_empty_stmt (input_location));
  gfc_add_expr_to_block (&se->post, tmp);

  se->expr = var;
  se->string_length = len;
}


/* Generate code for REPEAT (STRING, NCOPIES) intrinsic function.  */

static void
gfc_conv_intrinsic_repeat (gfc_se * se, gfc_expr * expr)
{
  tree args[3], ncopies, dest, dlen, src, slen, ncopies_type;
  tree type, cond, tmp, count, exit_label, n, max, largest;
  tree size;
  stmtblock_t block, body;
  int i;

  /* We store in charsize the size of a character.  */
  i = gfc_validate_kind (BT_CHARACTER, expr->ts.kind, false);
  size = build_int_cst (sizetype, gfc_character_kinds[i].bit_size / 8);

  /* Get the arguments.  */
  gfc_conv_intrinsic_function_args (se, expr, args, 3);
  slen = fold_convert (sizetype, gfc_evaluate_now (args[0], &se->pre));
  src = args[1];
  ncopies = gfc_evaluate_now (args[2], &se->pre);
  ncopies_type = TREE_TYPE (ncopies);

  /* Check that NCOPIES is not negative.  */
  cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node, ncopies,
			  build_int_cst (ncopies_type, 0));
  gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
			   "Argument NCOPIES of REPEAT intrinsic is negative "
			   "(its value is %ld)",
			   fold_convert (long_integer_type_node, ncopies));

  /* If the source length is zero, any non negative value of NCOPIES
     is valid, and nothing happens.  */
  n = gfc_create_var (ncopies_type, "ncopies");
  cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, slen,
			  size_zero_node);
  tmp = fold_build3_loc (input_location, COND_EXPR, ncopies_type, cond,
			 build_int_cst (ncopies_type, 0), ncopies);
  gfc_add_modify (&se->pre, n, tmp);
  ncopies = n;

  /* Check that ncopies is not too large: ncopies should be less than
     (or equal to) MAX / slen, where MAX is the maximal integer of
     the gfc_charlen_type_node type.  If slen == 0, we need a special
     case to avoid the division by zero.  */
  max = fold_build2_loc (input_location, TRUNC_DIV_EXPR, sizetype,
			 fold_convert (sizetype,
				       TYPE_MAX_VALUE (gfc_charlen_type_node)),
			 slen);
  largest = TYPE_PRECISION (sizetype) > TYPE_PRECISION (ncopies_type)
	      ? sizetype : ncopies_type;
  cond = fold_build2_loc (input_location, GT_EXPR, logical_type_node,
			  fold_convert (largest, ncopies),
			  fold_convert (largest, max));
  tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, slen,
			 size_zero_node);
  cond = fold_build3_loc (input_location, COND_EXPR, logical_type_node, tmp,
			  logical_false_node, cond);
  gfc_trans_runtime_check (true, false, cond, &se->pre, &expr->where,
			   "Argument NCOPIES of REPEAT intrinsic is too large");

  /* Compute the destination length.  */
  dlen = fold_build2_loc (input_location, MULT_EXPR, gfc_charlen_type_node,
			  fold_convert (gfc_charlen_type_node, slen),
			  fold_convert (gfc_charlen_type_node, ncopies));
  type = gfc_get_character_type (expr->ts.kind, expr->ts.u.cl);
  dest = gfc_conv_string_tmp (se, build_pointer_type (type), dlen);

  /* Generate the code to do the repeat operation:
       for (i = 0; i < ncopies; i++)
         memmove (dest + (i * slen * size), src, slen*size);  */
  gfc_start_block (&block);
  count = gfc_create_var (sizetype, "count");
  gfc_add_modify (&block, count, size_zero_node);
  exit_label = gfc_build_label_decl (NULL_TREE);

  /* Start the loop body.  */
  gfc_start_block (&body);

  /* Exit the loop if count >= ncopies.  */
  cond = fold_build2_loc (input_location, GE_EXPR, logical_type_node, count,
			  fold_convert (sizetype, ncopies));
  tmp = build1_v (GOTO_EXPR, exit_label);
  TREE_USED (exit_label) = 1;
  tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond, tmp,
			 build_empty_stmt (input_location));
  gfc_add_expr_to_block (&body, tmp);

  /* Call memmove (dest + (i*slen*size), src, slen*size).  */
  tmp = fold_build2_loc (input_location, MULT_EXPR, sizetype, slen,
			 count);
  tmp = fold_build2_loc (input_location, MULT_EXPR, sizetype, tmp,
			 size);
  tmp = fold_build_pointer_plus_loc (input_location,
				     fold_convert (pvoid_type_node, dest), tmp);
  tmp = build_call_expr_loc (input_location,
			     builtin_decl_explicit (BUILT_IN_MEMMOVE),
			     3, tmp, src,
			     fold_build2_loc (input_location, MULT_EXPR,
					      size_type_node, slen, size));
  gfc_add_expr_to_block (&body, tmp);

  /* Increment count.  */
  tmp = fold_build2_loc (input_location, PLUS_EXPR, sizetype,
			 count, size_one_node);
  gfc_add_modify (&body, count, tmp);

  /* Build the loop.  */
  tmp = build1_v (LOOP_EXPR, gfc_finish_block (&body));
  gfc_add_expr_to_block (&block, tmp);

  /* Add the exit label.  */
  tmp = build1_v (LABEL_EXPR, exit_label);
  gfc_add_expr_to_block (&block, tmp);

  /* Finish the block.  */
  tmp = gfc_finish_block (&block);
  gfc_add_expr_to_block (&se->pre, tmp);

  /* Set the result value.  */
  se->expr = dest;
  se->string_length = dlen;
}


/* Generate code for the IARGC intrinsic.  */

static void
gfc_conv_intrinsic_iargc (gfc_se * se, gfc_expr * expr)
{
  tree tmp;
  tree fndecl;
  tree type;

  /* Call the library function.  This always returns an INTEGER(4).  */
  fndecl = gfor_fndecl_iargc;
  tmp = build_call_expr_loc (input_location,
			 fndecl, 0);

  /* Convert it to the required type.  */
  type = gfc_typenode_for_spec (&expr->ts);
  tmp = fold_convert (type, tmp);

  se->expr = tmp;
}


/* Generate code for the KILL intrinsic.  */

static void
conv_intrinsic_kill (gfc_se *se, gfc_expr *expr)
{
  tree *args;
  tree int4_type_node = gfc_get_int_type (4);
  tree pid;
  tree sig;
  tree tmp;
  unsigned int num_args;

  num_args = gfc_intrinsic_argument_list_length (expr);
  args = XALLOCAVEC (tree, num_args);
  gfc_conv_intrinsic_function_args (se, expr, args, num_args);

  /* Convert PID to a INTEGER(4) entity.  */
  pid = convert (int4_type_node, args[0]);

  /* Convert SIG to a INTEGER(4) entity.  */
  sig = convert (int4_type_node, args[1]);

  tmp = build_call_expr_loc (input_location, gfor_fndecl_kill, 2, pid, sig);

  se->expr = fold_convert (TREE_TYPE (args[0]), tmp);
}


static tree
conv_intrinsic_kill_sub (gfc_code *code)
{
  stmtblock_t block;
  gfc_se se, se_stat;
  tree int4_type_node = gfc_get_int_type (4);
  tree pid;
  tree sig;
  tree statp;
  tree tmp;

  /* Make the function call.  */
  gfc_init_block (&block);
  gfc_init_se (&se, NULL);

  /* Convert PID to a INTEGER(4) entity.  */
  gfc_conv_expr (&se, code->ext.actual->expr);
  gfc_add_block_to_block (&block, &se.pre);
  pid = fold_convert (int4_type_node, gfc_evaluate_now (se.expr, &block));
  gfc_add_block_to_block (&block, &se.post);

  /* Convert SIG to a INTEGER(4) entity.  */
  gfc_conv_expr (&se, code->ext.actual->next->expr);
  gfc_add_block_to_block (&block, &se.pre);
  sig = fold_convert (int4_type_node, gfc_evaluate_now (se.expr, &block));
  gfc_add_block_to_block (&block, &se.post);

  /* Deal with an optional STATUS.  */
  if (code->ext.actual->next->next->expr)
    {
      gfc_init_se (&se_stat, NULL);
      gfc_conv_expr (&se_stat, code->ext.actual->next->next->expr);
      statp = gfc_create_var (gfc_get_int_type (4), "_statp");
    }
  else
    statp = NULL_TREE;

  tmp = build_call_expr_loc (input_location, gfor_fndecl_kill_sub, 3, pid, sig,
	statp ? gfc_build_addr_expr (NULL_TREE, statp) : null_pointer_node);

  gfc_add_expr_to_block (&block, tmp);

  if (statp && statp != se_stat.expr)
    gfc_add_modify (&block, se_stat.expr,
		    fold_convert (TREE_TYPE (se_stat.expr), statp));

  return gfc_finish_block (&block);
}



/* The loc intrinsic returns the address of its argument as
   gfc_index_integer_kind integer.  */

static void
gfc_conv_intrinsic_loc (gfc_se * se, gfc_expr * expr)
{
  tree temp_var;
  gfc_expr *arg_expr;

  gcc_assert (!se->ss);

  arg_expr = expr->value.function.actual->expr;
  if (arg_expr->rank == 0)
    {
      if (arg_expr->ts.type == BT_CLASS)
	gfc_add_data_component (arg_expr);
      gfc_conv_expr_reference (se, arg_expr);
    }
  else
    gfc_conv_array_parameter (se, arg_expr, true, NULL, NULL, NULL);
  se->expr = convert (gfc_get_int_type (gfc_index_integer_kind), se->expr);

  /* Create a temporary variable for loc return value.  Without this,
     we get an error an ICE in gcc/expr.c(expand_expr_addr_expr_1).  */
  temp_var = gfc_create_var (gfc_get_int_type (gfc_index_integer_kind), NULL);
  gfc_add_modify (&se->pre, temp_var, se->expr);
  se->expr = temp_var;
}


/* The following routine generates code for the intrinsic
   functions from the ISO_C_BINDING module:
    * C_LOC
    * C_FUNLOC
    * C_ASSOCIATED  */

static void
conv_isocbinding_function (gfc_se *se, gfc_expr *expr)
{
  gfc_actual_arglist *arg = expr->value.function.actual;

  if (expr->value.function.isym->id == GFC_ISYM_C_LOC)
    {
      if (arg->expr->rank == 0)
	gfc_conv_expr_reference (se, arg->expr);
      else if (gfc_is_simply_contiguous (arg->expr, false, false))
	gfc_conv_array_parameter (se, arg->expr, true, NULL, NULL, NULL);
      else
	{
	  gfc_conv_expr_descriptor (se, arg->expr);
	  se->expr = gfc_conv_descriptor_data_get (se->expr);
	}

      /* TODO -- the following two lines shouldn't be necessary, but if
	 they're removed, a bug is exposed later in the code path.
	 This workaround was thus introduced, but will have to be
	 removed; please see PR 35150 for details about the issue.  */
      se->expr = convert (pvoid_type_node, se->expr);
      se->expr = gfc_evaluate_now (se->expr, &se->pre);
    }
  else if (expr->value.function.isym->id == GFC_ISYM_C_FUNLOC)
    gfc_conv_expr_reference (se, arg->expr);
  else if (expr->value.function.isym->id == GFC_ISYM_C_ASSOCIATED)
    {
      gfc_se arg1se;
      gfc_se arg2se;

      /* Build the addr_expr for the first argument.  The argument is
	 already an *address* so we don't need to set want_pointer in
	 the gfc_se.  */
      gfc_init_se (&arg1se, NULL);
      gfc_conv_expr (&arg1se, arg->expr);
      gfc_add_block_to_block (&se->pre, &arg1se.pre);
      gfc_add_block_to_block (&se->post, &arg1se.post);

      /* See if we were given two arguments.  */
      if (arg->next->expr == NULL)
	/* Only given one arg so generate a null and do a
	   not-equal comparison against the first arg.  */
	se->expr = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
				    arg1se.expr,
				    fold_convert (TREE_TYPE (arg1se.expr),
						  null_pointer_node));
      else
	{
	  tree eq_expr;
	  tree not_null_expr;

	  /* Given two arguments so build the arg2se from second arg.  */
	  gfc_init_se (&arg2se, NULL);
	  gfc_conv_expr (&arg2se, arg->next->expr);
	  gfc_add_block_to_block (&se->pre, &arg2se.pre);
	  gfc_add_block_to_block (&se->post, &arg2se.post);

	  /* Generate test to compare that the two args are equal.  */
	  eq_expr = fold_build2_loc (input_location, EQ_EXPR, logical_type_node,
				     arg1se.expr, arg2se.expr);
	  /* Generate test to ensure that the first arg is not null.  */
	  not_null_expr = fold_build2_loc (input_location, NE_EXPR,
					   logical_type_node,
					   arg1se.expr, null_pointer_node);

	  /* Finally, the generated test must check that both arg1 is not
	     NULL and that it is equal to the second arg.  */
	  se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
				      logical_type_node,
				      not_null_expr, eq_expr);
	}
    }
  else
    gcc_unreachable ();
}


/* The following routine generates code for the intrinsic
   subroutines from the ISO_C_BINDING module:
    * C_F_POINTER
    * C_F_PROCPOINTER.  */

static tree
conv_isocbinding_subroutine (gfc_code *code)
{
  gfc_se se;
  gfc_se cptrse;
  gfc_se fptrse;
  gfc_se shapese;
  gfc_ss *shape_ss;
  tree desc, dim, tmp, stride, offset;
  stmtblock_t body, block;
  gfc_loopinfo loop;
  gfc_actual_arglist *arg = code->ext.actual;

  gfc_init_se (&se, NULL);
  gfc_init_se (&cptrse, NULL);
  gfc_conv_expr (&cptrse, arg->expr);
  gfc_add_block_to_block (&se.pre, &cptrse.pre);
  gfc_add_block_to_block (&se.post, &cptrse.post);

  gfc_init_se (&fptrse, NULL);
  if (arg->next->expr->rank == 0)
    {
      fptrse.want_pointer = 1;
      gfc_conv_expr (&fptrse, arg->next->expr);
      gfc_add_block_to_block (&se.pre, &fptrse.pre);
      gfc_add_block_to_block (&se.post, &fptrse.post);
      if (arg->next->expr->symtree->n.sym->attr.proc_pointer
	  && arg->next->expr->symtree->n.sym->attr.dummy)
	fptrse.expr = build_fold_indirect_ref_loc (input_location,
						       fptrse.expr);
      se.expr = fold_build2_loc (input_location, MODIFY_EXPR,
				 TREE_TYPE (fptrse.expr),
				 fptrse.expr,
				 fold_convert (TREE_TYPE (fptrse.expr),
					       cptrse.expr));
      gfc_add_expr_to_block (&se.pre, se.expr);
      gfc_add_block_to_block (&se.pre, &se.post);
      return gfc_finish_block (&se.pre);
    }

  gfc_start_block (&block);

  /* Get the descriptor of the Fortran pointer.  */
  fptrse.descriptor_only = 1;
  gfc_conv_expr_descriptor (&fptrse, arg->next->expr);
  gfc_add_block_to_block (&block, &fptrse.pre);
  desc = fptrse.expr;

  /* Set the span field.  */
  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc)));
  tmp = fold_convert (gfc_array_index_type, tmp);
  gfc_conv_descriptor_span_set (&block, desc, tmp);

  /* Set data value, dtype, and offset.  */
  tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc));
  gfc_conv_descriptor_data_set (&block, desc, fold_convert (tmp, cptrse.expr));
  gfc_add_modify (&block, gfc_conv_descriptor_dtype (desc),
		  gfc_get_dtype (TREE_TYPE (desc)));

  /* Start scalarization of the bounds, using the shape argument.  */

  shape_ss = gfc_walk_expr (arg->next->next->expr);
  gcc_assert (shape_ss != gfc_ss_terminator);
  gfc_init_se (&shapese, NULL);

  gfc_init_loopinfo (&loop);
  gfc_add_ss_to_loop (&loop, shape_ss);
  gfc_conv_ss_startstride (&loop);
  gfc_conv_loop_setup (&loop, &arg->next->expr->where);
  gfc_mark_ss_chain_used (shape_ss, 1);

  gfc_copy_loopinfo_to_se (&shapese, &loop);
  shapese.ss = shape_ss;

  stride = gfc_create_var (gfc_array_index_type, "stride");
  offset = gfc_create_var (gfc_array_index_type, "offset");
  gfc_add_modify (&block, stride, gfc_index_one_node);
  gfc_add_modify (&block, offset, gfc_index_zero_node);

  /* Loop body.  */
  gfc_start_scalarized_body (&loop, &body);

  dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type,
			     loop.loopvar[0], loop.from[0]);

  /* Set bounds and stride.  */
  gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node);
  gfc_conv_descriptor_stride_set (&body, desc, dim, stride);

  gfc_conv_expr (&shapese, arg->next->next->expr);
  gfc_add_block_to_block (&body, &shapese.pre);
  gfc_conv_descriptor_ubound_set (&body, desc, dim, shapese.expr);
  gfc_add_block_to_block (&body, &shapese.post);

  /* Calculate offset.  */
  gfc_add_modify (&body, offset,
		  fold_build2_loc (input_location, PLUS_EXPR,
				   gfc_array_index_type, offset, stride));
  /* Update stride.  */
  gfc_add_modify (&body, stride,
		  fold_build2_loc (input_location, MULT_EXPR,
				   gfc_array_index_type, stride,
				   fold_convert (gfc_array_index_type,
						 shapese.expr)));
  /* Finish scalarization loop.  */
  gfc_trans_scalarizing_loops (&loop, &body);
  gfc_add_block_to_block (&block, &loop.pre);
  gfc_add_block_to_block (&block, &loop.post);
  gfc_add_block_to_block (&block, &fptrse.post);
  gfc_cleanup_loop (&loop);

  gfc_add_modify (&block, offset,
		  fold_build1_loc (input_location, NEGATE_EXPR,
				   gfc_array_index_type, offset));
  gfc_conv_descriptor_offset_set (&block, desc, offset);

  gfc_add_expr_to_block (&se.pre, gfc_finish_block (&block));
  gfc_add_block_to_block (&se.pre, &se.post);
  return gfc_finish_block (&se.pre);
}


/* Save and restore floating-point state.  */

tree
gfc_save_fp_state (stmtblock_t *block)
{
  tree type, fpstate, tmp;

  type = build_array_type (char_type_node,
	                   build_range_type (size_type_node, size_zero_node,
					     size_int (GFC_FPE_STATE_BUFFER_SIZE)));
  fpstate = gfc_create_var (type, "fpstate");
  fpstate = gfc_build_addr_expr (pvoid_type_node, fpstate);

  tmp = build_call_expr_loc (input_location, gfor_fndecl_ieee_procedure_entry,
			     1, fpstate);
  gfc_add_expr_to_block (block, tmp);

  return fpstate;
}


void
gfc_restore_fp_state (stmtblock_t *block, tree fpstate)
{
  tree tmp;

  tmp = build_call_expr_loc (input_location, gfor_fndecl_ieee_procedure_exit,
			     1, fpstate);
  gfc_add_expr_to_block (block, tmp);
}


/* Generate code for arguments of IEEE functions.  */

static void
conv_ieee_function_args (gfc_se *se, gfc_expr *expr, tree *argarray,
			 int nargs)
{
  gfc_actual_arglist *actual;
  gfc_expr *e;
  gfc_se argse;
  int arg;

  actual = expr->value.function.actual;
  for (arg = 0; arg < nargs; arg++, actual = actual->next)
    {
      gcc_assert (actual);
      e = actual->expr;

      gfc_init_se (&argse, se);
      gfc_conv_expr_val (&argse, e);

      gfc_add_block_to_block (&se->pre, &argse.pre);
      gfc_add_block_to_block (&se->post, &argse.post);
      argarray[arg] = argse.expr;
    }
}


/* Generate code for intrinsics IEEE_IS_NAN, IEEE_IS_FINITE,
   and IEEE_UNORDERED, which translate directly to GCC type-generic
   built-ins.  */

static void
conv_intrinsic_ieee_builtin (gfc_se * se, gfc_expr * expr,
			     enum built_in_function code, int nargs)
{
  tree args[2];
  gcc_assert ((unsigned) nargs <= sizeof(args)/sizeof(args[0]));

  conv_ieee_function_args (se, expr, args, nargs);
  se->expr = build_call_expr_loc_array (input_location,
					builtin_decl_explicit (code),
					nargs, args);
  STRIP_TYPE_NOPS (se->expr);
  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Generate code for IEEE_IS_NORMAL intrinsic:
     IEEE_IS_NORMAL(x) --> (__builtin_isnormal(x) || x == 0)  */

static void
conv_intrinsic_ieee_is_normal (gfc_se * se, gfc_expr * expr)
{
  tree arg, isnormal, iszero;

  /* Convert arg, evaluate it only once.  */
  conv_ieee_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  isnormal = build_call_expr_loc (input_location,
				  builtin_decl_explicit (BUILT_IN_ISNORMAL),
				  1, arg);
  iszero = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, arg,
			    build_real_from_int_cst (TREE_TYPE (arg),
						     integer_zero_node));
  se->expr = fold_build2_loc (input_location, TRUTH_OR_EXPR,
			      logical_type_node, isnormal, iszero);
  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Generate code for IEEE_IS_NEGATIVE intrinsic:
     IEEE_IS_NEGATIVE(x) --> (__builtin_signbit(x) && !__builtin_isnan(x))  */

static void
conv_intrinsic_ieee_is_negative (gfc_se * se, gfc_expr * expr)
{
  tree arg, signbit, isnan;

  /* Convert arg, evaluate it only once.  */
  conv_ieee_function_args (se, expr, &arg, 1);
  arg = gfc_evaluate_now (arg, &se->pre);

  isnan = build_call_expr_loc (input_location,
			       builtin_decl_explicit (BUILT_IN_ISNAN),
			       1, arg);
  STRIP_TYPE_NOPS (isnan);

  signbit = build_call_expr_loc (input_location,
				 builtin_decl_explicit (BUILT_IN_SIGNBIT),
				 1, arg);
  signbit = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			     signbit, integer_zero_node);

  se->expr = fold_build2_loc (input_location, TRUTH_AND_EXPR,
			      logical_type_node, signbit,
			      fold_build1_loc (input_location, TRUTH_NOT_EXPR,
					       TREE_TYPE(isnan), isnan));

  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), se->expr);
}


/* Generate code for IEEE_LOGB and IEEE_RINT.  */

static void
conv_intrinsic_ieee_logb_rint (gfc_se * se, gfc_expr * expr,
			       enum built_in_function code)
{
  tree arg, decl, call, fpstate;
  int argprec;

  conv_ieee_function_args (se, expr, &arg, 1);
  argprec = TYPE_PRECISION (TREE_TYPE (arg));
  decl = builtin_decl_for_precision (code, argprec);

  /* Save floating-point state.  */
  fpstate = gfc_save_fp_state (&se->pre);

  /* Make the function call.  */
  call = build_call_expr_loc (input_location, decl, 1, arg);
  se->expr = fold_convert (gfc_typenode_for_spec (&expr->ts), call);

  /* Restore floating-point state.  */
  gfc_restore_fp_state (&se->post, fpstate);
}


/* Generate code for IEEE_REM.  */

static void
conv_intrinsic_ieee_rem (gfc_se * se, gfc_expr * expr)
{
  tree args[2], decl, call, fpstate;
  int argprec;

  conv_ieee_function_args (se, expr, args, 2);

  /* If arguments have unequal size, convert them to the larger.  */
  if (TYPE_PRECISION (TREE_TYPE (args[0]))
      > TYPE_PRECISION (TREE_TYPE (args[1])))
    args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
  else if (TYPE_PRECISION (TREE_TYPE (args[1]))
	   > TYPE_PRECISION (TREE_TYPE (args[0])))
    args[0] = fold_convert (TREE_TYPE (args[1]), args[0]);

  argprec = TYPE_PRECISION (TREE_TYPE (args[0]));
  decl = builtin_decl_for_precision (BUILT_IN_REMAINDER, argprec);

  /* Save floating-point state.  */
  fpstate = gfc_save_fp_state (&se->pre);

  /* Make the function call.  */
  call = build_call_expr_loc_array (input_location, decl, 2, args);
  se->expr = fold_convert (TREE_TYPE (args[0]), call);

  /* Restore floating-point state.  */
  gfc_restore_fp_state (&se->post, fpstate);
}


/* Generate code for IEEE_NEXT_AFTER.  */

static void
conv_intrinsic_ieee_next_after (gfc_se * se, gfc_expr * expr)
{
  tree args[2], decl, call, fpstate;
  int argprec;

  conv_ieee_function_args (se, expr, args, 2);

  /* Result has the characteristics of first argument.  */
  args[1] = fold_convert (TREE_TYPE (args[0]), args[1]);
  argprec = TYPE_PRECISION (TREE_TYPE (args[0]));
  decl = builtin_decl_for_precision (BUILT_IN_NEXTAFTER, argprec);

  /* Save floating-point state.  */
  fpstate = gfc_save_fp_state (&se->pre);

  /* Make the function call.  */
  call = build_call_expr_loc_array (input_location, decl, 2, args);
  se->expr = fold_convert (TREE_TYPE (args[0]), call);

  /* Restore floating-point state.  */
  gfc_restore_fp_state (&se->post, fpstate);
}


/* Generate code for IEEE_SCALB.  */

static void
conv_intrinsic_ieee_scalb (gfc_se * se, gfc_expr * expr)
{
  tree args[2], decl, call, huge, type;
  int argprec, n;

  conv_ieee_function_args (se, expr, args, 2);

  /* Result has the characteristics of first argument.  */
  argprec = TYPE_PRECISION (TREE_TYPE (args[0]));
  decl = builtin_decl_for_precision (BUILT_IN_SCALBN, argprec);

  if (TYPE_PRECISION (TREE_TYPE (args[1])) > TYPE_PRECISION (integer_type_node))
    {
      /* We need to fold the integer into the range of a C int.  */
      args[1] = gfc_evaluate_now (args[1], &se->pre);
      type = TREE_TYPE (args[1]);

      n = gfc_validate_kind (BT_INTEGER, gfc_c_int_kind, false);
      huge = gfc_conv_mpz_to_tree (gfc_integer_kinds[n].huge,
				   gfc_c_int_kind);
      huge = fold_convert (type, huge);
      args[1] = fold_build2_loc (input_location, MIN_EXPR, type, args[1],
				 huge);
      args[1] = fold_build2_loc (input_location, MAX_EXPR, type, args[1],
				 fold_build1_loc (input_location, NEGATE_EXPR,
						  type, huge));
    }

  args[1] = fold_convert (integer_type_node, args[1]);

  /* Make the function call.  */
  call = build_call_expr_loc_array (input_location, decl, 2, args);
  se->expr = fold_convert (TREE_TYPE (args[0]), call);
}


/* Generate code for IEEE_COPY_SIGN.  */

static void
conv_intrinsic_ieee_copy_sign (gfc_se * se, gfc_expr * expr)
{
  tree args[2], decl, sign;
  int argprec;

  conv_ieee_function_args (se, expr, args, 2);

  /* Get the sign of the second argument.  */
  sign = build_call_expr_loc (input_location,
			      builtin_decl_explicit (BUILT_IN_SIGNBIT),
			      1, args[1]);
  sign = fold_build2_loc (input_location, NE_EXPR, logical_type_node,
			  sign, integer_zero_node);

  /* Create a value of one, with the right sign.  */
  sign = fold_build3_loc (input_location, COND_EXPR, integer_type_node,
			  sign,
			  fold_build1_loc (input_location, NEGATE_EXPR,
					   integer_type_node,
					   integer_one_node),
			  integer_one_node);
  args[1] = fold_convert (TREE_TYPE (args[0]), sign);

  argprec = TYPE_PRECISION (TREE_TYPE (args[0]));
  decl = builtin_decl_for_precision (BUILT_IN_COPYSIGN, argprec);

  se->expr = build_call_expr_loc_array (input_location, decl, 2, args);
}


/* Generate code for an intrinsic function from the IEEE_ARITHMETIC
   module.  */

bool
gfc_conv_ieee_arithmetic_function (gfc_se * se, gfc_expr * expr)
{
  const char *name = expr->value.function.name;

  if (gfc_str_startswith (name, "_gfortran_ieee_is_nan"))
    conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISNAN, 1);
  else if (gfc_str_startswith (name, "_gfortran_ieee_is_finite"))
    conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISFINITE, 1);
  else if (gfc_str_startswith (name, "_gfortran_ieee_unordered"))
    conv_intrinsic_ieee_builtin (se, expr, BUILT_IN_ISUNORDERED, 2);
  else if (gfc_str_startswith (name, "_gfortran_ieee_is_normal"))
    conv_intrinsic_ieee_is_normal (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_is_negative"))
    conv_intrinsic_ieee_is_negative (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_copy_sign"))
    conv_intrinsic_ieee_copy_sign (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_scalb"))
    conv_intrinsic_ieee_scalb (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_next_after"))
    conv_intrinsic_ieee_next_after (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_rem"))
    conv_intrinsic_ieee_rem (se, expr);
  else if (gfc_str_startswith (name, "_gfortran_ieee_logb"))
    conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_LOGB);
  else if (gfc_str_startswith (name, "_gfortran_ieee_rint"))
    conv_intrinsic_ieee_logb_rint (se, expr, BUILT_IN_RINT);
  else
    /* It is not among the functions we translate directly.  We return
       false, so a library function call is emitted.  */
    return false;

  return true;
}


/* Generate a direct call to malloc() for the MALLOC intrinsic.  */

static void
gfc_conv_intrinsic_malloc (gfc_se * se, gfc_expr * expr)
{
  tree arg, res, restype;

  gfc_conv_intrinsic_function_args (se, expr, &arg, 1);
  arg = fold_convert (size_type_node, arg);
  res = build_call_expr_loc (input_location,
			     builtin_decl_explicit (BUILT_IN_MALLOC), 1, arg);
  restype = gfc_typenode_for_spec (&expr->ts);
  se->expr = fold_convert (restype, res);
}


/* Generate code for an intrinsic function.  Some map directly to library
   calls, others get special handling.  In some cases the name of the function
   used depends on the type specifiers.  */

void
gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
{
  const char *name;
  int lib, kind;
  tree fndecl;

  name = &expr->value.function.name[2];

  if (expr->rank > 0)
    {
      lib = gfc_is_intrinsic_libcall (expr);
      if (lib != 0)
	{
	  if (lib == 1)
	    se->ignore_optional = 1;

	  switch (expr->value.function.isym->id)
	    {
	    case GFC_ISYM_EOSHIFT:
	    case GFC_ISYM_PACK:
	    case GFC_ISYM_RESHAPE:
	      /* For all of those the first argument specifies the type and the
		 third is optional.  */
	      conv_generic_with_optional_char_arg (se, expr, 1, 3);
	      break;

	    case GFC_ISYM_FINDLOC:
	      gfc_conv_intrinsic_findloc (se, expr);
	      break;

	    case GFC_ISYM_MINLOC:
	      gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
	      break;

	    case GFC_ISYM_MAXLOC:
	      gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
	      break;

	    case GFC_ISYM_SHAPE:
	      gfc_conv_intrinsic_shape (se, expr);
	      break;

	    default:
	      gfc_conv_intrinsic_funcall (se, expr);
	      break;
	    }

	  return;
	}
    }

  switch (expr->value.function.isym->id)
    {
    case GFC_ISYM_NONE:
      gcc_unreachable ();

    case GFC_ISYM_REPEAT:
      gfc_conv_intrinsic_repeat (se, expr);
      break;

    case GFC_ISYM_TRIM:
      gfc_conv_intrinsic_trim (se, expr);
      break;

    case GFC_ISYM_SC_KIND:
      gfc_conv_intrinsic_sc_kind (se, expr);
      break;

    case GFC_ISYM_SI_KIND:
      gfc_conv_intrinsic_si_kind (se, expr);
      break;

    case GFC_ISYM_SR_KIND:
      gfc_conv_intrinsic_sr_kind (se, expr);
      break;

    case GFC_ISYM_EXPONENT:
      gfc_conv_intrinsic_exponent (se, expr);
      break;

    case GFC_ISYM_SCAN:
      kind = expr->value.function.actual->expr->ts.kind;
      if (kind == 1)
       fndecl = gfor_fndecl_string_scan;
      else if (kind == 4)
       fndecl = gfor_fndecl_string_scan_char4;
      else
       gcc_unreachable ();

      gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
      break;

    case GFC_ISYM_VERIFY:
      kind = expr->value.function.actual->expr->ts.kind;
      if (kind == 1)
       fndecl = gfor_fndecl_string_verify;
      else if (kind == 4)
       fndecl = gfor_fndecl_string_verify_char4;
      else
       gcc_unreachable ();

      gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
      break;

    case GFC_ISYM_ALLOCATED:
      gfc_conv_allocated (se, expr);
      break;

    case GFC_ISYM_ASSOCIATED:
      gfc_conv_associated(se, expr);
      break;

    case GFC_ISYM_SAME_TYPE_AS:
      gfc_conv_same_type_as (se, expr);
      break;

    case GFC_ISYM_ABS:
      gfc_conv_intrinsic_abs (se, expr);
      break;

    case GFC_ISYM_ADJUSTL:
      if (expr->ts.kind == 1)
       fndecl = gfor_fndecl_adjustl;
      else if (expr->ts.kind == 4)
       fndecl = gfor_fndecl_adjustl_char4;
      else
       gcc_unreachable ();

      gfc_conv_intrinsic_adjust (se, expr, fndecl);
      break;

    case GFC_ISYM_ADJUSTR:
      if (expr->ts.kind == 1)
       fndecl = gfor_fndecl_adjustr;
      else if (expr->ts.kind == 4)
       fndecl = gfor_fndecl_adjustr_char4;
      else
       gcc_unreachable ();

      gfc_conv_intrinsic_adjust (se, expr, fndecl);
      break;

    case GFC_ISYM_AIMAG:
      gfc_conv_intrinsic_imagpart (se, expr);
      break;

    case GFC_ISYM_AINT:
      gfc_conv_intrinsic_aint (se, expr, RND_TRUNC);
      break;

    case GFC_ISYM_ALL:
      gfc_conv_intrinsic_anyall (se, expr, EQ_EXPR);
      break;

    case GFC_ISYM_ANINT:
      gfc_conv_intrinsic_aint (se, expr, RND_ROUND);
      break;

    case GFC_ISYM_AND:
      gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
      break;

    case GFC_ISYM_ANY:
      gfc_conv_intrinsic_anyall (se, expr, NE_EXPR);
      break;

    case GFC_ISYM_BTEST:
      gfc_conv_intrinsic_btest (se, expr);
      break;

    case GFC_ISYM_BGE:
      gfc_conv_intrinsic_bitcomp (se, expr, GE_EXPR);
      break;

    case GFC_ISYM_BGT:
      gfc_conv_intrinsic_bitcomp (se, expr, GT_EXPR);
      break;

    case GFC_ISYM_BLE:
      gfc_conv_intrinsic_bitcomp (se, expr, LE_EXPR);
      break;

    case GFC_ISYM_BLT:
      gfc_conv_intrinsic_bitcomp (se, expr, LT_EXPR);
      break;

    case GFC_ISYM_C_ASSOCIATED:
    case GFC_ISYM_C_FUNLOC:
    case GFC_ISYM_C_LOC:
      conv_isocbinding_function (se, expr);
      break;

    case GFC_ISYM_ACHAR:
    case GFC_ISYM_CHAR:
      gfc_conv_intrinsic_char (se, expr);
      break;

    case GFC_ISYM_CONVERSION:
    case GFC_ISYM_REAL:
    case GFC_ISYM_LOGICAL:
    case GFC_ISYM_DBLE:
      gfc_conv_intrinsic_conversion (se, expr);
      break;

      /* Integer conversions are handled separately to make sure we get the
         correct rounding mode.  */
    case GFC_ISYM_INT:
    case GFC_ISYM_INT2:
    case GFC_ISYM_INT8:
    case GFC_ISYM_LONG:
      gfc_conv_intrinsic_int (se, expr, RND_TRUNC);
      break;

    case GFC_ISYM_NINT:
      gfc_conv_intrinsic_int (se, expr, RND_ROUND);
      break;

    case GFC_ISYM_CEILING:
      gfc_conv_intrinsic_int (se, expr, RND_CEIL);
      break;

    case GFC_ISYM_FLOOR:
      gfc_conv_intrinsic_int (se, expr, RND_FLOOR);
      break;

    case GFC_ISYM_MOD:
      gfc_conv_intrinsic_mod (se, expr, 0);
      break;

    case GFC_ISYM_MODULO:
      gfc_conv_intrinsic_mod (se, expr, 1);
      break;

    case GFC_ISYM_CAF_GET:
      gfc_conv_intrinsic_caf_get (se, expr, NULL_TREE, NULL_TREE, NULL_TREE,
				  false, NULL);
      break;

    case GFC_ISYM_CMPLX:
      gfc_conv_intrinsic_cmplx (se, expr, name[5] == '1');
      break;

    case GFC_ISYM_COMMAND_ARGUMENT_COUNT:
      gfc_conv_intrinsic_iargc (se, expr);
      break;

    case GFC_ISYM_COMPLEX:
      gfc_conv_intrinsic_cmplx (se, expr, 1);
      break;

    case GFC_ISYM_CONJG:
      gfc_conv_intrinsic_conjg (se, expr);
      break;

    case GFC_ISYM_COUNT:
      gfc_conv_intrinsic_count (se, expr);
      break;

    case GFC_ISYM_CTIME:
      gfc_conv_intrinsic_ctime (se, expr);
      break;

    case GFC_ISYM_DIM:
      gfc_conv_intrinsic_dim (se, expr);
      break;

    case GFC_ISYM_DOT_PRODUCT:
      gfc_conv_intrinsic_dot_product (se, expr);
      break;

    case GFC_ISYM_DPROD:
      gfc_conv_intrinsic_dprod (se, expr);
      break;

    case GFC_ISYM_DSHIFTL:
      gfc_conv_intrinsic_dshift (se, expr, true);
      break;

    case GFC_ISYM_DSHIFTR:
      gfc_conv_intrinsic_dshift (se, expr, false);
      break;

    case GFC_ISYM_FDATE:
      gfc_conv_intrinsic_fdate (se, expr);
      break;

    case GFC_ISYM_FRACTION:
      gfc_conv_intrinsic_fraction (se, expr);
      break;

    case GFC_ISYM_IALL:
      gfc_conv_intrinsic_arith (se, expr, BIT_AND_EXPR, false);
      break;

    case GFC_ISYM_IAND:
      gfc_conv_intrinsic_bitop (se, expr, BIT_AND_EXPR);
      break;

    case GFC_ISYM_IANY:
      gfc_conv_intrinsic_arith (se, expr, BIT_IOR_EXPR, false);
      break;

    case GFC_ISYM_IBCLR:
      gfc_conv_intrinsic_singlebitop (se, expr, 0);
      break;

    case GFC_ISYM_IBITS:
      gfc_conv_intrinsic_ibits (se, expr);
      break;

    case GFC_ISYM_IBSET:
      gfc_conv_intrinsic_singlebitop (se, expr, 1);
      break;

    case GFC_ISYM_IACHAR:
    case GFC_ISYM_ICHAR:
      /* We assume ASCII character sequence.  */
      gfc_conv_intrinsic_ichar (se, expr);
      break;

    case GFC_ISYM_IARGC:
      gfc_conv_intrinsic_iargc (se, expr);
      break;

    case GFC_ISYM_IEOR:
      gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
      break;

    case GFC_ISYM_INDEX:
      kind = expr->value.function.actual->expr->ts.kind;
      if (kind == 1)
       fndecl = gfor_fndecl_string_index;
      else if (kind == 4)
       fndecl = gfor_fndecl_string_index_char4;
      else
       gcc_unreachable ();

      gfc_conv_intrinsic_index_scan_verify (se, expr, fndecl);
      break;

    case GFC_ISYM_IOR:
      gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
      break;

    case GFC_ISYM_IPARITY:
      gfc_conv_intrinsic_arith (se, expr, BIT_XOR_EXPR, false);
      break;

    case GFC_ISYM_IS_IOSTAT_END:
      gfc_conv_has_intvalue (se, expr, LIBERROR_END);
      break;

    case GFC_ISYM_IS_IOSTAT_EOR:
      gfc_conv_has_intvalue (se, expr, LIBERROR_EOR);
      break;

    case GFC_ISYM_IS_CONTIGUOUS:
      gfc_conv_intrinsic_is_contiguous (se, expr);
      break;

    case GFC_ISYM_ISNAN:
      gfc_conv_intrinsic_isnan (se, expr);
      break;

    case GFC_ISYM_KILL:
      conv_intrinsic_kill (se, expr);
      break;

    case GFC_ISYM_LSHIFT:
      gfc_conv_intrinsic_shift (se, expr, false, false);
      break;

    case GFC_ISYM_RSHIFT:
      gfc_conv_intrinsic_shift (se, expr, true, true);
      break;

    case GFC_ISYM_SHIFTA:
      gfc_conv_intrinsic_shift (se, expr, true, true);
      break;

    case GFC_ISYM_SHIFTL:
      gfc_conv_intrinsic_shift (se, expr, false, false);
      break;

    case GFC_ISYM_SHIFTR:
      gfc_conv_intrinsic_shift (se, expr, true, false);
      break;

    case GFC_ISYM_ISHFT:
      gfc_conv_intrinsic_ishft (se, expr);
      break;

    case GFC_ISYM_ISHFTC:
      gfc_conv_intrinsic_ishftc (se, expr);
      break;

    case GFC_ISYM_LEADZ:
      gfc_conv_intrinsic_leadz (se, expr);
      break;

    case GFC_ISYM_TRAILZ:
      gfc_conv_intrinsic_trailz (se, expr);
      break;

    case GFC_ISYM_POPCNT:
      gfc_conv_intrinsic_popcnt_poppar (se, expr, 0);
      break;

    case GFC_ISYM_POPPAR:
      gfc_conv_intrinsic_popcnt_poppar (se, expr, 1);
      break;

    case GFC_ISYM_LBOUND:
      gfc_conv_intrinsic_bound (se, expr, 0);
      break;

    case GFC_ISYM_LCOBOUND:
      conv_intrinsic_cobound (se, expr);
      break;

    case GFC_ISYM_TRANSPOSE:
      /* The scalarizer has already been set up for reversed dimension access
	 order ; now we just get the argument value normally.  */
      gfc_conv_expr (se, expr->value.function.actual->expr);
      break;

    case GFC_ISYM_LEN:
      gfc_conv_intrinsic_len (se, expr);
      break;

    case GFC_ISYM_LEN_TRIM:
      gfc_conv_intrinsic_len_trim (se, expr);
      break;

    case GFC_ISYM_LGE:
      gfc_conv_intrinsic_strcmp (se, expr, GE_EXPR);
      break;

    case GFC_ISYM_LGT:
      gfc_conv_intrinsic_strcmp (se, expr, GT_EXPR);
      break;

    case GFC_ISYM_LLE:
      gfc_conv_intrinsic_strcmp (se, expr, LE_EXPR);
      break;

    case GFC_ISYM_LLT:
      gfc_conv_intrinsic_strcmp (se, expr, LT_EXPR);
      break;

    case GFC_ISYM_MALLOC:
      gfc_conv_intrinsic_malloc (se, expr);
      break;

    case GFC_ISYM_MASKL:
      gfc_conv_intrinsic_mask (se, expr, 1);
      break;

    case GFC_ISYM_MASKR:
      gfc_conv_intrinsic_mask (se, expr, 0);
      break;

    case GFC_ISYM_MAX:
      if (expr->ts.type == BT_CHARACTER)
	gfc_conv_intrinsic_minmax_char (se, expr, 1);
      else
	gfc_conv_intrinsic_minmax (se, expr, GT_EXPR);
      break;

    case GFC_ISYM_MAXLOC:
      gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR);
      break;

    case GFC_ISYM_FINDLOC:
      gfc_conv_intrinsic_findloc (se, expr);
      break;

    case GFC_ISYM_MAXVAL:
      gfc_conv_intrinsic_minmaxval (se, expr, GT_EXPR);
      break;

    case GFC_ISYM_MERGE:
      gfc_conv_intrinsic_merge (se, expr);
      break;

    case GFC_ISYM_MERGE_BITS:
      gfc_conv_intrinsic_merge_bits (se, expr);
      break;

    case GFC_ISYM_MIN:
      if (expr->ts.type == BT_CHARACTER)
	gfc_conv_intrinsic_minmax_char (se, expr, -1);
      else
	gfc_conv_intrinsic_minmax (se, expr, LT_EXPR);
      break;

    case GFC_ISYM_MINLOC:
      gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR);
      break;

    case GFC_ISYM_MINVAL:
      gfc_conv_intrinsic_minmaxval (se, expr, LT_EXPR);
      break;

    case GFC_ISYM_NEAREST:
      gfc_conv_intrinsic_nearest (se, expr);
      break;

    case GFC_ISYM_NORM2:
      gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, true);
      break;

    case GFC_ISYM_NOT:
      gfc_conv_intrinsic_not (se, expr);
      break;

    case GFC_ISYM_OR:
      gfc_conv_intrinsic_bitop (se, expr, BIT_IOR_EXPR);
      break;

    case GFC_ISYM_PARITY:
      gfc_conv_intrinsic_arith (se, expr, NE_EXPR, false);
      break;

    case GFC_ISYM_PRESENT:
      gfc_conv_intrinsic_present (se, expr);
      break;

    case GFC_ISYM_PRODUCT:
      gfc_conv_intrinsic_arith (se, expr, MULT_EXPR, false);
      break;

    case GFC_ISYM_RANK:
      gfc_conv_intrinsic_rank (se, expr);
      break;

    case GFC_ISYM_RRSPACING:
      gfc_conv_intrinsic_rrspacing (se, expr);
      break;

    case GFC_ISYM_SET_EXPONENT:
      gfc_conv_intrinsic_set_exponent (se, expr);
      break;

    case GFC_ISYM_SCALE:
      gfc_conv_intrinsic_scale (se, expr);
      break;

    case GFC_ISYM_SIGN:
      gfc_conv_intrinsic_sign (se, expr);
      break;

    case GFC_ISYM_SIZE:
      gfc_conv_intrinsic_size (se, expr);
      break;

    case GFC_ISYM_SIZEOF:
    case GFC_ISYM_C_SIZEOF:
      gfc_conv_intrinsic_sizeof (se, expr);
      break;

    case GFC_ISYM_STORAGE_SIZE:
      gfc_conv_intrinsic_storage_size (se, expr);
      break;

    case GFC_ISYM_SPACING:
      gfc_conv_intrinsic_spacing (se, expr);
      break;

    case GFC_ISYM_STRIDE:
      conv_intrinsic_stride (se, expr);
      break;

    case GFC_ISYM_SUM:
      gfc_conv_intrinsic_arith (se, expr, PLUS_EXPR, false);
      break;

    case GFC_ISYM_TEAM_NUMBER:
      conv_intrinsic_team_number (se, expr);
      break;

    case GFC_ISYM_TRANSFER:
      if (se->ss && se->ss->info->useflags)
	/* Access the previously obtained result.  */
	gfc_conv_tmp_array_ref (se);
      else
	gfc_conv_intrinsic_transfer (se, expr);
      break;

    case GFC_ISYM_TTYNAM:
      gfc_conv_intrinsic_ttynam (se, expr);
      break;

    case GFC_ISYM_UBOUND:
      gfc_conv_intrinsic_bound (se, expr, 1);
      break;

    case GFC_ISYM_UCOBOUND:
      conv_intrinsic_cobound (se, expr);
      break;

    case GFC_ISYM_XOR:
      gfc_conv_intrinsic_bitop (se, expr, BIT_XOR_EXPR);
      break;

    case GFC_ISYM_LOC:
      gfc_conv_intrinsic_loc (se, expr);
      break;

    case GFC_ISYM_THIS_IMAGE:
      /* For num_images() == 1, handle as LCOBOUND.  */
      if (expr->value.function.actual->expr
	  && flag_coarray == GFC_FCOARRAY_SINGLE)
	conv_intrinsic_cobound (se, expr);
      else
	trans_this_image (se, expr);
      break;

    case GFC_ISYM_IMAGE_INDEX:
      trans_image_index (se, expr);
      break;

    case GFC_ISYM_IMAGE_STATUS:
      conv_intrinsic_image_status (se, expr);
      break;

    case GFC_ISYM_NUM_IMAGES:
      trans_num_images (se, expr);
      break;

    case GFC_ISYM_ACCESS:
    case GFC_ISYM_CHDIR:
    case GFC_ISYM_CHMOD:
    case GFC_ISYM_DTIME:
    case GFC_ISYM_ETIME:
    case GFC_ISYM_EXTENDS_TYPE_OF:
    case GFC_ISYM_FGET:
    case GFC_ISYM_FGETC:
    case GFC_ISYM_FNUM:
    case GFC_ISYM_FPUT:
    case GFC_ISYM_FPUTC:
    case GFC_ISYM_FSTAT:
    case GFC_ISYM_FTELL:
    case GFC_ISYM_GETCWD:
    case GFC_ISYM_GETGID:
    case GFC_ISYM_GETPID:
    case GFC_ISYM_GETUID:
    case GFC_ISYM_HOSTNM:
    case GFC_ISYM_IERRNO:
    case GFC_ISYM_IRAND:
    case GFC_ISYM_ISATTY:
    case GFC_ISYM_JN2:
    case GFC_ISYM_LINK:
    case GFC_ISYM_LSTAT:
    case GFC_ISYM_MATMUL:
    case GFC_ISYM_MCLOCK:
    case GFC_ISYM_MCLOCK8:
    case GFC_ISYM_RAND:
    case GFC_ISYM_RENAME:
    case GFC_ISYM_SECOND:
    case GFC_ISYM_SECNDS:
    case GFC_ISYM_SIGNAL:
    case GFC_ISYM_STAT:
    case GFC_ISYM_SYMLNK:
    case GFC_ISYM_SYSTEM:
    case GFC_ISYM_TIME:
    case GFC_ISYM_TIME8:
    case GFC_ISYM_UMASK:
    case GFC_ISYM_UNLINK:
    case GFC_ISYM_YN2:
      gfc_conv_intrinsic_funcall (se, expr);
      break;

    case GFC_ISYM_EOSHIFT:
    case GFC_ISYM_PACK:
    case GFC_ISYM_RESHAPE:
      /* For those, expr->rank should always be >0 and thus the if above the
	 switch should have matched.  */
      gcc_unreachable ();
      break;

    default:
      gfc_conv_intrinsic_lib_function (se, expr);
      break;
    }
}


static gfc_ss *
walk_inline_intrinsic_transpose (gfc_ss *ss, gfc_expr *expr)
{
  gfc_ss *arg_ss, *tmp_ss;
  gfc_actual_arglist *arg;

  arg = expr->value.function.actual;

  gcc_assert (arg->expr);

  arg_ss = gfc_walk_subexpr (gfc_ss_terminator, arg->expr);
  gcc_assert (arg_ss != gfc_ss_terminator);

  for (tmp_ss = arg_ss; ; tmp_ss = tmp_ss->next)
    {
      if (tmp_ss->info->type != GFC_SS_SCALAR
	  && tmp_ss->info->type != GFC_SS_REFERENCE)
	{
	  gcc_assert (tmp_ss->dimen == 2);

	  /* We just invert dimensions.  */
	  std::swap (tmp_ss->dim[0], tmp_ss->dim[1]);
	}

      /* Stop when tmp_ss points to the last valid element of the chain...  */
      if (tmp_ss->next == gfc_ss_terminator)
	break;
    }

  /* ... so that we can attach the rest of the chain to it.  */
  tmp_ss->next = ss;

  return arg_ss;
}


/* Move the given dimension of the given gfc_ss list to a nested gfc_ss list.
   This has the side effect of reversing the nested list, so there is no
   need to call gfc_reverse_ss on it (the given list is assumed not to be
   reversed yet).   */

static gfc_ss *
nest_loop_dimension (gfc_ss *ss, int dim)
{
  int ss_dim, i;
  gfc_ss *new_ss, *prev_ss = gfc_ss_terminator;
  gfc_loopinfo *new_loop;

  gcc_assert (ss != gfc_ss_terminator);

  for (; ss != gfc_ss_terminator; ss = ss->next)
    {
      new_ss = gfc_get_ss ();
      new_ss->next = prev_ss;
      new_ss->parent = ss;
      new_ss->info = ss->info;
      new_ss->info->refcount++;
      if (ss->dimen != 0)
	{
	  gcc_assert (ss->info->type != GFC_SS_SCALAR
		      && ss->info->type != GFC_SS_REFERENCE);

	  new_ss->dimen = 1;
	  new_ss->dim[0] = ss->dim[dim];

	  gcc_assert (dim < ss->dimen);

	  ss_dim = --ss->dimen;
	  for (i = dim; i < ss_dim; i++)
	    ss->dim[i] = ss->dim[i + 1];

	  ss->dim[ss_dim] = 0;
	}
      prev_ss = new_ss;

      if (ss->nested_ss)
	{
	  ss->nested_ss->parent = new_ss;
	  new_ss->nested_ss = ss->nested_ss;
	}
      ss->nested_ss = new_ss;
    }

  new_loop = gfc_get_loopinfo ();
  gfc_init_loopinfo (new_loop);

  gcc_assert (prev_ss != NULL);
  gcc_assert (prev_ss != gfc_ss_terminator);
  gfc_add_ss_to_loop (new_loop, prev_ss);
  return new_ss->parent;
}


/* Create the gfc_ss list for the SUM/PRODUCT arguments when the function
   is to be inlined.  */

static gfc_ss *
walk_inline_intrinsic_arith (gfc_ss *ss, gfc_expr *expr)
{
  gfc_ss *tmp_ss, *tail, *array_ss;
  gfc_actual_arglist *arg1, *arg2, *arg3;
  int sum_dim;
  bool scalar_mask = false;

  /* The rank of the result will be determined later.  */
  arg1 = expr->value.function.actual;
  arg2 = arg1->next;
  arg3 = arg2->next;
  gcc_assert (arg3 != NULL);

  if (expr->rank == 0)
    return ss;

  tmp_ss = gfc_ss_terminator;

  if (arg3->expr)
    {
      gfc_ss *mask_ss;

      mask_ss = gfc_walk_subexpr (tmp_ss, arg3->expr);
      if (mask_ss == tmp_ss)
	scalar_mask = 1;

      tmp_ss = mask_ss;
    }

  array_ss = gfc_walk_subexpr (tmp_ss, arg1->expr);
  gcc_assert (array_ss != tmp_ss);

  /* Odd thing: If the mask is scalar, it is used by the frontend after
     the array (to make an if around the nested loop). Thus it shall
     be after array_ss once the gfc_ss list is reversed.  */
  if (scalar_mask)
    tmp_ss = gfc_get_scalar_ss (array_ss, arg3->expr);
  else
    tmp_ss = array_ss;

  /* "Hide" the dimension on which we will sum in the first arg's scalarization
     chain.  */
  sum_dim = mpz_get_si (arg2->expr->value.integer) - 1;
  tail = nest_loop_dimension (tmp_ss, sum_dim);
  tail->next = ss;

  return tmp_ss;
}


static gfc_ss *
walk_inline_intrinsic_function (gfc_ss * ss, gfc_expr * expr)
{

  switch (expr->value.function.isym->id)
    {
      case GFC_ISYM_PRODUCT:
      case GFC_ISYM_SUM:
	return walk_inline_intrinsic_arith (ss, expr);

      case GFC_ISYM_TRANSPOSE:
	return walk_inline_intrinsic_transpose (ss, expr);

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


/* This generates code to execute before entering the scalarization loop.
   Currently does nothing.  */

void
gfc_add_intrinsic_ss_code (gfc_loopinfo * loop ATTRIBUTE_UNUSED, gfc_ss * ss)
{
  switch (ss->info->expr->value.function.isym->id)
    {
    case GFC_ISYM_UBOUND:
    case GFC_ISYM_LBOUND:
    case GFC_ISYM_UCOBOUND:
    case GFC_ISYM_LCOBOUND:
    case GFC_ISYM_THIS_IMAGE:
      break;

    default:
      gcc_unreachable ();
    }
}


/* The LBOUND, LCOBOUND, UBOUND and UCOBOUND intrinsics with one parameter
   are expanded into code inside the scalarization loop.  */

static gfc_ss *
gfc_walk_intrinsic_bound (gfc_ss * ss, gfc_expr * expr)
{
  if (expr->value.function.actual->expr->ts.type == BT_CLASS)
    gfc_add_class_array_ref (expr->value.function.actual->expr);

  /* The two argument version returns a scalar.  */
  if (expr->value.function.actual->next->expr)
    return ss;

  return gfc_get_array_ss (ss, expr, 1, GFC_SS_INTRINSIC);
}


/* Walk an intrinsic array libcall.  */

static gfc_ss *
gfc_walk_intrinsic_libfunc (gfc_ss * ss, gfc_expr * expr)
{
  gcc_assert (expr->rank > 0);
  return gfc_get_array_ss (ss, expr, expr->rank, GFC_SS_FUNCTION);
}


/* Return whether the function call expression EXPR will be expanded
   inline by gfc_conv_intrinsic_function.  */

bool
gfc_inline_intrinsic_function_p (gfc_expr *expr)
{
  gfc_actual_arglist *args, *dim_arg, *mask_arg;
  gfc_expr *maskexpr;

  if (!expr->value.function.isym)
    return false;

  switch (expr->value.function.isym->id)
    {
    case GFC_ISYM_PRODUCT:
    case GFC_ISYM_SUM:
      /* Disable inline expansion if code size matters.  */
      if (optimize_size)
	return false;

      args = expr->value.function.actual;
      dim_arg = args->next;

      /* We need to be able to subset the SUM argument at compile-time.  */
      if (dim_arg->expr && dim_arg->expr->expr_type != EXPR_CONSTANT)
	return false;

      /* FIXME: If MASK is optional for a more than two-dimensional
	 argument, the scalarizer gets confused if the mask is
	 absent.  See PR 82995.  For now, fall back to the library
	 function.  */

      mask_arg = dim_arg->next;
      maskexpr = mask_arg->expr;

      if (expr->rank > 0 && maskexpr && maskexpr->expr_type == EXPR_VARIABLE
	  && maskexpr->symtree->n.sym->attr.dummy
	  && maskexpr->symtree->n.sym->attr.optional)
	return false;

      return true;

    case GFC_ISYM_TRANSPOSE:
      return true;

    default:
      return false;
    }
}


/* Returns nonzero if the specified intrinsic function call maps directly to
   an external library call.  Should only be used for functions that return
   arrays.  */

int
gfc_is_intrinsic_libcall (gfc_expr * expr)
{
  gcc_assert (expr->expr_type == EXPR_FUNCTION && expr->value.function.isym);
  gcc_assert (expr->rank > 0);

  if (gfc_inline_intrinsic_function_p (expr))
    return 0;

  switch (expr->value.function.isym->id)
    {
    case GFC_ISYM_ALL:
    case GFC_ISYM_ANY:
    case GFC_ISYM_COUNT:
    case GFC_ISYM_FINDLOC:
    case GFC_ISYM_JN2:
    case GFC_ISYM_IANY:
    case GFC_ISYM_IALL:
    case GFC_ISYM_IPARITY:
    case GFC_ISYM_MATMUL:
    case GFC_ISYM_MAXLOC:
    case GFC_ISYM_MAXVAL:
    case GFC_ISYM_MINLOC:
    case GFC_ISYM_MINVAL:
    case GFC_ISYM_NORM2:
    case GFC_ISYM_PARITY:
    case GFC_ISYM_PRODUCT:
    case GFC_ISYM_SUM:
    case GFC_ISYM_SHAPE:
    case GFC_ISYM_SPREAD:
    case GFC_ISYM_YN2:
      /* Ignore absent optional parameters.  */
      return 1;

    case GFC_ISYM_CSHIFT:
    case GFC_ISYM_EOSHIFT:
    case GFC_ISYM_GET_TEAM:
    case GFC_ISYM_FAILED_IMAGES:
    case GFC_ISYM_STOPPED_IMAGES:
    case GFC_ISYM_PACK:
    case GFC_ISYM_RESHAPE:
    case GFC_ISYM_UNPACK:
      /* Pass absent optional parameters.  */
      return 2;

    default:
      return 0;
    }
}

/* Walk an intrinsic function.  */
gfc_ss *
gfc_walk_intrinsic_function (gfc_ss * ss, gfc_expr * expr,
			     gfc_intrinsic_sym * isym)
{
  gcc_assert (isym);

  if (isym->elemental)
    return gfc_walk_elemental_function_args (ss, expr->value.function.actual,
					     NULL, GFC_SS_SCALAR);

  if (expr->rank == 0)
    return ss;

  if (gfc_inline_intrinsic_function_p (expr))
    return walk_inline_intrinsic_function (ss, expr);

  if (gfc_is_intrinsic_libcall (expr))
    return gfc_walk_intrinsic_libfunc (ss, expr);

  /* Special cases.  */
  switch (isym->id)
    {
    case GFC_ISYM_LBOUND:
    case GFC_ISYM_LCOBOUND:
    case GFC_ISYM_UBOUND:
    case GFC_ISYM_UCOBOUND:
    case GFC_ISYM_THIS_IMAGE:
      return gfc_walk_intrinsic_bound (ss, expr);

    case GFC_ISYM_TRANSFER:
    case GFC_ISYM_CAF_GET:
      return gfc_walk_intrinsic_libfunc (ss, expr);

    default:
      /* This probably meant someone forgot to add an intrinsic to the above
         list(s) when they implemented it, or something's gone horribly
	 wrong.  */
      gcc_unreachable ();
    }
}


static tree
conv_co_collective (gfc_code *code)
{
  gfc_se argse;
  stmtblock_t block, post_block;
  tree fndecl, array, strlen, image_index, stat, errmsg, errmsg_len;
  gfc_expr *image_idx_expr, *stat_expr, *errmsg_expr, *opr_expr;

  gfc_start_block (&block);
  gfc_init_block (&post_block);

  if (code->resolved_isym->id == GFC_ISYM_CO_REDUCE)
    {
      opr_expr = code->ext.actual->next->expr;
      image_idx_expr = code->ext.actual->next->next->expr;
      stat_expr = code->ext.actual->next->next->next->expr;
      errmsg_expr = code->ext.actual->next->next->next->next->expr;
    }
  else
    {
      opr_expr = NULL;
      image_idx_expr = code->ext.actual->next->expr;
      stat_expr = code->ext.actual->next->next->expr;
      errmsg_expr = code->ext.actual->next->next->next->expr;
    }

  /* stat.  */
  if (stat_expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr (&argse, stat_expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      stat = argse.expr;
      if (flag_coarray != GFC_FCOARRAY_SINGLE)
	stat = gfc_build_addr_expr (NULL_TREE, stat);
    }
  else if (flag_coarray == GFC_FCOARRAY_SINGLE)
    stat = NULL_TREE;
  else
    stat = null_pointer_node;

  /* Early exit for GFC_FCOARRAY_SINGLE.  */
  if (flag_coarray == GFC_FCOARRAY_SINGLE)
    {
      if (stat != NULL_TREE)
	gfc_add_modify (&block, stat,
			fold_convert (TREE_TYPE (stat), integer_zero_node));
      return gfc_finish_block (&block);
    }

  /* Handle the array.  */
  gfc_init_se (&argse, NULL);
  if (code->ext.actual->expr->rank == 0)
    {
      symbol_attribute attr;
      gfc_clear_attr (&attr);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr (&argse, code->ext.actual->expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      array = gfc_conv_scalar_to_descriptor (&argse, argse.expr, attr);
      array = gfc_build_addr_expr (NULL_TREE, array);
    }
  else
    {
      argse.want_pointer = 1;
      gfc_conv_expr_descriptor (&argse, code->ext.actual->expr);
      array = argse.expr;
    }
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);

  if (code->ext.actual->expr->ts.type == BT_CHARACTER)
    strlen = argse.string_length;
  else
    strlen = integer_zero_node;

  /* image_index.  */
  if (image_idx_expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr (&argse, image_idx_expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      image_index = fold_convert (integer_type_node, argse.expr);
    }
  else
    image_index = integer_zero_node;

  /* errmsg.  */
  if (errmsg_expr)
    {
      gfc_init_se (&argse, NULL);
      gfc_conv_expr (&argse, errmsg_expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      errmsg = argse.expr;
      errmsg_len = fold_convert (size_type_node, argse.string_length);
    }
  else
    {
      errmsg = null_pointer_node;
      errmsg_len = build_zero_cst (size_type_node);
    }

  /* Generate the function call.  */
  switch (code->resolved_isym->id)
    {
    case GFC_ISYM_CO_BROADCAST:
      fndecl = gfor_fndecl_co_broadcast;
      break;
    case GFC_ISYM_CO_MAX:
      fndecl = gfor_fndecl_co_max;
      break;
    case GFC_ISYM_CO_MIN:
      fndecl = gfor_fndecl_co_min;
      break;
    case GFC_ISYM_CO_REDUCE:
      fndecl = gfor_fndecl_co_reduce;
      break;
    case GFC_ISYM_CO_SUM:
      fndecl = gfor_fndecl_co_sum;
      break;
    default:
      gcc_unreachable ();
    }

  if (code->resolved_isym->id == GFC_ISYM_CO_SUM
      || code->resolved_isym->id == GFC_ISYM_CO_BROADCAST)
    fndecl = build_call_expr_loc (input_location, fndecl, 5, array,
				  image_index, stat, errmsg, errmsg_len);
  else if (code->resolved_isym->id != GFC_ISYM_CO_REDUCE)
    fndecl = build_call_expr_loc (input_location, fndecl, 6, array, image_index,
				  stat, errmsg, strlen, errmsg_len);
  else
    {
      tree opr, opr_flags;

      // FIXME: Handle TS29113's bind(C) strings with descriptor.
      int opr_flag_int;
      if (gfc_is_proc_ptr_comp (opr_expr))
	{
	  gfc_symbol *sym = gfc_get_proc_ptr_comp (opr_expr)->ts.interface;
	  opr_flag_int = sym->attr.dimension
			 || (sym->ts.type == BT_CHARACTER
			     && !sym->attr.is_bind_c)
			 ? GFC_CAF_BYREF : 0;
	  opr_flag_int |= opr_expr->ts.type == BT_CHARACTER
			  && !sym->attr.is_bind_c
			  ? GFC_CAF_HIDDENLEN : 0;
	  opr_flag_int |= sym->formal->sym->attr.value ? GFC_CAF_ARG_VALUE : 0;
	}
      else
	{
	  opr_flag_int = gfc_return_by_reference (opr_expr->symtree->n.sym)
			 ? GFC_CAF_BYREF : 0;
	  opr_flag_int |= opr_expr->ts.type == BT_CHARACTER
			  && !opr_expr->symtree->n.sym->attr.is_bind_c
			  ? GFC_CAF_HIDDENLEN : 0;
	  opr_flag_int |= opr_expr->symtree->n.sym->formal->sym->attr.value
			  ? GFC_CAF_ARG_VALUE : 0;
	}
      opr_flags = build_int_cst (integer_type_node, opr_flag_int);
      gfc_conv_expr (&argse, opr_expr);
      opr = argse.expr;
      fndecl = build_call_expr_loc (input_location, fndecl, 8, array, opr, opr_flags,
				    image_index, stat, errmsg, strlen, errmsg_len);
    }

  gfc_add_expr_to_block (&block, fndecl);
  gfc_add_block_to_block (&block, &post_block);

  return gfc_finish_block (&block);
}


static tree
conv_intrinsic_atomic_op (gfc_code *code)
{
  gfc_se argse;
  tree tmp, atom, value, old = NULL_TREE, stat = NULL_TREE;
  stmtblock_t block, post_block;
  gfc_expr *atom_expr = code->ext.actual->expr;
  gfc_expr *stat_expr;
  built_in_function fn;

  if (atom_expr->expr_type == EXPR_FUNCTION
      && atom_expr->value.function.isym
      && atom_expr->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom_expr = atom_expr->value.function.actual->expr;

  gfc_start_block (&block);
  gfc_init_block (&post_block);

  gfc_init_se (&argse, NULL);
  argse.want_pointer = 1;
  gfc_conv_expr (&argse, atom_expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  atom = argse.expr;

  gfc_init_se (&argse, NULL);
  if (flag_coarray == GFC_FCOARRAY_LIB
      && code->ext.actual->next->expr->ts.kind == atom_expr->ts.kind)
    argse.want_pointer = 1;
  gfc_conv_expr (&argse, code->ext.actual->next->expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  value = argse.expr;

  switch (code->resolved_isym->id)
    {
    case GFC_ISYM_ATOMIC_ADD:
    case GFC_ISYM_ATOMIC_AND:
    case GFC_ISYM_ATOMIC_DEF:
    case GFC_ISYM_ATOMIC_OR:
    case GFC_ISYM_ATOMIC_XOR:
      stat_expr = code->ext.actual->next->next->expr;
      if (flag_coarray == GFC_FCOARRAY_LIB)
	old = null_pointer_node;
      break;
    default:
      gfc_init_se (&argse, NULL);
      if (flag_coarray == GFC_FCOARRAY_LIB)
	argse.want_pointer = 1;
      gfc_conv_expr (&argse, code->ext.actual->next->next->expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      old = argse.expr;
      stat_expr = code->ext.actual->next->next->next->expr;
    }

  /* STAT=  */
  if (stat_expr != NULL)
    {
      gcc_assert (stat_expr->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      if (flag_coarray == GFC_FCOARRAY_LIB)
	argse.want_pointer = 1;
      gfc_conv_expr_val (&argse, stat_expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree image_index, caf_decl, offset, token;
      int op;

      switch (code->resolved_isym->id)
	{
	case GFC_ISYM_ATOMIC_ADD:
	case GFC_ISYM_ATOMIC_FETCH_ADD:
	  op = (int) GFC_CAF_ATOMIC_ADD;
	  break;
	case GFC_ISYM_ATOMIC_AND:
	case GFC_ISYM_ATOMIC_FETCH_AND:
	  op = (int) GFC_CAF_ATOMIC_AND;
	  break;
	case GFC_ISYM_ATOMIC_OR:
	case GFC_ISYM_ATOMIC_FETCH_OR:
	  op = (int) GFC_CAF_ATOMIC_OR;
	  break;
	case GFC_ISYM_ATOMIC_XOR:
	case GFC_ISYM_ATOMIC_FETCH_XOR:
	  op = (int) GFC_CAF_ATOMIC_XOR;
	  break;
	case GFC_ISYM_ATOMIC_DEF:
	  op = 0;  /* Unused.  */
	  break;
	default:
	  gcc_unreachable ();
	}

      caf_decl = gfc_get_tree_for_caf_expr (atom_expr);
      if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
	caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);

      if (gfc_is_coindexed (atom_expr))
	image_index = gfc_caf_get_image_index (&block, atom_expr, caf_decl);
      else
	image_index = integer_zero_node;

      if (!POINTER_TYPE_P (TREE_TYPE (value)))
	{
	  tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (atom)), "value");
	  gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), value));
          value = gfc_build_addr_expr (NULL_TREE, tmp);
	}

      gfc_init_se (&argse, NULL);
      gfc_get_caf_token_offset (&argse, &token, &offset, caf_decl, atom,
				atom_expr);

      gfc_add_block_to_block (&block, &argse.pre);
      if (code->resolved_isym->id == GFC_ISYM_ATOMIC_DEF)
	tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_atomic_def, 7,
				   token, offset, image_index, value, stat,
				   build_int_cst (integer_type_node,
						  (int) atom_expr->ts.type),
				   build_int_cst (integer_type_node,
						  (int) atom_expr->ts.kind));
      else
	tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_atomic_op, 9,
				   build_int_cst (integer_type_node, op),
				   token, offset, image_index, value, old, stat,
				   build_int_cst (integer_type_node,
						  (int) atom_expr->ts.type),
				   build_int_cst (integer_type_node,
						  (int) atom_expr->ts.kind));

      gfc_add_expr_to_block (&block, tmp);
      gfc_add_block_to_block (&block, &argse.post);
      gfc_add_block_to_block (&block, &post_block);
      return gfc_finish_block (&block);
    }


  switch (code->resolved_isym->id)
    {
    case GFC_ISYM_ATOMIC_ADD:
    case GFC_ISYM_ATOMIC_FETCH_ADD:
      fn = BUILT_IN_ATOMIC_FETCH_ADD_N;
      break;
    case GFC_ISYM_ATOMIC_AND:
    case GFC_ISYM_ATOMIC_FETCH_AND:
      fn = BUILT_IN_ATOMIC_FETCH_AND_N;
      break;
    case GFC_ISYM_ATOMIC_DEF:
      fn = BUILT_IN_ATOMIC_STORE_N;
      break;
    case GFC_ISYM_ATOMIC_OR:
    case GFC_ISYM_ATOMIC_FETCH_OR:
      fn = BUILT_IN_ATOMIC_FETCH_OR_N;
      break;
    case GFC_ISYM_ATOMIC_XOR:
    case GFC_ISYM_ATOMIC_FETCH_XOR:
      fn = BUILT_IN_ATOMIC_FETCH_XOR_N;
      break;
    default:
      gcc_unreachable ();
    }

  tmp = TREE_TYPE (TREE_TYPE (atom));
  fn = (built_in_function) ((int) fn
			    + exact_log2 (tree_to_uhwi (TYPE_SIZE_UNIT (tmp)))
			    + 1);
  tmp = builtin_decl_explicit (fn);
  tree itype = TREE_TYPE (TREE_TYPE (atom));
  tmp = builtin_decl_explicit (fn);

  switch (code->resolved_isym->id)
    {
    case GFC_ISYM_ATOMIC_ADD:
    case GFC_ISYM_ATOMIC_AND:
    case GFC_ISYM_ATOMIC_DEF:
    case GFC_ISYM_ATOMIC_OR:
    case GFC_ISYM_ATOMIC_XOR:
      tmp = build_call_expr_loc (input_location, tmp, 3, atom,
				 fold_convert (itype, value),
				 build_int_cst (NULL, MEMMODEL_RELAXED));
      gfc_add_expr_to_block (&block, tmp);
      break;
    default:
      tmp = build_call_expr_loc (input_location, tmp, 3, atom,
				 fold_convert (itype, value),
				 build_int_cst (NULL, MEMMODEL_RELAXED));
      gfc_add_modify (&block, old, fold_convert (TREE_TYPE (old), tmp));
      break;
    }

  if (stat != NULL_TREE)
    gfc_add_modify (&block, stat, build_int_cst (TREE_TYPE (stat), 0));
  gfc_add_block_to_block (&block, &post_block);
  return gfc_finish_block (&block);
}


static tree
conv_intrinsic_atomic_ref (gfc_code *code)
{
  gfc_se argse;
  tree tmp, atom, value, stat = NULL_TREE;
  stmtblock_t block, post_block;
  built_in_function fn;
  gfc_expr *atom_expr = code->ext.actual->next->expr;

  if (atom_expr->expr_type == EXPR_FUNCTION
      && atom_expr->value.function.isym
      && atom_expr->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom_expr = atom_expr->value.function.actual->expr;

  gfc_start_block (&block);
  gfc_init_block (&post_block);
  gfc_init_se (&argse, NULL);
  argse.want_pointer = 1;
  gfc_conv_expr (&argse, atom_expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  atom = argse.expr;

  gfc_init_se (&argse, NULL);
  if (flag_coarray == GFC_FCOARRAY_LIB
      && code->ext.actual->expr->ts.kind == atom_expr->ts.kind)
    argse.want_pointer = 1;
  gfc_conv_expr (&argse, code->ext.actual->expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  value = argse.expr;

  /* STAT=  */
  if (code->ext.actual->next->next->expr != NULL)
    {
      gcc_assert (code->ext.actual->next->next->expr->expr_type
		  == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      if (flag_coarray == GFC_FCOARRAY_LIB)
	argse.want_pointer = 1;
      gfc_conv_expr_val (&argse, code->ext.actual->next->next->expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree image_index, caf_decl, offset, token;
      tree orig_value = NULL_TREE, vardecl = NULL_TREE;

      caf_decl = gfc_get_tree_for_caf_expr (atom_expr);
      if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
	caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);

      if (gfc_is_coindexed (atom_expr))
	image_index = gfc_caf_get_image_index (&block, atom_expr, caf_decl);
      else
	image_index = integer_zero_node;

      gfc_init_se (&argse, NULL);
      gfc_get_caf_token_offset (&argse, &token, &offset, caf_decl, atom,
				atom_expr);
      gfc_add_block_to_block (&block, &argse.pre);

      /* Different type, need type conversion.  */
      if (!POINTER_TYPE_P (TREE_TYPE (value)))
	{
	  vardecl = gfc_create_var (TREE_TYPE (TREE_TYPE (atom)), "value");
          orig_value = value;
          value = gfc_build_addr_expr (NULL_TREE, vardecl);
	}

      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_atomic_ref, 7,
				 token, offset, image_index, value, stat,
				 build_int_cst (integer_type_node,
						(int) atom_expr->ts.type),
				 build_int_cst (integer_type_node,
						(int) atom_expr->ts.kind));
      gfc_add_expr_to_block (&block, tmp);
      if (vardecl != NULL_TREE)
	gfc_add_modify (&block, orig_value,
			fold_convert (TREE_TYPE (orig_value), vardecl));
      gfc_add_block_to_block (&block, &argse.post);
      gfc_add_block_to_block (&block, &post_block);
      return gfc_finish_block (&block);
    }

  tmp = TREE_TYPE (TREE_TYPE (atom));
  fn = (built_in_function) ((int) BUILT_IN_ATOMIC_LOAD_N
			    + exact_log2 (tree_to_uhwi (TYPE_SIZE_UNIT (tmp)))
			    + 1);
  tmp = builtin_decl_explicit (fn);
  tmp = build_call_expr_loc (input_location, tmp, 2, atom,
			     build_int_cst (integer_type_node,
					    MEMMODEL_RELAXED));
  gfc_add_modify (&block, value, fold_convert (TREE_TYPE (value), tmp));

  if (stat != NULL_TREE)
    gfc_add_modify (&block, stat, build_int_cst (TREE_TYPE (stat), 0));
  gfc_add_block_to_block (&block, &post_block);
  return gfc_finish_block (&block);
}


static tree
conv_intrinsic_atomic_cas (gfc_code *code)
{
  gfc_se argse;
  tree tmp, atom, old, new_val, comp, stat = NULL_TREE;
  stmtblock_t block, post_block;
  built_in_function fn;
  gfc_expr *atom_expr = code->ext.actual->expr;

  if (atom_expr->expr_type == EXPR_FUNCTION
      && atom_expr->value.function.isym
      && atom_expr->value.function.isym->id == GFC_ISYM_CAF_GET)
    atom_expr = atom_expr->value.function.actual->expr;

  gfc_init_block (&block);
  gfc_init_block (&post_block);
  gfc_init_se (&argse, NULL);
  argse.want_pointer = 1;
  gfc_conv_expr (&argse, atom_expr);
  atom = argse.expr;

  gfc_init_se (&argse, NULL);
  if (flag_coarray == GFC_FCOARRAY_LIB)
    argse.want_pointer = 1;
  gfc_conv_expr (&argse, code->ext.actual->next->expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  old = argse.expr;

  gfc_init_se (&argse, NULL);
  if (flag_coarray == GFC_FCOARRAY_LIB)
    argse.want_pointer = 1;
  gfc_conv_expr (&argse, code->ext.actual->next->next->expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  comp = argse.expr;

  gfc_init_se (&argse, NULL);
  if (flag_coarray == GFC_FCOARRAY_LIB
      && code->ext.actual->next->next->next->expr->ts.kind
	 == atom_expr->ts.kind)
    argse.want_pointer = 1;
  gfc_conv_expr (&argse, code->ext.actual->next->next->next->expr);
  gfc_add_block_to_block (&block, &argse.pre);
  gfc_add_block_to_block (&post_block, &argse.post);
  new_val = argse.expr;

  /* STAT=  */
  if (code->ext.actual->next->next->next->next->expr != NULL)
    {
      gcc_assert (code->ext.actual->next->next->next->next->expr->expr_type
		  == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      if (flag_coarray == GFC_FCOARRAY_LIB)
	argse.want_pointer = 1;
      gfc_conv_expr_val (&argse,
			 code->ext.actual->next->next->next->next->expr);
      gfc_add_block_to_block (&block, &argse.pre);
      gfc_add_block_to_block (&post_block, &argse.post);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree image_index, caf_decl, offset, token;

      caf_decl = gfc_get_tree_for_caf_expr (atom_expr);
      if (TREE_CODE (TREE_TYPE (caf_decl)) == REFERENCE_TYPE)
	caf_decl = build_fold_indirect_ref_loc (input_location, caf_decl);

      if (gfc_is_coindexed (atom_expr))
	image_index = gfc_caf_get_image_index (&block, atom_expr, caf_decl);
      else
	image_index = integer_zero_node;

      if (TREE_TYPE (TREE_TYPE (new_val)) != TREE_TYPE (TREE_TYPE (old)))
	{
	  tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (old)), "new");
	  gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), new_val));
          new_val = gfc_build_addr_expr (NULL_TREE, tmp);
	}

      /* Convert a constant to a pointer.  */
      if (!POINTER_TYPE_P (TREE_TYPE (comp)))
	{
	  tmp = gfc_create_var (TREE_TYPE (TREE_TYPE (old)), "comp");
	  gfc_add_modify (&block, tmp, fold_convert (TREE_TYPE (tmp), comp));
          comp = gfc_build_addr_expr (NULL_TREE, tmp);
	}

      gfc_init_se (&argse, NULL);
      gfc_get_caf_token_offset (&argse, &token, &offset, caf_decl, atom,
				atom_expr);
      gfc_add_block_to_block (&block, &argse.pre);

      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_atomic_cas, 9,
				 token, offset, image_index, old, comp, new_val,
				 stat, build_int_cst (integer_type_node,
						      (int) atom_expr->ts.type),
				 build_int_cst (integer_type_node,
						(int) atom_expr->ts.kind));
      gfc_add_expr_to_block (&block, tmp);
      gfc_add_block_to_block (&block, &argse.post);
      gfc_add_block_to_block (&block, &post_block);
      return gfc_finish_block (&block);
    }

  tmp = TREE_TYPE (TREE_TYPE (atom));
  fn = (built_in_function) ((int) BUILT_IN_ATOMIC_COMPARE_EXCHANGE_N
			    + exact_log2 (tree_to_uhwi (TYPE_SIZE_UNIT (tmp)))
			    + 1);
  tmp = builtin_decl_explicit (fn);

  gfc_add_modify (&block, old, comp);
  tmp = build_call_expr_loc (input_location, tmp, 6, atom,
			     gfc_build_addr_expr (NULL, old),
			     fold_convert (TREE_TYPE (old), new_val),
			     boolean_false_node,
			     build_int_cst (NULL, MEMMODEL_RELAXED),
			     build_int_cst (NULL, MEMMODEL_RELAXED));
  gfc_add_expr_to_block (&block, tmp);

  if (stat != NULL_TREE)
    gfc_add_modify (&block, stat, build_int_cst (TREE_TYPE (stat), 0));
  gfc_add_block_to_block (&block, &post_block);
  return gfc_finish_block (&block);
}

static tree
conv_intrinsic_event_query (gfc_code *code)
{
  gfc_se se, argse;
  tree stat = NULL_TREE, stat2 = NULL_TREE;
  tree count = NULL_TREE, count2 = NULL_TREE;

  gfc_expr *event_expr = code->ext.actual->expr;

  if (code->ext.actual->next->next->expr)
    {
      gcc_assert (code->ext.actual->next->next->expr->expr_type
		  == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->ext.actual->next->next->expr);
      stat = argse.expr;
    }
  else if (flag_coarray == GFC_FCOARRAY_LIB)
    stat = null_pointer_node;

  if (code->ext.actual->next->expr)
    {
      gcc_assert (code->ext.actual->next->expr->expr_type == EXPR_VARIABLE);
      gfc_init_se (&argse, NULL);
      gfc_conv_expr_val (&argse, code->ext.actual->next->expr);
      count = argse.expr;
    }

  gfc_start_block (&se.pre);
  if (flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree tmp, token, image_index;
      tree index = build_zero_cst (gfc_array_index_type);

      if (event_expr->expr_type == EXPR_FUNCTION
	  && event_expr->value.function.isym
	  && event_expr->value.function.isym->id == GFC_ISYM_CAF_GET)
	event_expr = event_expr->value.function.actual->expr;

      tree caf_decl = gfc_get_tree_for_caf_expr (event_expr);

      if (event_expr->symtree->n.sym->ts.type != BT_DERIVED
	  || event_expr->symtree->n.sym->ts.u.derived->from_intmod
	     != INTMOD_ISO_FORTRAN_ENV
	  || event_expr->symtree->n.sym->ts.u.derived->intmod_sym_id
	     != ISOFORTRAN_EVENT_TYPE)
	{
	  gfc_error ("Sorry, the event component of derived type at %L is not "
		     "yet supported", &event_expr->where);
	  return NULL_TREE;
	}

      if (gfc_is_coindexed (event_expr))
	{
	  gfc_error ("The event variable at %L shall not be coindexed",
		     &event_expr->where);
          return NULL_TREE;
	}

      image_index = integer_zero_node;

      gfc_get_caf_token_offset (&se, &token, NULL, caf_decl, NULL_TREE,
				event_expr);

      /* For arrays, obtain the array index.  */
      if (gfc_expr_attr (event_expr).dimension)
	{
	  tree desc, tmp, extent, lbound, ubound;
          gfc_array_ref *ar, ar2;
          int i;

	  /* TODO: Extend this, once DT components are supported.  */
	  ar = &event_expr->ref->u.ar;
	  ar2 = *ar;
	  memset (ar, '\0', sizeof (*ar));
	  ar->as = ar2.as;
	  ar->type = AR_FULL;

	  gfc_init_se (&argse, NULL);
	  argse.descriptor_only = 1;
	  gfc_conv_expr_descriptor (&argse, event_expr);
	  gfc_add_block_to_block (&se.pre, &argse.pre);
	  desc = argse.expr;
	  *ar = ar2;

	  extent = build_one_cst (gfc_array_index_type);
	  for (i = 0; i < ar->dimen; i++)
	    {
	      gfc_init_se (&argse, NULL);
	      gfc_conv_expr_type (&argse, ar->start[i], gfc_array_index_type);
	      gfc_add_block_to_block (&argse.pre, &argse.pre);
	      lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[i]);
	      tmp = fold_build2_loc (input_location, MINUS_EXPR,
				     TREE_TYPE (lbound), argse.expr, lbound);
	      tmp = fold_build2_loc (input_location, MULT_EXPR,
				     TREE_TYPE (tmp), extent, tmp);
	      index = fold_build2_loc (input_location, PLUS_EXPR,
				       TREE_TYPE (tmp), index, tmp);
	      if (i < ar->dimen - 1)
		{
		  ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[i]);
		  tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL);
		  extent = fold_build2_loc (input_location, MULT_EXPR,
					    TREE_TYPE (tmp), extent, tmp);
		}
	    }
	}

      if (count != null_pointer_node && TREE_TYPE (count) != integer_type_node)
	{
	  count2 = count;
	  count = gfc_create_var (integer_type_node, "count");
	}

      if (stat != null_pointer_node && TREE_TYPE (stat) != integer_type_node)
	{
	  stat2 = stat;
	  stat = gfc_create_var (integer_type_node, "stat");
	}

      index = fold_convert (size_type_node, index);
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_event_query, 5,
                                   token, index, image_index, count
				   ? gfc_build_addr_expr (NULL, count) : count,
				   stat != null_pointer_node
				   ? gfc_build_addr_expr (NULL, stat) : stat);
      gfc_add_expr_to_block (&se.pre, tmp);

      if (count2 != NULL_TREE)
	gfc_add_modify (&se.pre, count2,
			fold_convert (TREE_TYPE (count2), count));

      if (stat2 != NULL_TREE)
	gfc_add_modify (&se.pre, stat2,
			fold_convert (TREE_TYPE (stat2), stat));

      return gfc_finish_block (&se.pre);
    }

  gfc_init_se (&argse, NULL);
  gfc_conv_expr_val (&argse, code->ext.actual->expr);
  gfc_add_modify (&se.pre, count, fold_convert (TREE_TYPE (count), argse.expr));

  if (stat != NULL_TREE)
    gfc_add_modify (&se.pre, stat, build_int_cst (TREE_TYPE (stat), 0));

  return gfc_finish_block (&se.pre);
}

static tree
conv_intrinsic_move_alloc (gfc_code *code)
{
  stmtblock_t block;
  gfc_expr *from_expr, *to_expr;
  gfc_expr *to_expr2, *from_expr2 = NULL;
  gfc_se from_se, to_se;
  tree tmp;
  bool coarray;

  gfc_start_block (&block);

  from_expr = code->ext.actual->expr;
  to_expr = code->ext.actual->next->expr;

  gfc_init_se (&from_se, NULL);
  gfc_init_se (&to_se, NULL);

  gcc_assert (from_expr->ts.type != BT_CLASS
	      || to_expr->ts.type == BT_CLASS);
  coarray = gfc_get_corank (from_expr) != 0;

  if (from_expr->rank == 0 && !coarray)
    {
      if (from_expr->ts.type != BT_CLASS)
	from_expr2 = from_expr;
      else
	{
	  from_expr2 = gfc_copy_expr (from_expr);
	  gfc_add_data_component (from_expr2);
	}

      if (to_expr->ts.type != BT_CLASS)
	to_expr2 = to_expr;
      else
	{
	  to_expr2 = gfc_copy_expr (to_expr);
	  gfc_add_data_component (to_expr2);
	}

      from_se.want_pointer = 1;
      to_se.want_pointer = 1;
      gfc_conv_expr (&from_se, from_expr2);
      gfc_conv_expr (&to_se, to_expr2);
      gfc_add_block_to_block (&block, &from_se.pre);
      gfc_add_block_to_block (&block, &to_se.pre);

      /* Deallocate "to".  */
      tmp = gfc_deallocate_scalar_with_status (to_se.expr, NULL_TREE, NULL_TREE,
					       true, to_expr, to_expr->ts);
      gfc_add_expr_to_block (&block, tmp);

      /* Assign (_data) pointers.  */
      gfc_add_modify_loc (input_location, &block, to_se.expr,
			  fold_convert (TREE_TYPE (to_se.expr), from_se.expr));

      /* Set "from" to NULL.  */
      gfc_add_modify_loc (input_location, &block, from_se.expr,
			  fold_convert (TREE_TYPE (from_se.expr), null_pointer_node));

      gfc_add_block_to_block (&block, &from_se.post);
      gfc_add_block_to_block (&block, &to_se.post);

      /* Set _vptr.  */
      if (to_expr->ts.type == BT_CLASS)
	{
	  gfc_symbol *vtab;

	  gfc_free_expr (to_expr2);
	  gfc_init_se (&to_se, NULL);
	  to_se.want_pointer = 1;
	  gfc_add_vptr_component (to_expr);
	  gfc_conv_expr (&to_se, to_expr);

	  if (from_expr->ts.type == BT_CLASS)
	    {
	      if (UNLIMITED_POLY (from_expr))
		vtab = NULL;
	      else
		{
		  vtab = gfc_find_derived_vtab (from_expr->ts.u.derived);
		  gcc_assert (vtab);
		}

	      gfc_free_expr (from_expr2);
	      gfc_init_se (&from_se, NULL);
	      from_se.want_pointer = 1;
	      gfc_add_vptr_component (from_expr);
	      gfc_conv_expr (&from_se, from_expr);
	      gfc_add_modify_loc (input_location, &block, to_se.expr,
				  fold_convert (TREE_TYPE (to_se.expr),
				  from_se.expr));

              /* Reset _vptr component to declared type.  */
	      if (vtab == NULL)
		/* Unlimited polymorphic.  */
		gfc_add_modify_loc (input_location, &block, from_se.expr,
				    fold_convert (TREE_TYPE (from_se.expr),
						  null_pointer_node));
	      else
		{
		  tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
		  gfc_add_modify_loc (input_location, &block, from_se.expr,
				      fold_convert (TREE_TYPE (from_se.expr), tmp));
		}
	    }
	  else
	    {
	      vtab = gfc_find_vtab (&from_expr->ts);
	      gcc_assert (vtab);
	      tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
	      gfc_add_modify_loc (input_location, &block, to_se.expr,
				  fold_convert (TREE_TYPE (to_se.expr), tmp));
	    }
	}

      if (to_expr->ts.type == BT_CHARACTER && to_expr->ts.deferred)
	{
	  gfc_add_modify_loc (input_location, &block, to_se.string_length,
			      fold_convert (TREE_TYPE (to_se.string_length),
					    from_se.string_length));
	  if (from_expr->ts.deferred)
	    gfc_add_modify_loc (input_location, &block, from_se.string_length,
			build_int_cst (TREE_TYPE (from_se.string_length), 0));
	}

      return gfc_finish_block (&block);
    }

  /* Update _vptr component.  */
  if (to_expr->ts.type == BT_CLASS)
    {
      gfc_symbol *vtab;

      to_se.want_pointer = 1;
      to_expr2 = gfc_copy_expr (to_expr);
      gfc_add_vptr_component (to_expr2);
      gfc_conv_expr (&to_se, to_expr2);

      if (from_expr->ts.type == BT_CLASS)
	{
	  if (UNLIMITED_POLY (from_expr))
	    vtab = NULL;
	  else
	    {
	      vtab = gfc_find_derived_vtab (from_expr->ts.u.derived);
	      gcc_assert (vtab);
	    }

	  from_se.want_pointer = 1;
	  from_expr2 = gfc_copy_expr (from_expr);
	  gfc_add_vptr_component (from_expr2);
	  gfc_conv_expr (&from_se, from_expr2);
	  gfc_add_modify_loc (input_location, &block, to_se.expr,
			      fold_convert (TREE_TYPE (to_se.expr),
			      from_se.expr));

	  /* Reset _vptr component to declared type.  */
	  if (vtab == NULL)
	    /* Unlimited polymorphic.  */
	    gfc_add_modify_loc (input_location, &block, from_se.expr,
				fold_convert (TREE_TYPE (from_se.expr),
					      null_pointer_node));
	  else
	    {
	      tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
	      gfc_add_modify_loc (input_location, &block, from_se.expr,
				  fold_convert (TREE_TYPE (from_se.expr), tmp));
	    }
	}
      else
	{
	  vtab = gfc_find_vtab (&from_expr->ts);
	  gcc_assert (vtab);
	  tmp = gfc_build_addr_expr (NULL_TREE, gfc_get_symbol_decl (vtab));
	  gfc_add_modify_loc (input_location, &block, to_se.expr,
			      fold_convert (TREE_TYPE (to_se.expr), tmp));
	}

      gfc_free_expr (to_expr2);
      gfc_init_se (&to_se, NULL);

      if (from_expr->ts.type == BT_CLASS)
	{
	  gfc_free_expr (from_expr2);
	  gfc_init_se (&from_se, NULL);
	}
    }


  /* Deallocate "to".  */
  if (from_expr->rank == 0)
    {
      to_se.want_coarray = 1;
      from_se.want_coarray = 1;
    }
  gfc_conv_expr_descriptor (&to_se, to_expr);
  gfc_conv_expr_descriptor (&from_se, from_expr);

  /* For coarrays, call SYNC ALL if TO is already deallocated as MOVE_ALLOC
     is an image control "statement", cf. IR F08/0040 in 12-006A.  */
  if (coarray && flag_coarray == GFC_FCOARRAY_LIB)
    {
      tree cond;

      tmp = gfc_deallocate_with_status (to_se.expr, NULL_TREE, NULL_TREE,
					NULL_TREE, NULL_TREE, true, to_expr,
					GFC_CAF_COARRAY_DEALLOCATE_ONLY);
      gfc_add_expr_to_block (&block, tmp);

      tmp = gfc_conv_descriptor_data_get (to_se.expr);
      cond = fold_build2_loc (input_location, EQ_EXPR,
			      logical_type_node, tmp,
			      fold_convert (TREE_TYPE (tmp),
					    null_pointer_node));
      tmp = build_call_expr_loc (input_location, gfor_fndecl_caf_sync_all,
				 3, null_pointer_node, null_pointer_node,
				 build_int_cst (integer_type_node, 0));

      tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node, cond,
			     tmp, build_empty_stmt (input_location));
      gfc_add_expr_to_block (&block, tmp);
    }
  else
    {
      if (to_expr->ts.type == BT_DERIVED
	  && to_expr->ts.u.derived->attr.alloc_comp)
	{
	  tmp = gfc_deallocate_alloc_comp (to_expr->ts.u.derived,
					   to_se.expr, to_expr->rank);
	  gfc_add_expr_to_block (&block, tmp);
	}

      tmp = gfc_conv_descriptor_data_get (to_se.expr);
      tmp = gfc_deallocate_with_status (tmp, NULL_TREE, NULL_TREE, NULL_TREE,
					NULL_TREE, true, to_expr,
					GFC_CAF_COARRAY_NOCOARRAY);
      gfc_add_expr_to_block (&block, tmp);
    }

  /* Move the pointer and update the array descriptor data.  */
  gfc_add_modify_loc (input_location, &block, to_se.expr, from_se.expr);

  /* Set "from" to NULL.  */
  tmp = gfc_conv_descriptor_data_get (from_se.expr);
  gfc_add_modify_loc (input_location, &block, tmp,
		      fold_convert (TREE_TYPE (tmp), null_pointer_node));


  if (to_expr->ts.type == BT_CHARACTER && to_expr->ts.deferred)
    {
      gfc_add_modify_loc (input_location, &block, to_se.string_length,
			  fold_convert (TREE_TYPE (to_se.string_length),
					from_se.string_length));
      if (from_expr->ts.deferred)
        gfc_add_modify_loc (input_location, &block, from_se.string_length,
			build_int_cst (TREE_TYPE (from_se.string_length), 0));
    }

  return gfc_finish_block (&block);
}


tree
gfc_conv_intrinsic_subroutine (gfc_code *code)
{
  tree res;

  gcc_assert (code->resolved_isym);

  switch (code->resolved_isym->id)
    {
    case GFC_ISYM_MOVE_ALLOC:
      res = conv_intrinsic_move_alloc (code);
      break;

    case GFC_ISYM_ATOMIC_CAS:
      res = conv_intrinsic_atomic_cas (code);
      break;

    case GFC_ISYM_ATOMIC_ADD:
    case GFC_ISYM_ATOMIC_AND:
    case GFC_ISYM_ATOMIC_DEF:
    case GFC_ISYM_ATOMIC_OR:
    case GFC_ISYM_ATOMIC_XOR:
    case GFC_ISYM_ATOMIC_FETCH_ADD:
    case GFC_ISYM_ATOMIC_FETCH_AND:
    case GFC_ISYM_ATOMIC_FETCH_OR:
    case GFC_ISYM_ATOMIC_FETCH_XOR:
      res = conv_intrinsic_atomic_op (code);
      break;

    case GFC_ISYM_ATOMIC_REF:
      res = conv_intrinsic_atomic_ref (code);
      break;

    case GFC_ISYM_EVENT_QUERY:
      res = conv_intrinsic_event_query (code);
      break;

    case GFC_ISYM_C_F_POINTER:
    case GFC_ISYM_C_F_PROCPOINTER:
      res = conv_isocbinding_subroutine (code);
      break;

    case GFC_ISYM_CAF_SEND:
      res = conv_caf_send (code);
      break;

    case GFC_ISYM_CO_BROADCAST:
    case GFC_ISYM_CO_MIN:
    case GFC_ISYM_CO_MAX:
    case GFC_ISYM_CO_REDUCE:
    case GFC_ISYM_CO_SUM:
      res = conv_co_collective (code);
      break;

    case GFC_ISYM_FREE:
      res = conv_intrinsic_free (code);
      break;

    case GFC_ISYM_RANDOM_INIT:
      res = conv_intrinsic_random_init (code);
      break;

    case GFC_ISYM_KILL:
      res = conv_intrinsic_kill_sub (code);
      break;

    case GFC_ISYM_SYSTEM_CLOCK:
      res = conv_intrinsic_system_clock (code);
      break;

    default:
      res = NULL_TREE;
      break;
    }

  return res;
}

#include "gt-fortran-trans-intrinsic.h"
