/* OMP constructs' SIMD clone supporting code.

Copyright (C) 2005-2026 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "cfganal.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "langhooks.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "cfgloop.h"
#include "symbol-summary.h"
#include "ipa-param-manipulation.h"
#include "tree-eh.h"
#include "varasm.h"
#include "stringpool.h"
#include "attribs.h"
#include "omp-simd-clone.h"
#include "omp-low.h"
#include "omp-general.h"

/* Print debug info for ok_for_auto_simd_clone to the dump file, logging
   failure reason EXCUSE for function DECL.  Always returns false.  */
static bool
auto_simd_fail (tree decl, const char *excuse)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "\nNot auto-cloning %s because %s\n",
	     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
	     excuse);
  return false;
}

/* Helper function for ok_for_auto_simd_clone; return false if the statement
   violates restrictions for an "omp declare simd" function.  Specifically,
   the function must not
   - throw or call setjmp/longjmp
   - write memory that could alias parallel calls
   - read volatile memory
   - include openmp directives or calls
   - call functions that might do those things */

static bool
auto_simd_check_stmt (gimple *stmt, tree outer)
{
  tree decl;

  switch (gimple_code (stmt))
    {
    case GIMPLE_CALL:

      /* Calls to functions that are CONST or PURE are ok, even if they
	 are internal functions without a decl.  Reject other internal
	 functions.  */
      if (gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE))
	break;
      if (gimple_call_internal_p (stmt))
	return auto_simd_fail (outer,
			       "body contains internal function call");

      decl = gimple_call_fndecl (stmt);

      /* We can't know whether indirect calls are safe.  */
      if (decl == NULL_TREE)
	return auto_simd_fail (outer, "body contains indirect call");

      /* Calls to functions that are already marked "omp declare simd" are
	 OK.  */
      if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl)))
	break;

      /* Let recursive calls to the current function through.  */
      if (decl == outer)
	break;

      /* Other function calls are not permitted.  This covers all calls to
	 the libgomp API and setjmp/longjmp, too, as well as things like
	 __cxa_throw_ related to exception handling.  */
      return auto_simd_fail (outer, "body contains unsafe function call");

      /* Reject EH-related constructs.  Most of the EH gimple codes are
	already lowered by the time this pass runs during IPA.
	 GIMPLE_EH_DISPATCH and GIMPLE_RESX remain and are lowered by
	 pass_lower_eh_dispatch and pass_lower_resx, respectively; those
	 passes run later.  */
    case GIMPLE_EH_DISPATCH:
    case GIMPLE_RESX:
      return auto_simd_fail (outer, "body contains EH constructs");

      /* Asms are not permitted since we don't know what they do.  */
    case GIMPLE_ASM:
      return auto_simd_fail (outer, "body contains inline asm");

    default:
      break;
    }

  /* Memory writes are not permitted.
     FIXME: this could be relaxed a little to permit writes to
     function-local variables that could not alias other instances
     of the function running in parallel.  */
  if (gimple_store_p (stmt))
    return auto_simd_fail (outer, "body includes memory write");

  /* Volatile reads are not permitted.  */
  if (gimple_has_volatile_ops (stmt))
    return auto_simd_fail (outer, "body includes volatile op");

  /* Otherwise OK.  */
  return true;
}

/* Helper function for ok_for_auto_simd_clone:  return true if type T is
   plausible for a cloneable function argument or return type.  */
static bool
plausible_type_for_simd_clone (tree t)
{
  if (VOID_TYPE_P (t))
    return true;
  else if (RECORD_OR_UNION_TYPE_P (t) || !is_a <scalar_mode> (TYPE_MODE (t)))
    /* Small record/union types may fit into a scalar mode, but are
       still not suitable.  */
    return false;
  else if (TYPE_ATOMIC (t))
    /* Atomic types trigger warnings in simd_clone_clauses_extract.  */
    return false;
  else
    return true;
}

/* Check if the function NODE appears suitable for auto-annotation
   with "declare simd".  */

static bool
ok_for_auto_simd_clone (struct cgraph_node *node)
{
  tree decl = node->decl;
  tree t;
  basic_block bb;

  /* Nothing to do if the function isn't a definition or doesn't
     have a body.  */
  if (!node->definition || !node->has_gimple_body_p ())
    return auto_simd_fail (decl, "no definition or body");

  /* No point in trying to generate implicit clones if the function
     isn't used in the compilation unit.  */
  if (!node->callers)
    return auto_simd_fail (decl, "function is not used");

  /* Nothing to do if the function already has the "omp declare simd"
     attribute, is marked noclone, or is not "omp declare target".  */
  if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (decl))
      || lookup_attribute ("noclone", DECL_ATTRIBUTES (decl))
      || !lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
    return auto_simd_fail (decl, "incompatible attributes");

  /* Check whether the function is restricted host/nohost via the
     "omp declare target device_type" clause, and that doesn't match
     what we're compiling for.  Internally, these translate into
     "omp declare target [no]host" attributes on the decl; "any"
     translates into both attributes, but the default (which is supposed
     to be equivalent to "any") is neither.  */
  tree host = lookup_attribute ("omp declare target host",
				DECL_ATTRIBUTES (decl));
  tree nohost = lookup_attribute ("omp declare target nohost",
				  DECL_ATTRIBUTES (decl));
#ifdef ACCEL_COMPILER
  if (host && !nohost)
    return auto_simd_fail (decl, "device doesn't match for accel compiler");
#else
  if (nohost && !host)
    return auto_simd_fail (decl, "device doesn't match for host compiler");
#endif

  /* Backends will check for vectorizable arguments/return types in a
     target-specific way, but we can immediately filter out functions
     that have implausible argument/return types.  */
  t = TREE_TYPE (TREE_TYPE (decl));
  if (!plausible_type_for_simd_clone (t))
    return auto_simd_fail (decl, "return type fails sniff test");

  if (TYPE_ARG_TYPES (TREE_TYPE (decl)))
    {
      for (tree temp = TYPE_ARG_TYPES (TREE_TYPE (decl));
	   temp; temp = TREE_CHAIN (temp))
	{
	  t = TREE_VALUE (temp);
	  if (!plausible_type_for_simd_clone (t))
	    return auto_simd_fail (decl, "argument type fails sniff test");
	}
    }
  else if (DECL_ARGUMENTS (decl))
    {
      for (tree temp = DECL_ARGUMENTS (decl); temp; temp = DECL_CHAIN (temp))
	{
	  t = TREE_TYPE (temp);
	  if (!plausible_type_for_simd_clone (t))
	    return auto_simd_fail (decl, "argument type fails sniff test");
	}
    }
  else
    return auto_simd_fail (decl, "function has no arguments");

  /* Scan the function body to see if it is suitable for SIMD-ization.  */
  node->get_body ();

  FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl))
    {
      for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
	   gsi_next (&gsi))
	if (!auto_simd_check_stmt (gsi_stmt (gsi), decl))
	  return false;
    }

  /* All is good.  */
  if (dump_file)
    fprintf (dump_file, "\nMarking %s for auto-cloning\n",
	     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
  return true;
}

/* Allocate a fresh `simd_clone' and return it.  NARGS is the number
   of arguments to reserve space for.  */

static struct cgraph_simd_clone *
simd_clone_struct_alloc (int nargs)
{
  struct cgraph_simd_clone *clone_info;
  size_t len = (sizeof (struct cgraph_simd_clone)
		+ nargs * sizeof (struct cgraph_simd_clone_arg));
  clone_info = (struct cgraph_simd_clone *)
	       ggc_internal_cleared_alloc (len);
  return clone_info;
}

/* Make a copy of the `struct cgraph_simd_clone' in FROM to TO.  */

static inline void
simd_clone_struct_copy (struct cgraph_simd_clone *to,
			struct cgraph_simd_clone *from)
{
  memcpy (to, from, (sizeof (struct cgraph_simd_clone)
		     + ((from->nargs - from->inbranch)
			* sizeof (struct cgraph_simd_clone_arg))));
}

/* Fill an empty vector ARGS with parameter types of function FNDECL.  This
   uses TYPE_ARG_TYPES if available, otherwise falls back to types of
   DECL_ARGUMENTS types.  */

static void
simd_clone_vector_of_formal_parm_types (vec<tree> *args, tree fndecl)
{
  if (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
    {
      push_function_arg_types (args, TREE_TYPE (fndecl));
      return;
    }
  push_function_arg_decls (args, fndecl);
  unsigned int i;
  tree arg;
  FOR_EACH_VEC_ELT (*args, i, arg)
    (*args)[i] = TREE_TYPE ((*args)[i]);
}

/* Given a simd function in NODE, extract the simd specific
   information from the OMP clauses passed in CLAUSES, and return
   the struct cgraph_simd_clone * if it should be cloned.  *INBRANCH_SPECIFIED
   is set to TRUE if the `inbranch' or `notinbranch' clause specified,
   otherwise set to FALSE.  */

static struct cgraph_simd_clone *
simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
			    bool *inbranch_specified)
{
  auto_vec<tree> args;
  simd_clone_vector_of_formal_parm_types (&args, node->decl);
  tree t;
  int n;
  *inbranch_specified = false;

  n = args.length ();
  if (n > 0 && args.last () == void_type_node)
    n--;

  /* Allocate one more than needed just in case this is an in-branch
     clone which will require a mask argument.  */
  struct cgraph_simd_clone *clone_info = simd_clone_struct_alloc (n + 1);
  clone_info->nargs = n;

  if (!clauses)
    goto out;

  clauses = TREE_VALUE (clauses);
  if (!clauses || TREE_CODE (clauses) != OMP_CLAUSE)
    goto out;

  for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
    {
      switch (OMP_CLAUSE_CODE (t))
	{
	case OMP_CLAUSE_INBRANCH:
	  clone_info->inbranch = 1;
	  *inbranch_specified = true;
	  break;
	case OMP_CLAUSE_NOTINBRANCH:
	  clone_info->inbranch = 0;
	  *inbranch_specified = true;
	  break;
	case OMP_CLAUSE_SIMDLEN:
	  clone_info->simdlen
	    = TREE_INT_CST_LOW (OMP_CLAUSE_SIMDLEN_EXPR (t));
	  break;
	case OMP_CLAUSE_LINEAR:
	  {
	    tree decl = OMP_CLAUSE_DECL (t);
	    tree step = OMP_CLAUSE_LINEAR_STEP (t);
	    int argno = TREE_INT_CST_LOW (decl);
	    if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (t))
	      {
		enum cgraph_simd_clone_arg_type arg_type;
		if (TREE_CODE (args[argno]) == REFERENCE_TYPE)
		  switch (OMP_CLAUSE_LINEAR_KIND (t))
		    {
		    case OMP_CLAUSE_LINEAR_REF:
		      arg_type
			= SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP;
		      break;
		    case OMP_CLAUSE_LINEAR_UVAL:
		      arg_type
			= SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP;
		      break;
		    case OMP_CLAUSE_LINEAR_VAL:
		    case OMP_CLAUSE_LINEAR_DEFAULT:
		      arg_type
			= SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP;
		      break;
		    default:
		      gcc_unreachable ();
		    }
		else
		  arg_type = SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP;
		clone_info->args[argno].arg_type = arg_type;
		clone_info->args[argno].linear_step = tree_to_shwi (step);
		gcc_assert (clone_info->args[argno].linear_step >= 0
			    && clone_info->args[argno].linear_step < n);
	      }
	    else
	      {
		if (POINTER_TYPE_P (args[argno]))
		  step = fold_convert (ssizetype, step);
		if (!tree_fits_shwi_p (step))
		  {
		    warning_at (OMP_CLAUSE_LOCATION (t), OPT_Wopenmp,
				"ignoring large linear step");
		    return NULL;
		  }
		else if (integer_zerop (step))
		  {
		    warning_at (OMP_CLAUSE_LOCATION (t), OPT_Wopenmp,
				"ignoring zero linear step");
		    return NULL;
		  }
		else
		  {
		    enum cgraph_simd_clone_arg_type arg_type;
		    if (TREE_CODE (args[argno]) == REFERENCE_TYPE)
		      switch (OMP_CLAUSE_LINEAR_KIND (t))
			{
			case OMP_CLAUSE_LINEAR_REF:
			  arg_type
			    = SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP;
			  break;
			case OMP_CLAUSE_LINEAR_UVAL:
			  arg_type
			    = SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP;
			  break;
			case OMP_CLAUSE_LINEAR_VAL:
			case OMP_CLAUSE_LINEAR_DEFAULT:
			  arg_type
			    = SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP;
			  break;
			default:
			  gcc_unreachable ();
			}
		    else
		      arg_type = SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP;
		    clone_info->args[argno].arg_type = arg_type;
		    clone_info->args[argno].linear_step = tree_to_shwi (step);
		  }
	      }
	    break;
	  }
	case OMP_CLAUSE_UNIFORM:
	  {
	    tree decl = OMP_CLAUSE_DECL (t);
	    int argno = tree_to_uhwi (decl);
	    clone_info->args[argno].arg_type
	      = SIMD_CLONE_ARG_TYPE_UNIFORM;
	    break;
	  }
	case OMP_CLAUSE_ALIGNED:
	  {
	    /* Ignore aligned (x) for declare simd, for the ABI we really
	       need an alignment specified.  */
	    if (OMP_CLAUSE_ALIGNED_ALIGNMENT (t) == NULL_TREE)
	      break;
	    tree decl = OMP_CLAUSE_DECL (t);
	    int argno = tree_to_uhwi (decl);
	    clone_info->args[argno].alignment
	      = TREE_INT_CST_LOW (OMP_CLAUSE_ALIGNED_ALIGNMENT (t));
	    break;
	  }
	default:
	  break;
	}
    }

 out:
  if (TYPE_ATOMIC (TREE_TYPE (TREE_TYPE (node->decl))))
    {
      warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wopenmp,
		  "ignoring %<#pragma omp declare simd%> on function "
		  "with %<_Atomic%> qualified return type");
      return NULL;
    }

  for (unsigned int argno = 0; argno < clone_info->nargs; argno++)
    if (TYPE_ATOMIC (args[argno])
	&& clone_info->args[argno].arg_type != SIMD_CLONE_ARG_TYPE_UNIFORM)
      {
	warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wopenmp,
		    "ignoring %<#pragma omp declare simd%> on function "
		    "with %<_Atomic%> qualified non-%<uniform%> argument");
	args.release ();
	return NULL;
      }

  return clone_info;
}

/* Given a SIMD clone in NODE, calculate the characteristic data
   type and return the corresponding type.  The characteristic data
   type is computed as described in the Intel Vector ABI.  */

static tree
simd_clone_compute_base_data_type (struct cgraph_node *node,
				   struct cgraph_simd_clone *clone_info)
{
  tree type = integer_type_node;
  tree fndecl = node->decl;

  /* a) For non-void function, the characteristic data type is the
        return type.  */
  if (TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != VOID_TYPE)
    type = TREE_TYPE (TREE_TYPE (fndecl));

  /* b) If the function has any non-uniform, non-linear parameters,
        then the characteristic data type is the type of the first
        such parameter.  */
  else
    {
      auto_vec<tree> map;
      simd_clone_vector_of_formal_parm_types (&map, fndecl);
      for (unsigned int i = 0; i < clone_info->nargs; ++i)
	if (clone_info->args[i].arg_type == SIMD_CLONE_ARG_TYPE_VECTOR)
	  {
	    type = map[i];
	    break;
	  }
    }

  /* c) If the characteristic data type determined by a) or b) above
        is struct, union, or class type which is pass-by-value (except
        for the type that maps to the built-in complex data type), the
        characteristic data type is int.  */
  if (RECORD_OR_UNION_TYPE_P (type)
      && !aggregate_value_p (type, NULL)
      && TREE_CODE (type) != COMPLEX_TYPE)
    return integer_type_node;

  /* d) If none of the above three classes is applicable, the
        characteristic data type is int.  */

  return type;

  /* e) For Intel Xeon Phi native and offload compilation, if the
        resulting characteristic data type is 8-bit or 16-bit integer
        data type, the characteristic data type is int.  */
  /* Well, we don't handle Xeon Phi yet.  */
}

static tree
simd_clone_mangle (struct cgraph_node *node,
		   struct cgraph_simd_clone *clone_info)
{
  char vecsize_mangle = clone_info->vecsize_mangle;
  char mask = clone_info->inbranch ? 'M' : 'N';
  poly_uint64 simdlen = clone_info->simdlen;
  unsigned int n;
  pretty_printer pp;

  gcc_assert (vecsize_mangle && maybe_ne (simdlen, 0U));

  pp_string (&pp, "_ZGV");
  pp_character (&pp, vecsize_mangle);
  pp_character (&pp, mask);

  unsigned HOST_WIDE_INT len;
  if (simdlen.is_constant (&len))
    pp_decimal_int (&pp, (int) (len));
  else
    pp_character (&pp, 'x');

  for (n = 0; n < clone_info->nargs; ++n)
    {
      struct cgraph_simd_clone_arg arg = clone_info->args[n];

      switch (arg.arg_type)
	{
	case SIMD_CLONE_ARG_TYPE_UNIFORM:
	  pp_character (&pp, 'u');
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
	  pp_character (&pp, 'l');
	  goto mangle_linear;
	case SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP:
	  pp_character (&pp, 'R');
	  goto mangle_linear;
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
	  pp_character (&pp, 'L');
	  goto mangle_linear;
	case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
	  pp_character (&pp, 'U');
	  goto mangle_linear;
	mangle_linear:
	  gcc_assert (arg.linear_step != 0);
	  if (arg.linear_step > 1)
	    pp_unsigned_wide_integer (&pp, arg.linear_step);
	  else if (arg.linear_step < 0)
	    {
	      pp_character (&pp, 'n');
	      pp_unsigned_wide_integer (&pp, (-(unsigned HOST_WIDE_INT)
					      arg.linear_step));
	    }
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
	  pp_string (&pp, "ls");
	  pp_unsigned_wide_integer (&pp, arg.linear_step);
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP:
	  pp_string (&pp, "Rs");
	  pp_unsigned_wide_integer (&pp, arg.linear_step);
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
	  pp_string (&pp, "Ls");
	  pp_unsigned_wide_integer (&pp, arg.linear_step);
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
	  pp_string (&pp, "Us");
	  pp_unsigned_wide_integer (&pp, arg.linear_step);
	  break;
	default:
	  pp_character (&pp, 'v');
	}
      if (arg.alignment)
	{
	  pp_character (&pp, 'a');
	  pp_decimal_int (&pp, arg.alignment);
	}
    }

  pp_underscore (&pp);
  const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl));
  if (*str == '*')
    ++str;
  pp_string (&pp, str);
  str = pp_formatted_text (&pp);

  /* If there already is a SIMD clone with the same mangled name, don't
     add another one.  This can happen e.g. for
     #pragma omp declare simd
     #pragma omp declare simd simdlen(8)
     int foo (int, int);
     if the simdlen is assumed to be 8 for the first one, etc.  */
  for (struct cgraph_node *clone = node->simd_clones; clone;
       clone = clone->simdclone->next_clone)
    if (id_equal (DECL_ASSEMBLER_NAME (clone->decl), str))
      return NULL_TREE;

  return get_identifier (str);
}

/* Create a simd clone of OLD_NODE and return it.  If FORCE_LOCAL is true,
   create it as a local symbol, otherwise copy the symbol linkage and
   visibility attributes from OLD_NODE.  */

static struct cgraph_node *
simd_clone_create (struct cgraph_node *old_node, bool force_local)
{
  struct cgraph_node *new_node;
  if (old_node->definition)
    {
      if (!old_node->has_gimple_body_p ())
	return NULL;
      old_node->get_body ();
      new_node = old_node->create_version_clone_with_body (vNULL, NULL, NULL,
							   NULL, NULL,
							   "simdclone");
    }
  else
    {
      tree old_decl = old_node->decl;
      tree new_decl = copy_node (old_node->decl);
      DECL_NAME (new_decl) = clone_function_name_numbered (old_decl,
							   "simdclone");
      SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
      SET_DECL_RTL (new_decl, NULL);
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = old_node->create_version_clone (new_decl, vNULL, NULL);
      if (old_node->in_other_partition)
	new_node->in_other_partition = 1;
    }
  if (new_node == NULL)
    return new_node;

  set_decl_built_in_function (new_node->decl, NOT_BUILT_IN, 0);
  if (force_local)
    {
      TREE_PUBLIC (new_node->decl) = 0;
      DECL_COMDAT (new_node->decl) = 0;
      DECL_WEAK (new_node->decl) = 0;
      DECL_EXTERNAL (new_node->decl) = 0;
      DECL_VISIBILITY_SPECIFIED (new_node->decl) = 0;
      DECL_VISIBILITY (new_node->decl) = VISIBILITY_DEFAULT;
      DECL_DLLIMPORT_P (new_node->decl) = 0;
    }
  else
    {
      TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
      DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
      DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
      DECL_EXTERNAL (new_node->decl) = DECL_EXTERNAL (old_node->decl);
      DECL_VISIBILITY_SPECIFIED (new_node->decl)
	= DECL_VISIBILITY_SPECIFIED (old_node->decl);
      DECL_VISIBILITY (new_node->decl) = DECL_VISIBILITY (old_node->decl);
      DECL_DLLIMPORT_P (new_node->decl) = DECL_DLLIMPORT_P (old_node->decl);
      if (DECL_ONE_ONLY (old_node->decl))
	make_decl_one_only (new_node->decl,
			    DECL_ASSEMBLER_NAME (new_node->decl));

      /* The method cgraph_version_clone_with_body () will force the new
	 symbol local.  Undo this, and inherit external visibility from
	 the old node.  */
      new_node->local = old_node->local;
      new_node->externally_visible = old_node->externally_visible;
      new_node->has_omp_variant_constructs
	= old_node->has_omp_variant_constructs;
    }

  /* Mark clones with internal linkage as gc'able, so they will not be
     emitted unless the vectorizer can actually use them.  */
  if (!TREE_PUBLIC (new_node->decl))
    new_node->gc_candidate = true;

  return new_node;
}

/* Adjust the return type of the given function to its appropriate
   vector counterpart.  */

static void
simd_clone_adjust_return_type (struct cgraph_node *node)
{
  tree fndecl = node->decl;
  tree orig_rettype = TREE_TYPE (TREE_TYPE (fndecl));
  poly_uint64 veclen;
  tree t;

  /* Adjust the function return type.  */
  if (VOID_TYPE_P (orig_rettype))
    return;
  t = TREE_TYPE (TREE_TYPE (fndecl));
  if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
    veclen = node->simdclone->vecsize_int;
  else
    veclen = node->simdclone->vecsize_float;
  if (known_eq (veclen, 0U))
    veclen = node->simdclone->simdlen;
  else
    veclen = exact_div (veclen, GET_MODE_BITSIZE (SCALAR_TYPE_MODE (t)));
  if (multiple_p (veclen, node->simdclone->simdlen))
    veclen = node->simdclone->simdlen;
  if (POINTER_TYPE_P (t))
    t = pointer_sized_int_node;
  if (known_eq (veclen, node->simdclone->simdlen))
    t = build_vector_type (t, node->simdclone->simdlen);
  else
    {
      t = build_vector_type (t, veclen);
      t = build_array_type_nelts (t, exact_div (node->simdclone->simdlen,
						veclen));
    }
  TREE_TYPE (TREE_TYPE (fndecl)) = t;
}

/* Each vector argument has a corresponding array to be used locally
   as part of the eventual loop.  Create such temporary array and
   return it.

   PREFIX is the prefix to be used for the temporary.

   TYPE is the inner element type.

   SIMDLEN is the number of elements.  */

static tree
create_tmp_simd_array (const char *prefix, tree type, poly_uint64 simdlen)
{
  tree atype = build_array_type_nelts (type, simdlen);
  tree avar = create_tmp_var_raw (atype, prefix);
  gimple_add_tmp_var (avar);
  return avar;
}

/* Modify the function argument types to their corresponding vector
   counterparts if appropriate.  Also, create one array for each simd
   argument to be used locally when using the function arguments as
   part of the loop.

   NODE is the function whose arguments are to be adjusted.

   If NODE does not represent function definition, returns NULL.  Otherwise
   returns an adjustment class that will be filled describing how the argument
   declarations will be remapped.  New arguments which are not to be remapped
   are marked with USER_FLAG.  */

static void
simd_clone_adjust_argument_types (struct cgraph_node *node)
{
  auto_vec<tree> args;

  if (node->definition)
    push_function_arg_decls (&args, node->decl);
  else
    simd_clone_vector_of_formal_parm_types (&args, node->decl);
  struct cgraph_simd_clone *sc = node->simdclone;
  unsigned i, k;
  poly_uint64 veclen;
  auto_vec<tree> new_params;

  for (i = 0; i < sc->nargs; ++i)
    {
      tree parm = NULL_TREE;
      tree parm_type = NULL_TREE;
      if (i < args.length())
	{
	  parm = args[i];
	  parm_type = node->definition ? TREE_TYPE (parm) : parm;
	}

      sc->args[i].orig_arg = node->definition ? parm : NULL_TREE;
      sc->args[i].orig_type = parm_type;

      switch (sc->args[i].arg_type)
	{
	default:
	  new_params.safe_push (parm_type);
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
	case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
	  new_params.safe_push (parm_type);
	  if (node->definition)
	    sc->args[i].simd_array
	      = create_tmp_simd_array (IDENTIFIER_POINTER (DECL_NAME (parm)),
				       TREE_TYPE (parm_type),
				       sc->simdlen);
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
	case SIMD_CLONE_ARG_TYPE_VECTOR:
	  if (INTEGRAL_TYPE_P (parm_type) || POINTER_TYPE_P (parm_type))
	    veclen = sc->vecsize_int;
	  else
	    veclen = sc->vecsize_float;
	  if (known_eq (veclen, 0U))
	    veclen = sc->simdlen;
	  else
	    veclen
	      = exact_div (veclen,
			   GET_MODE_BITSIZE (SCALAR_TYPE_MODE (parm_type)));
	  if (multiple_p (veclen, sc->simdlen))
	    veclen = sc->simdlen;
	  tree vtype;
	  if (POINTER_TYPE_P (parm_type))
	    vtype = build_vector_type (pointer_sized_int_node, veclen);
	  else
	    vtype = build_vector_type (parm_type, veclen);
	  sc->args[i].vector_type = vtype;
	  k = vector_unroll_factor (sc->simdlen, veclen);
	  for (unsigned j = 0; j < k; j++)
	    new_params.safe_push (vtype);

	  if (node->definition)
	    sc->args[i].simd_array
	      = create_tmp_simd_array (DECL_NAME (parm)
				       ? IDENTIFIER_POINTER (DECL_NAME (parm))
				       : NULL, parm_type, sc->simdlen);
	}
    }

  if (sc->inbranch)
    {
      tree base_type = simd_clone_compute_base_data_type (sc->origin, sc);
      tree mask_type;
      if (INTEGRAL_TYPE_P (base_type) || POINTER_TYPE_P (base_type))
	veclen = sc->vecsize_int;
      else
	veclen = sc->vecsize_float;
      if (known_eq (veclen, 0U))
	veclen = sc->simdlen;
      else
	veclen = exact_div (veclen,
			    GET_MODE_BITSIZE (SCALAR_TYPE_MODE (base_type)));
      if (multiple_p (veclen, sc->simdlen))
	veclen = sc->simdlen;
      if (sc->mask_mode != VOIDmode)
	mask_type
	  = lang_hooks.types.type_for_mode (sc->mask_mode, 1);
      else if (POINTER_TYPE_P (base_type))
	mask_type = build_vector_type (pointer_sized_int_node, veclen);
      else
	mask_type = build_vector_type (base_type, veclen);

      k = vector_unroll_factor (sc->simdlen, veclen);

      /* We have previously allocated one extra entry for the mask.  Use
	 it and fill it.  */
      sc->nargs++;
      if (sc->mask_mode != VOIDmode)
	base_type = boolean_type_node;
      if (node->definition)
	{
	  sc->args[i].orig_arg
	    = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL, base_type);
	  if (sc->mask_mode == VOIDmode)
	    sc->args[i].simd_array
	      = create_tmp_simd_array ("mask", base_type, sc->simdlen);
	  else if (k > 1)
	    sc->args[i].simd_array
	      = create_tmp_simd_array ("mask", mask_type, k);
	  else
	    sc->args[i].simd_array = NULL_TREE;
	}
      sc->args[i].orig_type = base_type;
      sc->args[i].arg_type = SIMD_CLONE_ARG_TYPE_MASK;
      sc->args[i].vector_type = mask_type;
      /* Record the number of mask copies when that is difficult to
	 compute.  */
      if (sc->mask_mode != VOIDmode)
	sc->args[i].linear_step = k;
    }

  if (!node->definition)
    {
      tree new_arg_types = NULL_TREE, new_reversed;
      bool last_parm_void = false;
      if (args.length () > 0 && args.last () == void_type_node)
	last_parm_void = true;

      gcc_assert (TYPE_ARG_TYPES (TREE_TYPE (node->decl)));
      for (i = 0; i < new_params.length (); i++)
	new_arg_types = tree_cons (NULL_TREE, new_params[i], new_arg_types);
      new_reversed = nreverse (new_arg_types);
      if (last_parm_void)
	{
	  if (new_reversed)
	    TREE_CHAIN (new_arg_types) = void_list_node;
	  else
	    new_reversed = void_list_node;
	}
      TYPE_ARG_TYPES (TREE_TYPE (node->decl)) = new_reversed;
    }
}

/* Initialize and copy the function arguments in NODE to their
   corresponding local simd arrays.  Returns a fresh gimple_seq with
   the instruction sequence generated.  */

static gimple_seq
simd_clone_init_simd_arrays (struct cgraph_node *node,
			     ipa_param_body_adjustments *adjustments)
{
  gimple_seq seq = NULL;
  unsigned i = 0, j = 0, k;

  for (tree arg = DECL_ARGUMENTS (node->decl);
       arg;
       arg = DECL_CHAIN (arg), i++, j++)
    {
      ipa_adjusted_param adj = (*adjustments->m_adj_params)[j];
      if (adj.op == IPA_PARAM_OP_COPY
	  || POINTER_TYPE_P (TREE_TYPE (arg)))
	continue;

      node->simdclone->args[i].vector_arg = arg;

      tree array = node->simdclone->args[i].simd_array;
      if (node->simdclone->mask_mode != VOIDmode
	  && adj.param_prefix_index == IPA_PARAM_PREFIX_MASK)
	{
	  if (array == NULL_TREE)
	    continue;
	  unsigned int l
	    = tree_to_uhwi (TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (array))));
	  for (k = 0; k <= l; k++)
	    {
	      if (k)
		{
		  arg = DECL_CHAIN (arg);
		  j++;
		}
	      tree t = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (array)),
			       array, size_int (k), NULL, NULL);
	      t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
	      gimplify_and_add (t, &seq);
	    }
	  continue;
	}
      if (!VECTOR_TYPE_P (TREE_TYPE (arg))
	  || known_eq (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg)),
		       node->simdclone->simdlen))
	{
	  tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
	  tree ptr = build_fold_addr_expr (array);
	  tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
			   build_int_cst (ptype, 0));
	  t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
	  gimplify_and_add (t, &seq);
	}
      else
	{
	  poly_uint64 simdlen = TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg));
	  unsigned int times = vector_unroll_factor (node->simdclone->simdlen,
						     simdlen);
	  tree ptype = build_pointer_type (TREE_TYPE (TREE_TYPE (array)));
	  for (k = 0; k < times; k++)
	    {
	      tree ptr = build_fold_addr_expr (array);
	      int elemsize;
	      if (k)
		{
		  arg = DECL_CHAIN (arg);
		  j++;
		}
	      tree elemtype = TREE_TYPE (TREE_TYPE (arg));
	      elemsize = GET_MODE_SIZE (SCALAR_TYPE_MODE (elemtype));
	      tree t = build2 (MEM_REF, TREE_TYPE (arg), ptr,
			       build_int_cst (ptype, k * elemsize * simdlen));
	      t = build2 (MODIFY_EXPR, TREE_TYPE (t), t, arg);
	      gimplify_and_add (t, &seq);
	    }
	}
    }
  return seq;
}

/* Callback info for ipa_simd_modify_stmt_ops below.  */

struct modify_stmt_info {
  ipa_param_body_adjustments *adjustments;
  gimple *stmt;
  gimple *after_stmt;
  /* True if the parent statement was modified by
     ipa_simd_modify_stmt_ops.  */
  bool modified;
};

/* Callback for walk_gimple_op.

   Adjust operands from a given statement as specified in the
   adjustments vector in the callback data.  */

static tree
ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
{
  struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
  struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info;
  tree *orig_tp = tp;
  if (TREE_CODE (*tp) == ADDR_EXPR)
    tp = &TREE_OPERAND (*tp, 0);

  if (TREE_CODE (*tp) == BIT_FIELD_REF
      || TREE_CODE (*tp) == IMAGPART_EXPR
      || TREE_CODE (*tp) == REALPART_EXPR)
    tp = &TREE_OPERAND (*tp, 0);

  tree repl = NULL_TREE;
  ipa_param_body_replacement *pbr = NULL;

  if (TREE_CODE (*tp) == PARM_DECL)
    {
      pbr = info->adjustments->get_expr_replacement (*tp, true);
      if (pbr)
	repl = pbr->repl;
    }
  else if (TYPE_P (*tp))
    *walk_subtrees = 0;

  if (repl)
    repl = unshare_expr (repl);
  else
    {
      if (tp != orig_tp)
	{
	  *walk_subtrees = 0;
	  bool modified = info->modified;
	  info->modified = false;
	  walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset);
	  if (!info->modified)
	    {
	      info->modified = modified;
	      return NULL_TREE;
	    }
	  info->modified = modified;
	  repl = *tp;
	}
      else
	return NULL_TREE;
    }

  if (tp != orig_tp)
    {
      if (gimple_code (info->stmt) == GIMPLE_PHI
	  && pbr
	  && TREE_CODE (*orig_tp) == ADDR_EXPR
	  && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL
	  && pbr->dummy)
	{
	  gcc_assert (TREE_CODE (pbr->dummy) == SSA_NAME);
	  *orig_tp = pbr->dummy;
	  info->modified = true;
	  return NULL_TREE;
	}

      repl = build_fold_addr_expr (repl);
      gimple *stmt;
      if (is_gimple_debug (info->stmt))
	{
	  tree vexpr = build_debug_expr_decl (TREE_TYPE (repl));
	  stmt = gimple_build_debug_source_bind (vexpr, repl, NULL);
	  repl = vexpr;
	}
      else
	{
	  stmt = gimple_build_assign (make_ssa_name (TREE_TYPE (repl)), repl);
	  repl = gimple_assign_lhs (stmt);
	}
      gimple_stmt_iterator gsi;
      if (gimple_code (info->stmt) == GIMPLE_PHI)
	{
	  if (info->after_stmt)
	    gsi = gsi_for_stmt (info->after_stmt);
	  else
	    gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
	  /* Cache SSA_NAME for next time.  */
	  if (pbr
	      && TREE_CODE (*orig_tp) == ADDR_EXPR
	      && TREE_CODE (TREE_OPERAND (*orig_tp, 0)) == PARM_DECL)
	    {
	      gcc_assert (!pbr->dummy);
	      pbr->dummy = repl;
	    }
	}
      else
	gsi = gsi_for_stmt (info->stmt);
      if (info->after_stmt)
	gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
      else
	gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
      if (gimple_code (info->stmt) == GIMPLE_PHI)
	info->after_stmt = stmt;
      *orig_tp = repl;
    }
  else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
    {
      tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
      *tp = vce;
    }
  else
    *tp = repl;

  info->modified = true;
  return NULL_TREE;
}

/* Traverse the function body and perform all modifications as
   described in ADJUSTMENTS.  At function return, ADJUSTMENTS will be
   modified such that the replacement/reduction value will now be an
   offset into the corresponding simd_array.

   This function will replace all function argument uses with their
   corresponding simd array elements, and adjust the return values
   accordingly.  */

static void
ipa_simd_modify_function_body (struct cgraph_node *node,
			       ipa_param_body_adjustments *adjustments,
			       tree retval_array, tree iter)
{
  basic_block bb;
  unsigned int i, j;


  /* Register replacements for every function argument use to an offset into
     the corresponding simd_array.  */
  for (i = 0, j = 0; i < node->simdclone->nargs; ++i, ++j)
    {
      if (!node->simdclone->args[i].vector_arg
	  || (*adjustments->m_adj_params)[j].user_flag)
	continue;

      tree basetype = TREE_TYPE (node->simdclone->args[i].orig_arg);
      tree vectype = TREE_TYPE (node->simdclone->args[i].vector_arg);
      tree r = build4 (ARRAY_REF, basetype, node->simdclone->args[i].simd_array,
		  iter, NULL_TREE, NULL_TREE);
      adjustments->register_replacement (&(*adjustments->m_adj_params)[j], r);

      if (multiple_p (node->simdclone->simdlen, TYPE_VECTOR_SUBPARTS (vectype)))
	j += vector_unroll_factor (node->simdclone->simdlen,
				   TYPE_VECTOR_SUBPARTS (vectype)) - 1;
    }
  adjustments->sort_replacements ();

  tree name;
  FOR_EACH_SSA_NAME (i, name, cfun)
    {
      tree base_var;
      if (SSA_NAME_VAR (name)
	  && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL
	  && (base_var
	      = adjustments->get_replacement_ssa_base (SSA_NAME_VAR (name))))
	{
	  if (SSA_NAME_IS_DEFAULT_DEF (name))
	    {
	      tree old_decl = SSA_NAME_VAR (name);
	      bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
	      gimple_stmt_iterator gsi = gsi_after_labels (bb);
	      tree repl = adjustments->lookup_replacement (old_decl, 0);
	      gcc_checking_assert (repl);
	      repl = unshare_expr (repl);
	      set_ssa_default_def (cfun, old_decl, NULL_TREE);
	      SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
	      SSA_NAME_IS_DEFAULT_DEF (name) = 0;
	      gimple *stmt = gimple_build_assign (name, repl);
	      gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
	    }
	  else
	    SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var);
	}
    }

  struct modify_stmt_info info;
  info.adjustments = adjustments;

  FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->decl))
    {
      gimple_stmt_iterator gsi;

      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
	  int i, n = gimple_phi_num_args (phi);
	  info.stmt = phi;
	  info.after_stmt = NULL;
	  struct walk_stmt_info wi;
	  memset (&wi, 0, sizeof (wi));
	  info.modified = false;
	  wi.info = &info;
	  for (i = 0; i < n; ++i)
	    {
	      int walk_subtrees = 1;
	      tree arg = gimple_phi_arg_def (phi, i);
	      tree op = arg;
	      ipa_simd_modify_stmt_ops (&op, &walk_subtrees, &wi);
	      if (op != arg)
		{
		  SET_PHI_ARG_DEF (phi, i, op);
		  gcc_assert (TREE_CODE (op) == SSA_NAME);
		  if (gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL)
		    SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) = 1;
		}
	    }
	}

      gsi = gsi_start_bb (bb);
      while (!gsi_end_p (gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  info.stmt = stmt;
	  info.after_stmt = NULL;
	  struct walk_stmt_info wi;

	  memset (&wi, 0, sizeof (wi));
	  info.modified = false;
	  wi.info = &info;
	  walk_gimple_op (stmt, ipa_simd_modify_stmt_ops, &wi);

	  if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
	    {
	      tree retval = gimple_return_retval (return_stmt);
	      edge e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
	      e->flags |= EDGE_FALLTHRU;
	      if (!retval)
		{
		  gsi_remove (&gsi, true);
		  continue;
		}

	      /* Replace `return foo' with `retval_array[iter] = foo'.  */
	      tree ref = build4 (ARRAY_REF, TREE_TYPE (retval),
				 retval_array, iter, NULL, NULL);
	      stmt = gimple_build_assign (ref, retval);
	      gsi_replace (&gsi, stmt, true);
	      info.modified = true;
	    }

	  if (info.modified)
	    {
	      update_stmt (stmt);
	      /* If the above changed the var of a debug bind into something
		 different, remove the debug stmt.  We could also for all the
		 replaced parameters add VAR_DECLs for debug info purposes,
		 add debug stmts for those to be the simd array accesses and
		 replace debug stmt var operand with that var.  Debugging of
		 vectorized loops doesn't work too well, so don't bother for
		 now.  */
	      if ((gimple_debug_bind_p (stmt)
		   && !DECL_P (gimple_debug_bind_get_var (stmt)))
		  || (gimple_debug_source_bind_p (stmt)
		      && !DECL_P (gimple_debug_source_bind_get_var (stmt))))
		{
		  gsi_remove (&gsi, true);
		  continue;
		}
	      if (maybe_clean_eh_stmt (stmt))
		gimple_purge_dead_eh_edges (gimple_bb (stmt));
	    }
	  gsi_next (&gsi);
	}
    }
}

/* Helper function of simd_clone_adjust, return linear step addend
   of Ith argument.  */

static tree
simd_clone_linear_addend (struct cgraph_node *node, unsigned int i,
			  tree addtype, basic_block entry_bb)
{
  tree ptype = NULL_TREE;
  switch (node->simdclone->args[i].arg_type)
    {
    case SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP:
    case SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP:
    case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
    case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP:
      return build_int_cst (addtype, node->simdclone->args[i].linear_step);
    case SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP:
    case SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP:
      ptype = TREE_TYPE (node->simdclone->args[i].orig_arg);
      break;
    case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
    case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
      ptype = TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg));
      break;
    default:
      gcc_unreachable ();
    }

  unsigned int idx = node->simdclone->args[i].linear_step;
  tree arg = node->simdclone->args[idx].orig_arg;
  gcc_assert (is_gimple_reg_type (TREE_TYPE (arg)));
  gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
  gimple *g;
  tree ret;
  if (is_gimple_reg (arg))
    ret = get_or_create_ssa_default_def (cfun, arg);
  else
    {
      g = gimple_build_assign (make_ssa_name (TREE_TYPE (arg)), arg);
      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
      ret = gimple_assign_lhs (g);
    }
  if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE)
    {
      g = gimple_build_assign (make_ssa_name (TREE_TYPE (TREE_TYPE (arg))),
			       build_simple_mem_ref (ret));
      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
      ret = gimple_assign_lhs (g);
    }
  if (!useless_type_conversion_p (addtype, TREE_TYPE (ret)))
    {
      g = gimple_build_assign (make_ssa_name (addtype), NOP_EXPR, ret);
      gsi_insert_before (&gsi, g, GSI_SAME_STMT);
      ret = gimple_assign_lhs (g);
    }
  if (POINTER_TYPE_P (ptype))
    {
      tree size = TYPE_SIZE_UNIT (TREE_TYPE (ptype));
      if (size && TREE_CODE (size) == INTEGER_CST)
	{
	  g = gimple_build_assign (make_ssa_name (addtype), MULT_EXPR,
				   ret, fold_convert (addtype, size));
	  gsi_insert_before (&gsi, g, GSI_SAME_STMT);
	  ret = gimple_assign_lhs (g);
	}
    }
  return ret;
}

/* Adjust the argument types in NODE to their appropriate vector
   counterparts.  */

static void
simd_clone_adjust (struct cgraph_node *node)
{
  push_cfun (DECL_STRUCT_FUNCTION (node->decl));

  tree orig_rettype = TREE_TYPE (TREE_TYPE (node->decl));
  TREE_TYPE (node->decl) = build_distinct_type_copy (TREE_TYPE (node->decl));
  simd_clone_adjust_return_type (node);
  simd_clone_adjust_argument_types (node);
  targetm.simd_clone.adjust (node);
  tree retval = NULL_TREE;
  if (!VOID_TYPE_P (orig_rettype))
    {
      poly_uint64 veclen;
      if (INTEGRAL_TYPE_P (orig_rettype) || POINTER_TYPE_P (orig_rettype))
	veclen = node->simdclone->vecsize_int;
      else
	veclen = node->simdclone->vecsize_float;
      if (known_eq (veclen, 0U))
	veclen = node->simdclone->simdlen;
      else
	veclen = exact_div (veclen,
			    GET_MODE_BITSIZE (SCALAR_TYPE_MODE (orig_rettype)));
      if (multiple_p (veclen, node->simdclone->simdlen))
	veclen = node->simdclone->simdlen;

      retval = DECL_RESULT (node->decl);
      /* Adjust the DECL_RESULT.  */
      TREE_TYPE (retval) = TREE_TYPE (TREE_TYPE (node->decl));
      relayout_decl (retval);

      tree atype = build_array_type_nelts (orig_rettype,
					   node->simdclone->simdlen);
      if (maybe_ne (veclen, node->simdclone->simdlen))
	retval = build1 (VIEW_CONVERT_EXPR, atype, retval);
      else
	{
	  /* Set up a SIMD array to use as the return value.  */
	  retval = create_tmp_var_raw (atype, "retval");
	  gimple_add_tmp_var (retval);
	}
    }

  struct cgraph_simd_clone *sc = node->simdclone;
  vec<ipa_adjusted_param, va_gc> *new_params = NULL;
  vec_safe_reserve (new_params, sc->nargs);
  unsigned i, j, k;
  for (i = 0; i < sc->nargs; ++i)
    {
      ipa_adjusted_param adj;
      memset (&adj, 0, sizeof (adj));
      poly_uint64 veclen;
      tree elem_type;

      adj.base_index = i;
      adj.prev_clone_index = i;
      switch (sc->args[i].arg_type)
	{
	default:
	  /* No adjustment necessary for scalar arguments.  */
	  adj.op = IPA_PARAM_OP_COPY;
	  break;
	case SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP:
	  adj.op = IPA_PARAM_OP_COPY;
	  break;
	case SIMD_CLONE_ARG_TYPE_MASK:
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_CONSTANT_STEP:
	case SIMD_CLONE_ARG_TYPE_LINEAR_VAL_VARIABLE_STEP:
	case SIMD_CLONE_ARG_TYPE_VECTOR:
	  if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK
	      && sc->mask_mode != VOIDmode)
	    elem_type = simd_clone_compute_base_data_type (sc->origin, sc);
	  else
	    elem_type = TREE_TYPE (sc->args[i].vector_type);
	  if (INTEGRAL_TYPE_P (elem_type) || POINTER_TYPE_P (elem_type))
	    veclen = sc->vecsize_int;
	  else
	    veclen = sc->vecsize_float;
	  if (known_eq (veclen, 0U))
	    veclen = sc->simdlen;
	  else
	    veclen
	      = exact_div (veclen,
			   GET_MODE_BITSIZE (SCALAR_TYPE_MODE (elem_type)));
	  if (multiple_p (veclen, sc->simdlen))
	    veclen = sc->simdlen;
	  if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
	    {
	      adj.user_flag = 1;
	      adj.param_prefix_index = IPA_PARAM_PREFIX_MASK;
	    }
	  else
	    adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
	  adj.op = IPA_PARAM_OP_NEW;
	  adj.type =  sc->args[i].vector_type;
	  k = vector_unroll_factor (sc->simdlen, veclen);
	  for (j = 1; j < k; j++)
	    {
	      vec_safe_push (new_params, adj);
	      if (j == 1)
		{
		  memset (&adj, 0, sizeof (adj));
		  adj.op = IPA_PARAM_OP_NEW;
		  adj.user_flag = 1;
		  if (sc->args[i].arg_type == SIMD_CLONE_ARG_TYPE_MASK)
		    adj.param_prefix_index = IPA_PARAM_PREFIX_MASK;
		  else
		    adj.param_prefix_index = IPA_PARAM_PREFIX_SIMD;
		  adj.base_index = i;
		  adj.prev_clone_index = i;
		  adj.type = sc->args[i].vector_type;
		}
	    }
	}
      vec_safe_push (new_params, adj);
    }
  ipa_param_body_adjustments *adjustments
    = new ipa_param_body_adjustments (new_params, node->decl);
  adjustments->modify_formal_parameters ();

  push_gimplify_context ();

  gimple_seq seq = simd_clone_init_simd_arrays (node, adjustments);

  /* Adjust all uses of vector arguments accordingly.  Adjust all
     return values accordingly.  */
  tree iter = create_tmp_var (unsigned_type_node, "iter");
  tree iter1 = make_ssa_name (iter);
  tree iter2 = NULL_TREE;
  ipa_simd_modify_function_body (node, adjustments, retval, iter1);
  delete adjustments;

  /* Initialize the iteration variable.  */
  basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  basic_block body_bb = split_block_after_labels (entry_bb)->dest;
  gimple_stmt_iterator gsi = gsi_after_labels (entry_bb);
  /* Insert the SIMD array and iv initialization at function
     entry.  */
  gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT);

  pop_gimplify_context (NULL);

  gimple *g;
  basic_block incr_bb = NULL;
  class loop *loop = NULL;

  /* Create a new BB right before the original exit BB, to hold the
     iteration increment and the condition/branch.  */
  if (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
    {
      basic_block orig_exit = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0)->src;
      incr_bb = create_empty_bb (orig_exit);
      incr_bb->count = profile_count::zero ();
      add_bb_to_loop (incr_bb, body_bb->loop_father);
      while (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
	{
	  edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
	  redirect_edge_succ (e, incr_bb);
	  incr_bb->count += e->count ();
	}
    }
  else if (node->simdclone->inbranch)
    {
      incr_bb = create_empty_bb (entry_bb);
      incr_bb->count = profile_count::zero ();
      add_bb_to_loop (incr_bb, body_bb->loop_father);
    }

  if (incr_bb)
    {
      make_single_succ_edge (incr_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
      gsi = gsi_last_bb (incr_bb);
      iter2 = make_ssa_name (iter);
      g = gimple_build_assign (iter2, PLUS_EXPR, iter1,
			       build_int_cst (unsigned_type_node, 1));
      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);

      /* Mostly annotate the loop for the vectorizer (the rest is done
	 below).  */
      loop = alloc_loop ();
      cfun->has_force_vectorize_loops = true;
      /* We can assert that safelen is the 'minimum' simdlen.  */
      loop->safelen = constant_lower_bound (node->simdclone->simdlen);
      loop->force_vectorize = true;
      loop->header = body_bb;
    }

  /* Branch around the body if the mask applies.  */
  if (node->simdclone->inbranch)
    {
      gsi = gsi_last_bb (loop->header);
      tree mask_array
	= node->simdclone->args[node->simdclone->nargs - 1].simd_array;
      tree mask;
      if (node->simdclone->mask_mode != VOIDmode)
	{
	  tree shift_cnt;
	  if (mask_array == NULL_TREE)
	    {
	      tree arg = node->simdclone->args[node->simdclone->nargs
					       - 1].vector_arg;
	      mask = get_or_create_ssa_default_def (cfun, arg);
	      shift_cnt = iter1;
	    }
	  else
	    {
	      tree maskt = TREE_TYPE (mask_array);
	      int c = tree_to_uhwi (TYPE_MAX_VALUE (TYPE_DOMAIN (maskt)));
	      /* For now, c must be constant here.  */
	      c = exact_div (node->simdclone->simdlen, c + 1).to_constant ();
	      int s = exact_log2 (c);
	      gcc_assert (s > 0);
	      c--;
	      tree idx = make_ssa_name (TREE_TYPE (iter1));
	      g = gimple_build_assign (idx, RSHIFT_EXPR, iter1,
				       build_int_cst (integer_type_node, s));
	      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	      mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)));
	      tree aref = build4 (ARRAY_REF,
				  TREE_TYPE (TREE_TYPE (mask_array)),
				  mask_array, idx, NULL, NULL);
	      g = gimple_build_assign (mask, aref);
	      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	      shift_cnt = make_ssa_name (TREE_TYPE (iter1));
	      g = gimple_build_assign (shift_cnt, BIT_AND_EXPR, iter1,
				       build_int_cst (TREE_TYPE (iter1), c));
	      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	    }
	  tree shift_cnt_conv = shift_cnt;
	  if (!useless_type_conversion_p (TREE_TYPE (mask),
					  TREE_TYPE (shift_cnt)))
	    {
	      shift_cnt_conv = make_ssa_name (TREE_TYPE (mask));
	      g = gimple_build_assign (shift_cnt_conv, NOP_EXPR, shift_cnt);
	      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	    }
	  g = gimple_build_assign (make_ssa_name (TREE_TYPE (mask)),
				   RSHIFT_EXPR, mask, shift_cnt_conv);
	  gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	  mask = gimple_assign_lhs (g);
	  g = gimple_build_assign (make_ssa_name (TREE_TYPE (mask)),
				   BIT_AND_EXPR, mask,
				   build_one_cst (TREE_TYPE (mask)));
	  gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	  mask = gimple_assign_lhs (g);
	}
      else
	{
	  mask = make_ssa_name (TREE_TYPE (TREE_TYPE (mask_array)));
	  tree aref = build4 (ARRAY_REF,
			      TREE_TYPE (TREE_TYPE (mask_array)),
			      mask_array, iter1, NULL, NULL);
	  g = gimple_build_assign (mask, aref);
	  gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	  int bitsize = GET_MODE_BITSIZE (SCALAR_TYPE_MODE (TREE_TYPE (aref)));
	  if (!INTEGRAL_TYPE_P (TREE_TYPE (aref)))
	    {
	      aref = build1 (VIEW_CONVERT_EXPR,
			     build_nonstandard_integer_type (bitsize, 0),
							     mask);
	      mask = make_ssa_name (TREE_TYPE (aref));
	      g = gimple_build_assign (mask, aref);
	      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
	    }
	}

      g = gimple_build_cond (EQ_EXPR, mask, build_zero_cst (TREE_TYPE (mask)),
			     NULL, NULL);
      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
      edge e = make_edge (loop->header, incr_bb, EDGE_TRUE_VALUE);
      e->probability = profile_probability::unlikely ().guessed ();
      incr_bb->count += e->count ();
      edge fallthru = FALLTHRU_EDGE (loop->header);
      fallthru->flags = EDGE_FALSE_VALUE;
      fallthru->probability = profile_probability::likely ().guessed ();
    }

  basic_block latch_bb = NULL;
  basic_block new_exit_bb = NULL;

  /* Generate the condition.  */
  if (incr_bb)
    {
      gsi = gsi_last_bb (incr_bb);
      g = gimple_build_cond (LT_EXPR, iter2,
			     build_int_cst (unsigned_type_node,
					    node->simdclone->simdlen),
			     NULL, NULL);
      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
      edge e = split_block (incr_bb, gsi_stmt (gsi));
      latch_bb = e->dest;
      new_exit_bb = split_block_after_labels (latch_bb)->dest;
      loop->latch = latch_bb;

      redirect_edge_succ (FALLTHRU_EDGE (latch_bb), body_bb);

      edge new_e = make_edge (incr_bb, new_exit_bb, EDGE_FALSE_VALUE);

      /* FIXME: Do we need to distribute probabilities for the conditional? */
      new_e->probability = profile_probability::guessed_never ();
      /* The successor of incr_bb is already pointing to latch_bb; just
	 change the flags.
	 make_edge (incr_bb, latch_bb, EDGE_TRUE_VALUE);  */
      FALLTHRU_EDGE (incr_bb)->flags = EDGE_TRUE_VALUE;
    }

  gphi *phi = create_phi_node (iter1, body_bb);
  edge preheader_edge = find_edge (entry_bb, body_bb);
  edge latch_edge = NULL;
  add_phi_arg (phi, build_zero_cst (unsigned_type_node), preheader_edge,
	       UNKNOWN_LOCATION);
  if (incr_bb)
    {
      latch_edge = single_succ_edge (latch_bb);
      add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);

      /* Generate the new return.  */
      gsi = gsi_last_bb (new_exit_bb);
      if (retval
	  && TREE_CODE (retval) == VIEW_CONVERT_EXPR
	  && TREE_CODE (TREE_OPERAND (retval, 0)) == RESULT_DECL)
	retval = TREE_OPERAND (retval, 0);
      else if (retval)
	{
	  retval = build1 (VIEW_CONVERT_EXPR,
			   TREE_TYPE (TREE_TYPE (node->decl)),
			   retval);
	  retval = force_gimple_operand_gsi (&gsi, retval, true, NULL,
					     false, GSI_CONTINUE_LINKING);
	}
      g = gimple_build_return (retval);
      gsi_insert_after (&gsi, g, GSI_CONTINUE_LINKING);
    }

  /* Handle aligned clauses by replacing default defs of the aligned
     uniform args with __builtin_assume_aligned (arg_N(D), alignment)
     lhs.  Handle linear by adding PHIs.  */
  for (unsigned i = 0; i < node->simdclone->nargs; i++)
    if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
	&& (TREE_ADDRESSABLE (node->simdclone->args[i].orig_arg)
	    || !is_gimple_reg_type
			(TREE_TYPE (node->simdclone->args[i].orig_arg))))
      {
	tree orig_arg = node->simdclone->args[i].orig_arg;
	if (is_gimple_reg_type (TREE_TYPE (orig_arg)))
	  iter1 = make_ssa_name (TREE_TYPE (orig_arg));
	else
	  {
	    iter1 = create_tmp_var_raw (TREE_TYPE (orig_arg));
	    gimple_add_tmp_var (iter1);
	  }
	gsi = gsi_after_labels (entry_bb);
	g = gimple_build_assign (iter1, orig_arg);
	gsi_insert_before (&gsi, g, GSI_NEW_STMT);
	gsi = gsi_after_labels (body_bb);
	g = gimple_build_assign (orig_arg, iter1);
	gsi_insert_before (&gsi, g, GSI_NEW_STMT);
      }
    else if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM
	     && DECL_BY_REFERENCE (node->simdclone->args[i].orig_arg)
	     && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
		== REFERENCE_TYPE
	     && TREE_ADDRESSABLE
		  (TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg))))
      {
	tree orig_arg = node->simdclone->args[i].orig_arg;
	tree def = ssa_default_def (cfun, orig_arg);
	if (def && !has_zero_uses (def))
	  {
	    iter1 = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (orig_arg)));
	    gimple_add_tmp_var (iter1);
	    gsi = gsi_after_labels (entry_bb);
	    g = gimple_build_assign (iter1, build_simple_mem_ref (def));
	    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
	    gsi = gsi_after_labels (body_bb);
	    g = gimple_build_assign (build_simple_mem_ref (def), iter1);
	    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
	  }
      }
    else if (node->simdclone->args[i].alignment
	     && node->simdclone->args[i].arg_type
		== SIMD_CLONE_ARG_TYPE_UNIFORM
	     && (node->simdclone->args[i].alignment
		 & (node->simdclone->args[i].alignment - 1)) == 0
	     && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg))
		== POINTER_TYPE)
      {
	unsigned int alignment = node->simdclone->args[i].alignment;
	tree orig_arg = node->simdclone->args[i].orig_arg;
	tree def = ssa_default_def (cfun, orig_arg);
	if (def && !has_zero_uses (def))
	  {
	    tree fn = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
	    gimple_seq seq = NULL;
	    bool need_cvt = false;
	    gcall *call
	      = gimple_build_call (fn, 2, def, size_int (alignment));
	    g = call;
	    if (!useless_type_conversion_p (TREE_TYPE (orig_arg),
					    ptr_type_node))
	      need_cvt = true;
	    tree t = make_ssa_name (need_cvt ? ptr_type_node : orig_arg);
	    gimple_call_set_lhs (g, t);
	    gimple_seq_add_stmt_without_update (&seq, g);
	    if (need_cvt)
	      {
		t = make_ssa_name (orig_arg);
		g = gimple_build_assign (t, NOP_EXPR, gimple_call_lhs (g));
		gimple_seq_add_stmt_without_update (&seq, g);
	      }
	    gsi_insert_seq_on_edge_immediate
	      (single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun)), seq);

	    entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
	    node->create_edge (cgraph_node::get_create (fn),
			       call, entry_bb->count);

	    imm_use_iterator iter;
	    use_operand_p use_p;
	    gimple *use_stmt;
	    tree repl = gimple_get_lhs (g);
	    FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
	      if (is_gimple_debug (use_stmt) || use_stmt == call)
		continue;
	      else
		FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		  SET_USE (use_p, repl);
	  }
      }
    else if ((node->simdclone->args[i].arg_type
	      == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP)
	     || (node->simdclone->args[i].arg_type
		 == SIMD_CLONE_ARG_TYPE_LINEAR_REF_CONSTANT_STEP)
	     || (node->simdclone->args[i].arg_type
		 == SIMD_CLONE_ARG_TYPE_LINEAR_VARIABLE_STEP)
	     || (node->simdclone->args[i].arg_type
		 == SIMD_CLONE_ARG_TYPE_LINEAR_REF_VARIABLE_STEP))
      {
	tree orig_arg = node->simdclone->args[i].orig_arg;
	gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
		    || POINTER_TYPE_P (TREE_TYPE (orig_arg)));
	tree def = NULL_TREE;
	if (TREE_ADDRESSABLE (orig_arg))
	  {
	    def = make_ssa_name (TREE_TYPE (orig_arg));
	    iter1 = make_ssa_name (TREE_TYPE (orig_arg));
	    if (incr_bb)
	      iter2 = make_ssa_name (TREE_TYPE (orig_arg));
	    gsi = gsi_after_labels (entry_bb);
	    g = gimple_build_assign (def, orig_arg);
	    gsi_insert_before (&gsi, g, GSI_NEW_STMT);
	  }
	else
	  {
	    def = ssa_default_def (cfun, orig_arg);
	    if (!def || has_zero_uses (def))
	      def = NULL_TREE;
	    else
	      {
		iter1 = make_ssa_name (orig_arg);
		if (incr_bb)
		  iter2 = make_ssa_name (orig_arg);
	      }
	  }
	if (def)
	  {
	    phi = create_phi_node (iter1, body_bb);
	    add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION);
	    if (incr_bb)
	      {
		add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
		enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
				      ? PLUS_EXPR : POINTER_PLUS_EXPR;
		tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (orig_arg))
			       ? TREE_TYPE (orig_arg) : sizetype;
		tree addcst = simd_clone_linear_addend (node, i, addtype,
							entry_bb);
		gsi = gsi_last_bb (incr_bb);
		g = gimple_build_assign (iter2, code, iter1, addcst);
		gsi_insert_before (&gsi, g, GSI_SAME_STMT);
	      }

	    imm_use_iterator iter;
	    use_operand_p use_p;
	    gimple *use_stmt;
	    if (TREE_ADDRESSABLE (orig_arg))
	      {
		gsi = gsi_after_labels (body_bb);
		g = gimple_build_assign (orig_arg, iter1);
		gsi_insert_before (&gsi, g, GSI_NEW_STMT);
	      }
	    else
	      FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
		if (use_stmt == phi)
		  continue;
		else
		  FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		    SET_USE (use_p, iter1);
	  }
      }
    else if (node->simdclone->args[i].arg_type
	     == SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_CONSTANT_STEP
	     || (node->simdclone->args[i].arg_type
		 == SIMD_CLONE_ARG_TYPE_LINEAR_UVAL_VARIABLE_STEP))
      {
	tree orig_arg = node->simdclone->args[i].orig_arg;
	tree def = ssa_default_def (cfun, orig_arg);
	gcc_assert (!TREE_ADDRESSABLE (orig_arg)
		    && TREE_CODE (TREE_TYPE (orig_arg)) == REFERENCE_TYPE);
	if (def && !has_zero_uses (def))
	  {
	    tree rtype = TREE_TYPE (TREE_TYPE (orig_arg));
	    iter1 = make_ssa_name (orig_arg);
	    if (incr_bb)
	      iter2 = make_ssa_name (orig_arg);
	    tree iter3 = make_ssa_name (rtype);
	    tree iter4 = make_ssa_name (rtype);
	    tree iter5 = incr_bb ? make_ssa_name (rtype) : NULL_TREE;
	    gsi = gsi_after_labels (entry_bb);
	    gimple *load
	      = gimple_build_assign (iter3, build_simple_mem_ref (def));
	    gsi_insert_before (&gsi, load, GSI_NEW_STMT);

	    tree array = node->simdclone->args[i].simd_array;
	    TREE_ADDRESSABLE (array) = 1;
	    tree ptr = build_fold_addr_expr (array);
	    phi = create_phi_node (iter1, body_bb);
	    add_phi_arg (phi, ptr, preheader_edge, UNKNOWN_LOCATION);
	    if (incr_bb)
	      {
		add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION);
		g = gimple_build_assign (iter2, POINTER_PLUS_EXPR, iter1,
					 TYPE_SIZE_UNIT (TREE_TYPE (iter3)));
		gsi = gsi_last_bb (incr_bb);
		gsi_insert_before (&gsi, g, GSI_SAME_STMT);
	      }

	    phi = create_phi_node (iter4, body_bb);
	    add_phi_arg (phi, iter3, preheader_edge, UNKNOWN_LOCATION);
	    if (incr_bb)
	      {
		add_phi_arg (phi, iter5, latch_edge, UNKNOWN_LOCATION);
		enum tree_code code = INTEGRAL_TYPE_P (TREE_TYPE (iter3))
				      ? PLUS_EXPR : POINTER_PLUS_EXPR;
		tree addtype = INTEGRAL_TYPE_P (TREE_TYPE (iter3))
			       ? TREE_TYPE (iter3) : sizetype;
		tree addcst = simd_clone_linear_addend (node, i, addtype,
							entry_bb);
		g = gimple_build_assign (iter5, code, iter4, addcst);
		gsi = gsi_last_bb (incr_bb);
		gsi_insert_before (&gsi, g, GSI_SAME_STMT);
	      }

	    g = gimple_build_assign (build_simple_mem_ref (iter1), iter4);
	    gsi = gsi_after_labels (body_bb);
	    gsi_insert_before (&gsi, g, GSI_SAME_STMT);

	    imm_use_iterator iter;
	    use_operand_p use_p;
	    gimple *use_stmt;
	    FOR_EACH_IMM_USE_STMT (use_stmt, iter, def)
	      if (use_stmt == load)
		continue;
	      else
		FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
		  SET_USE (use_p, iter1);

	    if (!TYPE_READONLY (rtype) && incr_bb)
	      {
		tree v = make_ssa_name (rtype);
		tree aref = build4 (ARRAY_REF, rtype, array,
				    size_zero_node, NULL_TREE,
				    NULL_TREE);
		gsi = gsi_after_labels (new_exit_bb);
		g = gimple_build_assign (v, aref);
		gsi_insert_before (&gsi, g, GSI_SAME_STMT);
		g = gimple_build_assign (build_simple_mem_ref (def), v);
		gsi_insert_before (&gsi, g, GSI_SAME_STMT);
	      }
	  }
      }

  calculate_dominance_info (CDI_DOMINATORS);
  if (loop)
    add_loop (loop, loop->header->loop_father);
  update_ssa (TODO_update_ssa);

  pop_cfun ();
}

/* If the function in NODE is tagged as an elemental SIMD function,
   create the appropriate SIMD clones.  */

void
expand_simd_clones (struct cgraph_node *node)
{
  tree attr;
  bool explicit_p = true;

  if (node->inlined_to
      || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
    return;

  attr = lookup_attribute ("omp declare simd",
			   DECL_ATTRIBUTES (node->decl));

  /* See if we can add an "omp declare simd" directive implicitly
     before giving up.  */
  /* FIXME: OpenACC "#pragma acc routine" translates into
     "omp declare target", but appears also to have some other effects
     that conflict with generating SIMD clones, causing ICEs.  So don't
     do this if we've got OpenACC instead of OpenMP.  */
  if (attr == NULL_TREE
#ifdef ACCEL_COMPILER
      && (flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_ANY
	  || flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_NOHOST)
#else
      && (flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_ANY
	  || flag_openmp_target_simd_clone == OMP_TARGET_SIMD_CLONE_HOST)
#endif
      && !oacc_get_fn_attrib (node->decl)
      && ok_for_auto_simd_clone (node))
    {
      attr = tree_cons (get_identifier ("omp declare simd"), NULL,
			DECL_ATTRIBUTES (node->decl));
      DECL_ATTRIBUTES (node->decl) = attr;
      explicit_p = false;
    }

  if (attr == NULL_TREE)
    return;

  /* Ignore
     #pragma omp declare simd
     extern int foo ();
     in C, there we don't know the argument types at all.  */
  if (!node->definition
      && TYPE_ARG_TYPES (TREE_TYPE (node->decl)) == NULL_TREE)
    return;

  /* Call this before creating clone_info, as it might ggc_collect.  */
  if (node->definition && node->has_gimple_body_p ())
    node->get_body ();

  do
    {
      /* Start with parsing the "omp declare simd" attribute(s).  */
      bool inbranch_clause_specified;
      struct cgraph_simd_clone *clone_info
	= simd_clone_clauses_extract (node, TREE_VALUE (attr),
				      &inbranch_clause_specified);
      if (clone_info == NULL)
	continue;

      poly_uint64 orig_simdlen = clone_info->simdlen;
      tree base_type = simd_clone_compute_base_data_type (node, clone_info);

      /* The target can return 0 (no simd clones should be created),
	 1 (just one ISA of simd clones should be created) or higher
	 count of ISA variants.  In that case, clone_info is initialized
	 for the first ISA variant.  */
      int count
	= targetm.simd_clone.compute_vecsize_and_simdlen (node, clone_info,
							  base_type, 0,
							  explicit_p);
      if (count == 0)
	continue;

      /* Loop over all COUNT ISA variants, and if !INBRANCH_CLAUSE_SPECIFIED,
	 also create one inbranch and one !inbranch clone of it.  */
      for (int i = 0; i < count * 2; i++)
	{
	  struct cgraph_simd_clone *clone = clone_info;
	  if (inbranch_clause_specified && (i & 1) != 0)
	    continue;

	  if (i != 0)
	    {
	      clone = simd_clone_struct_alloc (clone_info->nargs
					       + ((i & 1) != 0));
	      simd_clone_struct_copy (clone, clone_info);
	      /* Undo changes targetm.simd_clone.compute_vecsize_and_simdlen
		 and simd_clone_adjust_argument_types did to the first
		 clone's info.  */
	      clone->nargs -= clone_info->inbranch;
	      clone->simdlen = orig_simdlen;
	      /* And call the target hook again to get the right ISA.  */
	      targetm.simd_clone.compute_vecsize_and_simdlen (node, clone,
							      base_type,
							      i / 2,
							      explicit_p);
	      if ((i & 1) != 0)
		clone->inbranch = 1;
	    }

	  /* simd_clone_mangle might fail if such a clone has been created
	     already.  */
	  tree id = simd_clone_mangle (node, clone);
	  if (id == NULL_TREE)
	    {
	      if (i == 0)
		clone->nargs += clone->inbranch;
	      continue;
	    }

	  /* Only when we are sure we want to create the clone actually
	     clone the function (or definitions) or create another
	     extern FUNCTION_DECL (for prototypes without definitions).  */
	  struct cgraph_node *n = simd_clone_create (node, !explicit_p);
	  if (n == NULL)
	    {
	      if (i == 0)
		clone->nargs += clone->inbranch;
	      continue;
	    }

	  n->simdclone = clone;
	  clone->origin = node;
	  clone->next_clone = NULL;
	  if (node->simd_clones == NULL)
	    {
	      clone->prev_clone = n;
	      node->simd_clones = n;
	    }
	  else
	    {
	      clone->prev_clone = node->simd_clones->simdclone->prev_clone;
	      clone->prev_clone->simdclone->next_clone = n;
	      node->simd_clones->simdclone->prev_clone = n;
	    }
	  symtab->change_decl_assembler_name (n->decl, id);
	  /* And finally adjust the return type, parameters and for
	     definitions also function body.  */
	  if (node->definition)
	    simd_clone_adjust (n);
	  else
	    {
	      TREE_TYPE (n->decl)
		= build_distinct_type_copy (TREE_TYPE (n->decl));
	      simd_clone_adjust_return_type (n);
	      simd_clone_adjust_argument_types (n);
	      targetm.simd_clone.adjust (n);
	    }
	  if (dump_file)
	    fprintf (dump_file, "\nGenerated %s clone %s\n",
		     (TREE_PUBLIC (n->decl) ? "global" : "local"),
		     IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->decl)));
	}
    }
  while ((attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr))));
}

/* Entry point for IPA simd clone creation pass.  */

static unsigned int
ipa_omp_simd_clone (void)
{
  struct cgraph_node *node;
  FOR_EACH_FUNCTION (node)
    expand_simd_clones (node);
  return 0;
}

namespace {

const pass_data pass_data_omp_simd_clone =
{
  SIMPLE_IPA_PASS,		/* type */
  "simdclone",			/* name */
  OPTGROUP_OMP,			/* optinfo_flags */
  TV_NONE,			/* tv_id */
  ( PROP_ssa | PROP_cfg ),	/* properties_required */
  0,				/* properties_provided */
  0,				/* properties_destroyed */
  0,				/* todo_flags_start */
  0,				/* todo_flags_finish */
};

class pass_omp_simd_clone : public simple_ipa_opt_pass
{
public:
  pass_omp_simd_clone(gcc::context *ctxt)
    : simple_ipa_opt_pass(pass_data_omp_simd_clone, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) final override;
  unsigned int execute (function *) final override
  {
    return ipa_omp_simd_clone ();
  }
};

bool
pass_omp_simd_clone::gate (function *)
{
  return targetm.simd_clone.compute_vecsize_and_simdlen != NULL;
}

} // anon namespace

simple_ipa_opt_pass *
make_pass_omp_simd_clone (gcc::context *ctxt)
{
  return new pass_omp_simd_clone (ctxt);
}
