/* Dependency analysis
   Copyright (C) 2000-2022 Free Software Foundation, Inc.
   Contributed by Paul Brook <paul@nowt.org>

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

/* dependency.cc -- Expression dependency analysis code.  */
/* There's probably quite a bit of duplication in this file.  We currently
   have different dependency checking functions for different types
   if dependencies.  Ideally these would probably be merged.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "gfortran.h"
#include "dependency.h"
#include "constructor.h"
#include "arith.h"
#include "options.h"

/* static declarations */
/* Enums  */
enum range {LHS, RHS, MID};

/* Dependency types.  These must be in reverse order of priority.  */
enum gfc_dependency
{
  GFC_DEP_ERROR,
  GFC_DEP_EQUAL,	/* Identical Ranges.  */
  GFC_DEP_FORWARD,	/* e.g., a(1:3) = a(2:4).  */
  GFC_DEP_BACKWARD,	/* e.g. a(2:4) = a(1:3).  */
  GFC_DEP_OVERLAP,	/* May overlap in some other way.  */
  GFC_DEP_NODEP		/* Distinct ranges.  */
};

/* Macros */
#define IS_ARRAY_EXPLICIT(as) ((as->type == AS_EXPLICIT ? 1 : 0))

/* Forward declarations */

static gfc_dependency check_section_vs_section (gfc_array_ref *,
						gfc_array_ref *, int);

/* Returns 1 if the expr is an integer constant value 1, 0 if it is not or
   def if the value could not be determined.  */

int
gfc_expr_is_one (gfc_expr *expr, int def)
{
  gcc_assert (expr != NULL);

  if (expr->expr_type != EXPR_CONSTANT)
    return def;

  if (expr->ts.type != BT_INTEGER)
    return def;

  return mpz_cmp_si (expr->value.integer, 1) == 0;
}

/* Check if two array references are known to be identical.  Calls
   gfc_dep_compare_expr if necessary for comparing array indices.  */

static bool
identical_array_ref (gfc_array_ref *a1, gfc_array_ref *a2)
{
  int i;

  if (a1->type == AR_FULL && a2->type == AR_FULL)
    return true;

  if (a1->type == AR_SECTION && a2->type == AR_SECTION)
    {
      gcc_assert (a1->dimen == a2->dimen);

      for ( i = 0; i < a1->dimen; i++)
	{
	  /* TODO: Currently, we punt on an integer array as an index.  */
	  if (a1->dimen_type[i] != DIMEN_RANGE
	      || a2->dimen_type[i] != DIMEN_RANGE)
	    return false;

	  if (check_section_vs_section (a1, a2, i) != GFC_DEP_EQUAL)
	    return false;
	}
      return true;
    }

  if (a1->type == AR_ELEMENT && a2->type == AR_ELEMENT)
    {
      if (a1->dimen != a2->dimen)
	gfc_internal_error ("identical_array_ref(): inconsistent dimensions");

      for (i = 0; i < a1->dimen; i++)
	{
	  if (gfc_dep_compare_expr (a1->start[i], a2->start[i]) != 0)
	    return false;
	}
      return true;
    }
  return false;
}



/* Return true for identical variables, checking for references if
   necessary.  Calls identical_array_ref for checking array sections.  */

static bool
are_identical_variables (gfc_expr *e1, gfc_expr *e2)
{
  gfc_ref *r1, *r2;

  if (e1->symtree->n.sym->attr.dummy && e2->symtree->n.sym->attr.dummy)
    {
      /* Dummy arguments: Only check for equal names.  */
      if (e1->symtree->n.sym->name != e2->symtree->n.sym->name)
	return false;
    }
  else
    {
      /* Check for equal symbols.  */
      if (e1->symtree->n.sym != e2->symtree->n.sym)
	return false;
    }

  /* Volatile variables should never compare equal to themselves.  */

  if (e1->symtree->n.sym->attr.volatile_)
    return false;

  r1 = e1->ref;
  r2 = e2->ref;

  while (r1 != NULL || r2 != NULL)
    {

      /* Assume the variables are not equal if one has a reference and the
	 other doesn't.
	 TODO: Handle full references like comparing a(:) to a.
      */

      if (r1 == NULL || r2 == NULL)
	return false;

      if (r1->type != r2->type)
	return false;

      switch (r1->type)
	{

	case REF_ARRAY:
	  if (!identical_array_ref (&r1->u.ar,  &r2->u.ar))
	    return false;

	  break;

	case REF_COMPONENT:
	  if (r1->u.c.component != r2->u.c.component)
	    return false;
	  break;

	case REF_SUBSTRING:
	  if (gfc_dep_compare_expr (r1->u.ss.start, r2->u.ss.start) != 0)
	    return false;

	  /* If both are NULL, the end length compares equal, because we
	     are looking at the same variable. This can only happen for
	     assumed- or deferred-length character arguments.  */

	  if (r1->u.ss.end == NULL && r2->u.ss.end == NULL)
	    break;

	  if (gfc_dep_compare_expr (r1->u.ss.end, r2->u.ss.end) != 0)
	    return false;

	  break;

	case REF_INQUIRY:
	  if (r1->u.i != r2->u.i)
	    return false;
	  break;

	default:
	  gfc_internal_error ("are_identical_variables: Bad type");
	}
      r1 = r1->next;
      r2 = r2->next;
    }
  return true;
}

/* Compare two functions for equality.  Returns 0 if e1==e2, -2 otherwise.  If
   impure_ok is false, only return 0 for pure functions.  */

int
gfc_dep_compare_functions (gfc_expr *e1, gfc_expr *e2, bool impure_ok)
{

  gfc_actual_arglist *args1;
  gfc_actual_arglist *args2;

  if (e1->expr_type != EXPR_FUNCTION || e2->expr_type != EXPR_FUNCTION)
    return -2;

  if ((e1->value.function.esym && e2->value.function.esym
       && e1->value.function.esym == e2->value.function.esym
       && (e1->value.function.esym->result->attr.pure || impure_ok))
       || (e1->value.function.isym && e2->value.function.isym
	   && e1->value.function.isym == e2->value.function.isym
	   && (e1->value.function.isym->pure || impure_ok)))
    {
      args1 = e1->value.function.actual;
      args2 = e2->value.function.actual;

      /* Compare the argument lists for equality.  */
      while (args1 && args2)
	{
	  /*  Bitwise xor, since C has no non-bitwise xor operator.  */
	  if ((args1->expr == NULL) ^ (args2->expr == NULL))
	    return -2;

	  if (args1->expr != NULL && args2->expr != NULL)
	    {
	      gfc_expr *e1, *e2;
	      e1 = args1->expr;
	      e2 = args2->expr;

	      if (gfc_dep_compare_expr (e1, e2) != 0)
		return -2;

	      /* Special case: String arguments which compare equal can have
		 different lengths, which makes them different in calls to
		 procedures.  */

	      if (e1->expr_type == EXPR_CONSTANT
		  && e1->ts.type == BT_CHARACTER
		  && e2->expr_type == EXPR_CONSTANT
		  && e2->ts.type == BT_CHARACTER
		  && e1->value.character.length != e2->value.character.length)
		return -2;
	    }

	  args1 = args1->next;
	  args2 = args2->next;
	}
      return (args1 || args2) ? -2 : 0;
    }
      else
	return -2;
}

/* Helper function to look through parens, unary plus and widening
   integer conversions.  */

gfc_expr *
gfc_discard_nops (gfc_expr *e)
{
  gfc_actual_arglist *arglist;

  if (e == NULL)
    return NULL;

  while (true)
    {
      if (e->expr_type == EXPR_OP
	  && (e->value.op.op == INTRINSIC_UPLUS
	      || e->value.op.op == INTRINSIC_PARENTHESES))
	{
	  e = e->value.op.op1;
	  continue;
	}

      if (e->expr_type == EXPR_FUNCTION && e->value.function.isym
	  && e->value.function.isym->id == GFC_ISYM_CONVERSION
	  && e->ts.type == BT_INTEGER)
	{
	  arglist = e->value.function.actual;
	  if (arglist->expr->ts.type == BT_INTEGER
	      && e->ts.kind > arglist->expr->ts.kind)
	    {
	      e = arglist->expr;
	      continue;
	    }
	}
      break;
    }

  return e;
}


/* Compare two expressions.  Return values:
   * +1 if e1 > e2
   * 0 if e1 == e2
   * -1 if e1 < e2
   * -2 if the relationship could not be determined
   * -3 if e1 /= e2, but we cannot tell which one is larger.
   REAL and COMPLEX constants are only compared for equality
   or inequality; if they are unequal, -2 is returned in all cases.  */

int
gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
{
  int i;

  if (e1 == NULL && e2 == NULL)
    return 0;
  else if (e1 == NULL || e2 == NULL)
    return -2;

  e1 = gfc_discard_nops (e1);
  e2 = gfc_discard_nops (e2);

  if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_PLUS)
    {
      /* Compare X+C vs. X, for INTEGER only.  */
      if (e1->value.op.op2->expr_type == EXPR_CONSTANT
	  && e1->value.op.op2->ts.type == BT_INTEGER
	  && gfc_dep_compare_expr (e1->value.op.op1, e2) == 0)
	return mpz_sgn (e1->value.op.op2->value.integer);

      /* Compare P+Q vs. R+S.  */
      if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
	{
	  int l, r;

	  l = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1);
	  r = gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op2);
	  if (l == 0 && r == 0)
	    return 0;
	  if (l == 0 && r > -2)
	    return r;
	  if (l > -2 && r == 0)
	    return l;
	  if (l == 1 && r == 1)
	    return 1;
	  if (l == -1 && r == -1)
	    return -1;

	  l = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op2);
	  r = gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op1);
	  if (l == 0 && r == 0)
	    return 0;
	  if (l == 0 && r > -2)
	    return r;
	  if (l > -2 && r == 0)
	    return l;
	  if (l == 1 && r == 1)
	    return 1;
	  if (l == -1 && r == -1)
	    return -1;
	}
    }

  /* Compare X vs. X+C, for INTEGER only.  */
  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
    {
      if (e2->value.op.op2->expr_type == EXPR_CONSTANT
	  && e2->value.op.op2->ts.type == BT_INTEGER
	  && gfc_dep_compare_expr (e1, e2->value.op.op1) == 0)
	return -mpz_sgn (e2->value.op.op2->value.integer);
    }

  /* Compare X-C vs. X, for INTEGER only.  */
  if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_MINUS)
    {
      if (e1->value.op.op2->expr_type == EXPR_CONSTANT
	  && e1->value.op.op2->ts.type == BT_INTEGER
	  && gfc_dep_compare_expr (e1->value.op.op1, e2) == 0)
	return -mpz_sgn (e1->value.op.op2->value.integer);

      /* Compare P-Q vs. R-S.  */
      if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
	{
	  int l, r;

	  l = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1);
	  r = gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op2);
	  if (l == 0 && r == 0)
	    return 0;
	  if (l > -2 && r == 0)
	    return l;
	  if (l == 0 && r > -2)
	    return -r;
	  if (l == 1 && r == -1)
	    return 1;
	  if (l == -1 && r == 1)
	    return -1;
	}
    }

  /* Compare A // B vs. C // D.  */

  if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_CONCAT
      && e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_CONCAT)
    {
      int l, r;

      l = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1);
      r = gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op2);

      if (l != 0)
	return l;

      /* Left expressions of // compare equal, but
	 watch out for 'A ' // x vs. 'A' // x.  */
      gfc_expr *e1_left = e1->value.op.op1;
      gfc_expr *e2_left = e2->value.op.op1;

      if (e1_left->expr_type == EXPR_CONSTANT
	  && e2_left->expr_type == EXPR_CONSTANT
	  && e1_left->value.character.length
	  != e2_left->value.character.length)
	return -2;
      else
	return r;
    }

  /* Compare X vs. X-C, for INTEGER only.  */
  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
    {
      if (e2->value.op.op2->expr_type == EXPR_CONSTANT
	  && e2->value.op.op2->ts.type == BT_INTEGER
	  && gfc_dep_compare_expr (e1, e2->value.op.op1) == 0)
	return mpz_sgn (e2->value.op.op2->value.integer);
    }

  if (e1->expr_type != e2->expr_type)
    return -3;

  switch (e1->expr_type)
    {
    case EXPR_CONSTANT:
      /* Compare strings for equality.  */
      if (e1->ts.type == BT_CHARACTER && e2->ts.type == BT_CHARACTER)
	return gfc_compare_string (e1, e2);

      /* Compare REAL and COMPLEX constants.  Because of the
	 traps and pitfalls associated with comparing
	 a + 1.0 with a + 0.5, check for equality only.  */
      if (e2->expr_type == EXPR_CONSTANT)
	{
	  if (e1->ts.type == BT_REAL && e2->ts.type == BT_REAL)
	    {
	      if (mpfr_cmp (e1->value.real, e2->value.real) == 0)
		return 0;
	      else
		return -2;
	    }
	  else if (e1->ts.type == BT_COMPLEX && e2->ts.type == BT_COMPLEX)
	    {
	      if (mpc_cmp (e1->value.complex, e2->value.complex) == 0)
		return 0;
	      else
		return -2;
	    }
	}

      if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
	return -2;

      /* For INTEGER, all cases where e2 is not constant should have
	 been filtered out above.  */
      gcc_assert (e2->expr_type == EXPR_CONSTANT);

      i = mpz_cmp (e1->value.integer, e2->value.integer);
      if (i == 0)
	return 0;
      else if (i < 0)
	return -1;
      return 1;

    case EXPR_VARIABLE:
      if (are_identical_variables (e1, e2))
	return 0;
      else
	return -3;

    case EXPR_OP:
      /* Intrinsic operators are the same if their operands are the same.  */
      if (e1->value.op.op != e2->value.op.op)
	return -2;
      if (e1->value.op.op2 == 0)
	{
	  i = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1);
	  return i == 0 ? 0 : -2;
	}
      if (gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1) == 0
	  && gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op2) == 0)
	return 0;
      else if (e1->value.op.op == INTRINSIC_TIMES
	       && gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op2) == 0
	       && gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op1) == 0)
	/* Commutativity of multiplication; addition is handled above.  */
	return 0;

      return -2;

    case EXPR_FUNCTION:
      return gfc_dep_compare_functions (e1, e2, false);

    default:
      return -2;
    }
}


/* Return the difference between two expressions.  Integer expressions of
   the form

   X + constant, X - constant and constant + X

   are handled.  Return true on success, false on failure. result is assumed
   to be uninitialized on entry, and will be initialized on success.
*/

bool
gfc_dep_difference (gfc_expr *e1, gfc_expr *e2, mpz_t *result)
{
  gfc_expr *e1_op1, *e1_op2, *e2_op1, *e2_op2;

  if (e1 == NULL || e2 == NULL)
    return false;

  if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
    return false;

  e1 = gfc_discard_nops (e1);
  e2 = gfc_discard_nops (e2);

  /* Inizialize tentatively, clear if we don't return anything.  */
  mpz_init (*result);

  /* Case 1: c1 - c2 = c1 - c2, trivially.  */

  if (e1->expr_type == EXPR_CONSTANT && e2->expr_type == EXPR_CONSTANT)
    {
      mpz_sub (*result, e1->value.integer, e2->value.integer);
      return true;
    }

  if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_PLUS)
    {
      e1_op1 = gfc_discard_nops (e1->value.op.op1);
      e1_op2 = gfc_discard_nops (e1->value.op.op2);

      /* Case 2: (X + c1) - X = c1.  */
      if (e1_op2->expr_type == EXPR_CONSTANT
	  && gfc_dep_compare_expr (e1_op1, e2) == 0)
	{
	  mpz_set (*result, e1_op2->value.integer);
	  return true;
	}

      /* Case 3: (c1 + X) - X = c1.  */
      if (e1_op1->expr_type == EXPR_CONSTANT
	  && gfc_dep_compare_expr (e1_op2, e2) == 0)
	{
	  mpz_set (*result, e1_op1->value.integer);
	  return true;
	}

      if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
	{
	  e2_op1 = gfc_discard_nops (e2->value.op.op1);
	  e2_op2 = gfc_discard_nops (e2->value.op.op2);

	  if (e1_op2->expr_type == EXPR_CONSTANT)
	    {
	      /* Case 4: X + c1 - (X + c2) = c1 - c2.  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op1) == 0)
		{
		  mpz_sub (*result, e1_op2->value.integer,
			   e2_op2->value.integer);
		  return true;
		}
	      /* Case 5: X + c1 - (c2 + X) = c1 - c2.  */
	      if (e2_op1->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op2) == 0)
		{
		  mpz_sub (*result, e1_op2->value.integer,
			   e2_op1->value.integer);
		  return true;
		}
	    }
	  else if (e1_op1->expr_type == EXPR_CONSTANT)
	    {
	      /* Case 6: c1 + X - (X + c2) = c1 - c2.  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op2, e2_op1) == 0)
		{
		  mpz_sub (*result, e1_op1->value.integer,
			   e2_op2->value.integer);
		  return true;
		}
	      /* Case 7: c1 + X - (c2 + X) = c1 - c2.  */
	      if (e2_op1->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op2, e2_op2) == 0)
		{
		  mpz_sub (*result, e1_op1->value.integer,
			   e2_op1->value.integer);
		  return true;
		}
	    }
	}

      if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
	{
	  e2_op1 = gfc_discard_nops (e2->value.op.op1);
	  e2_op2 = gfc_discard_nops (e2->value.op.op2);

	  if (e1_op2->expr_type == EXPR_CONSTANT)
	    {
	      /* Case 8: X + c1 - (X - c2) = c1 + c2.  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op1) == 0)
		{
		  mpz_add (*result, e1_op2->value.integer,
			   e2_op2->value.integer);
		  return true;
		}
	    }
	  if (e1_op1->expr_type == EXPR_CONSTANT)
	    {
	      /* Case 9: c1 + X - (X - c2) = c1 + c2.  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op2, e2_op1) == 0)
		{
		  mpz_add (*result, e1_op1->value.integer,
			   e2_op2->value.integer);
		  return true;
		}
	    }
	}
    }

  if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_MINUS)
    {
      e1_op1 = gfc_discard_nops (e1->value.op.op1);
      e1_op2 = gfc_discard_nops (e1->value.op.op2);

      if (e1_op2->expr_type == EXPR_CONSTANT)
	{
	  /* Case 10: (X - c1) - X = -c1  */

	  if (gfc_dep_compare_expr (e1_op1, e2) == 0)
	    {
	      mpz_neg (*result, e1_op2->value.integer);
	      return true;
	    }

	  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
	    {
	      e2_op1 = gfc_discard_nops (e2->value.op.op1);
	      e2_op2 = gfc_discard_nops (e2->value.op.op2);

	      /* Case 11: (X - c1) - (X + c2) = -( c1 + c2).  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op1) == 0)
		{
		  mpz_add (*result, e1_op2->value.integer,
			   e2_op2->value.integer);
		  mpz_neg (*result, *result);
		  return true;
		}

	      /* Case 12: X - c1 - (c2 + X) = - (c1 + c2).  */
	      if (e2_op1->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op2) == 0)
		{
		  mpz_add (*result, e1_op2->value.integer,
			   e2_op1->value.integer);
		  mpz_neg (*result, *result);
		  return true;
		}
	    }

	  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
	    {
	      e2_op1 = gfc_discard_nops (e2->value.op.op1);
	      e2_op2 = gfc_discard_nops (e2->value.op.op2);

	      /* Case 13: (X - c1) - (X - c2) = c2 - c1.  */
	      if (e2_op2->expr_type == EXPR_CONSTANT
		  && gfc_dep_compare_expr (e1_op1, e2_op1) == 0)
		{
		  mpz_sub (*result, e2_op2->value.integer,
			   e1_op2->value.integer);
		  return true;
		}
	    }
	}
      if (e1_op1->expr_type == EXPR_CONSTANT)
	{
	  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
	    {
	      e2_op1 = gfc_discard_nops (e2->value.op.op1);
	      e2_op2 = gfc_discard_nops (e2->value.op.op2);

	      /* Case 14: (c1 - X) - (c2 - X) == c1 - c2.  */
	      if (gfc_dep_compare_expr (e1_op2, e2_op2) == 0)
		{
		  mpz_sub (*result, e1_op1->value.integer,
			   e2_op1->value.integer);
		    return true;
		}
	    }

	}
    }

  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_PLUS)
    {
      e2_op1 = gfc_discard_nops (e2->value.op.op1);
      e2_op2 = gfc_discard_nops (e2->value.op.op2);

      /* Case 15: X - (X + c2) = -c2.  */
      if (e2_op2->expr_type == EXPR_CONSTANT
	  && gfc_dep_compare_expr (e1, e2_op1) == 0)
	{
	  mpz_neg (*result, e2_op2->value.integer);
	  return true;
	}
      /* Case 16: X - (c2 + X) = -c2.  */
      if (e2_op1->expr_type == EXPR_CONSTANT
	  && gfc_dep_compare_expr (e1, e2_op2) == 0)
	{
	  mpz_neg (*result, e2_op1->value.integer);
	  return true;
	}
    }

  if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
    {
      e2_op1 = gfc_discard_nops (e2->value.op.op1);
      e2_op2 = gfc_discard_nops (e2->value.op.op2);

      /* Case 17: X - (X - c2) = c2.  */
      if (e2_op2->expr_type == EXPR_CONSTANT
	  && gfc_dep_compare_expr (e1, e2_op1) == 0)
	{
	  mpz_set (*result, e2_op2->value.integer);
	  return true;
	}
    }

  if (gfc_dep_compare_expr (e1, e2) == 0)
    {
      /* Case 18: X - X = 0.  */
      mpz_set_si (*result, 0);
      return true;
    }

  mpz_clear (*result);
  return false;
}

/* Returns 1 if the two ranges are the same and 0 if they are not (or if the
   results are indeterminate). 'n' is the dimension to compare.  */

static int
is_same_range (gfc_array_ref *ar1, gfc_array_ref *ar2, int n)
{
  gfc_expr *e1;
  gfc_expr *e2;
  int i;

  /* TODO: More sophisticated range comparison.  */
  gcc_assert (ar1 && ar2);

  gcc_assert (ar1->dimen_type[n] == ar2->dimen_type[n]);

  e1 = ar1->stride[n];
  e2 = ar2->stride[n];
  /* Check for mismatching strides.  A NULL stride means a stride of 1.  */
  if (e1 && !e2)
    {
      i = gfc_expr_is_one (e1, -1);
      if (i == -1 || i == 0)
	return 0;
    }
  else if (e2 && !e1)
    {
      i = gfc_expr_is_one (e2, -1);
      if (i == -1 || i == 0)
	return 0;
    }
  else if (e1 && e2)
    {
      i = gfc_dep_compare_expr (e1, e2);
      if (i != 0)
	return 0;
    }
  /* The strides match.  */

  /* Check the range start.  */
  e1 = ar1->start[n];
  e2 = ar2->start[n];
  if (e1 || e2)
    {
      /* Use the bound of the array if no bound is specified.  */
      if (ar1->as && !e1)
	e1 = ar1->as->lower[n];

      if (ar2->as && !e2)
	e2 = ar2->as->lower[n];

      /* Check we have values for both.  */
      if (!(e1 && e2))
	return 0;

      i = gfc_dep_compare_expr (e1, e2);
      if (i != 0)
	return 0;
    }

  /* Check the range end.  */
  e1 = ar1->end[n];
  e2 = ar2->end[n];
  if (e1 || e2)
    {
      /* Use the bound of the array if no bound is specified.  */
      if (ar1->as && !e1)
	e1 = ar1->as->upper[n];

      if (ar2->as && !e2)
	e2 = ar2->as->upper[n];

      /* Check we have values for both.  */
      if (!(e1 && e2))
	return 0;

      i = gfc_dep_compare_expr (e1, e2);
      if (i != 0)
	return 0;
    }

  return 1;
}


/* Some array-returning intrinsics can be implemented by reusing the
   data from one of the array arguments.  For example, TRANSPOSE does
   not necessarily need to allocate new data: it can be implemented
   by copying the original array's descriptor and simply swapping the
   two dimension specifications.

   If EXPR is a call to such an intrinsic, return the argument
   whose data can be reused, otherwise return NULL.  */

gfc_expr *
gfc_get_noncopying_intrinsic_argument (gfc_expr *expr)
{
  if (expr->expr_type != EXPR_FUNCTION || !expr->value.function.isym)
    return NULL;

  switch (expr->value.function.isym->id)
    {
    case GFC_ISYM_TRANSPOSE:
      return expr->value.function.actual->expr;

    default:
      return NULL;
    }
}


/* Return true if the result of reference REF can only be constructed
   using a temporary array.  */

bool
gfc_ref_needs_temporary_p (gfc_ref *ref)
{
  int n;
  bool subarray_p;

  subarray_p = false;
  for (; ref; ref = ref->next)
    switch (ref->type)
      {
      case REF_ARRAY:
	/* Vector dimensions are generally not monotonic and must be
	   handled using a temporary.  */
	if (ref->u.ar.type == AR_SECTION)
	  for (n = 0; n < ref->u.ar.dimen; n++)
	    if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
	      return true;

	subarray_p = true;
	break;

      case REF_SUBSTRING:
	/* Within an array reference, character substrings generally
	   need a temporary.  Character array strides are expressed as
	   multiples of the element size (consistent with other array
	   types), not in characters.  */
	return subarray_p;

      case REF_COMPONENT:
      case REF_INQUIRY:
	break;
      }

  return false;
}


static int
gfc_is_data_pointer (gfc_expr *e)
{
  gfc_ref *ref;

  if (e->expr_type != EXPR_VARIABLE && e->expr_type != EXPR_FUNCTION)
    return 0;

  /* No subreference if it is a function  */
  gcc_assert (e->expr_type == EXPR_VARIABLE || !e->ref);

  if (e->symtree->n.sym->attr.pointer)
    return 1;

  for (ref = e->ref; ref; ref = ref->next)
    if (ref->type == REF_COMPONENT && ref->u.c.component->attr.pointer)
      return 1;

  return 0;
}


/* Return true if array variable VAR could be passed to the same function
   as argument EXPR without interfering with EXPR.  INTENT is the intent
   of VAR.

   This is considerably less conservative than other dependencies
   because many function arguments will already be copied into a
   temporary.  */

static int
gfc_check_argument_var_dependency (gfc_expr *var, sym_intent intent,
				   gfc_expr *expr, gfc_dep_check elemental)
{
  gfc_expr *arg;

  gcc_assert (var->expr_type == EXPR_VARIABLE);
  gcc_assert (var->rank > 0);

  switch (expr->expr_type)
    {
    case EXPR_VARIABLE:
      /* In case of elemental subroutines, there is no dependency
         between two same-range array references.  */
      if (gfc_ref_needs_temporary_p (expr->ref)
	  || gfc_check_dependency (var, expr, elemental == NOT_ELEMENTAL))
	{
	  if (elemental == ELEM_DONT_CHECK_VARIABLE)
	    {
	      /* Too many false positive with pointers.  */
	      if (!gfc_is_data_pointer (var) && !gfc_is_data_pointer (expr))
		{
		  /* Elemental procedures forbid unspecified intents,
		     and we don't check dependencies for INTENT_IN args.  */
		  gcc_assert (intent == INTENT_OUT || intent == INTENT_INOUT);

		  /* We are told not to check dependencies.
		     We do it, however, and issue a warning in case we find one.
		     If a dependency is found in the case
		     elemental == ELEM_CHECK_VARIABLE, we will generate
		     a temporary, so we don't need to bother the user.  */

		  if (var->expr_type == EXPR_VARIABLE
		      && expr->expr_type == EXPR_VARIABLE
		      && strcmp(var->symtree->name, expr->symtree->name) == 0)
		    gfc_warning (0, "INTENT(%s) actual argument at %L might "
				 "interfere with actual argument at %L.",
				 intent == INTENT_OUT ? "OUT" : "INOUT",
				 &var->where, &expr->where);
		}
	      return 0;
	    }
	  else
	    return 1;
	}
      return 0;

    case EXPR_ARRAY:
      /* the scalarizer always generates a temporary for array constructors,
	 so there is no dependency.  */
      return 0;

    case EXPR_FUNCTION:
      if (intent != INTENT_IN)
	{
	  arg = gfc_get_noncopying_intrinsic_argument (expr);
	  if (arg != NULL)
	    return gfc_check_argument_var_dependency (var, intent, arg,
						      NOT_ELEMENTAL);
	}

      if (elemental != NOT_ELEMENTAL)
	{
	  if ((expr->value.function.esym
	       && expr->value.function.esym->attr.elemental)
	      || (expr->value.function.isym
		  && expr->value.function.isym->elemental))
	    return gfc_check_fncall_dependency (var, intent, NULL,
						expr->value.function.actual,
						ELEM_CHECK_VARIABLE);

	  if (gfc_inline_intrinsic_function_p (expr))
	    {
	      /* The TRANSPOSE case should have been caught in the
		 noncopying intrinsic case above.  */
	      gcc_assert (expr->value.function.isym->id != GFC_ISYM_TRANSPOSE);

	      return gfc_check_fncall_dependency (var, intent, NULL,
						  expr->value.function.actual,
						  ELEM_CHECK_VARIABLE);
	    }
	}
      return 0;

    case EXPR_OP:
      /* In case of non-elemental procedures, there is no need to catch
	 dependencies, as we will make a temporary anyway.  */
      if (elemental)
	{
	  /* If the actual arg EXPR is an expression, we need to catch
	     a dependency between variables in EXPR and VAR,
	     an intent((IN)OUT) variable.  */
	  if (expr->value.op.op1
	      && gfc_check_argument_var_dependency (var, intent,
						    expr->value.op.op1,
						    ELEM_CHECK_VARIABLE))
	    return 1;
	  else if (expr->value.op.op2
		   && gfc_check_argument_var_dependency (var, intent,
							 expr->value.op.op2,
							 ELEM_CHECK_VARIABLE))
	    return 1;
	}
      return 0;

    default:
      return 0;
    }
}


/* Like gfc_check_argument_var_dependency, but extended to any
   array expression OTHER, not just variables.  */

static int
gfc_check_argument_dependency (gfc_expr *other, sym_intent intent,
			       gfc_expr *expr, gfc_dep_check elemental)
{
  switch (other->expr_type)
    {
    case EXPR_VARIABLE:
      return gfc_check_argument_var_dependency (other, intent, expr, elemental);

    case EXPR_FUNCTION:
      other = gfc_get_noncopying_intrinsic_argument (other);
      if (other != NULL)
	return gfc_check_argument_dependency (other, INTENT_IN, expr,
					      NOT_ELEMENTAL);

      return 0;

    default:
      return 0;
    }
}


/* Like gfc_check_argument_dependency, but check all the arguments in ACTUAL.
   FNSYM is the function being called, or NULL if not known.  */

int
gfc_check_fncall_dependency (gfc_expr *other, sym_intent intent,
			     gfc_symbol *fnsym, gfc_actual_arglist *actual,
			     gfc_dep_check elemental)
{
  gfc_formal_arglist *formal;
  gfc_expr *expr;

  formal = fnsym ? gfc_sym_get_dummy_args (fnsym) : NULL;
  for (; actual; actual = actual->next, formal = formal ? formal->next : NULL)
    {
      expr = actual->expr;

      /* Skip args which are not present.  */
      if (!expr)
	continue;

      /* Skip other itself.  */
      if (expr == other)
	continue;

      /* Skip intent(in) arguments if OTHER itself is intent(in).  */
      if (formal && intent == INTENT_IN
	  && formal->sym->attr.intent == INTENT_IN)
	continue;

      if (gfc_check_argument_dependency (other, intent, expr, elemental))
	return 1;
    }

  return 0;
}


/* Return 1 if e1 and e2 are equivalenced arrays, either
   directly or indirectly; i.e., equivalence (a,b) for a and b
   or equivalence (a,c),(b,c).  This function uses the equiv_
   lists, generated in trans-common(add_equivalences), that are
   guaranteed to pick up indirect equivalences.  We explicitly
   check for overlap using the offset and length of the equivalence.
   This function is symmetric.
   TODO: This function only checks whether the full top-level
   symbols overlap.  An improved implementation could inspect
   e1->ref and e2->ref to determine whether the actually accessed
   portions of these variables/arrays potentially overlap.  */

int
gfc_are_equivalenced_arrays (gfc_expr *e1, gfc_expr *e2)
{
  gfc_equiv_list *l;
  gfc_equiv_info *s, *fl1, *fl2;

  gcc_assert (e1->expr_type == EXPR_VARIABLE
	      && e2->expr_type == EXPR_VARIABLE);

  if (!e1->symtree->n.sym->attr.in_equivalence
      || !e2->symtree->n.sym->attr.in_equivalence|| !e1->rank || !e2->rank)
    return 0;

  if (e1->symtree->n.sym->ns
	&& e1->symtree->n.sym->ns != gfc_current_ns)
    l = e1->symtree->n.sym->ns->equiv_lists;
  else
    l = gfc_current_ns->equiv_lists;

  /* Go through the equiv_lists and return 1 if the variables
     e1 and e2 are members of the same group and satisfy the
     requirement on their relative offsets.  */
  for (; l; l = l->next)
    {
      fl1 = NULL;
      fl2 = NULL;
      for (s = l->equiv; s; s = s->next)
	{
	  if (s->sym == e1->symtree->n.sym)
	    {
	      fl1 = s;
	      if (fl2)
		break;
	    }
	  if (s->sym == e2->symtree->n.sym)
	    {
	      fl2 = s;
	      if (fl1)
		break;
	    }
	}

      if (s)
	{
	  /* Can these lengths be zero?  */
	  if (fl1->length <= 0 || fl2->length <= 0)
	    return 1;
	  /* These can't overlap if [f11,fl1+length] is before
	     [fl2,fl2+length], or [fl2,fl2+length] is before
	     [fl1,fl1+length], otherwise they do overlap.  */
	  if (fl1->offset + fl1->length > fl2->offset
	      && fl2->offset + fl2->length > fl1->offset)
	    return 1;
	}
    }
  return 0;
}


/* Return true if there is no possibility of aliasing because of a type
   mismatch between all the possible pointer references and the
   potential target.  Note that this function is asymmetric in the
   arguments and so must be called twice with the arguments exchanged.  */

static bool
check_data_pointer_types (gfc_expr *expr1, gfc_expr *expr2)
{
  gfc_component *cm1;
  gfc_symbol *sym1;
  gfc_symbol *sym2;
  gfc_ref *ref1;
  bool seen_component_ref;

  if (expr1->expr_type != EXPR_VARIABLE
	|| expr2->expr_type != EXPR_VARIABLE)
    return false;

  sym1 = expr1->symtree->n.sym;
  sym2 = expr2->symtree->n.sym;

  /* Keep it simple for now.  */
  if (sym1->ts.type == BT_DERIVED && sym2->ts.type == BT_DERIVED)
    return false;

  if (sym1->attr.pointer)
    {
      if (gfc_compare_types (&sym1->ts, &sym2->ts))
	return false;
    }

  /* This is a conservative check on the components of the derived type
     if no component references have been seen.  Since we will not dig
     into the components of derived type components, we play it safe by
     returning false.  First we check the reference chain and then, if
     no component references have been seen, the components.  */
  seen_component_ref = false;
  if (sym1->ts.type == BT_DERIVED)
    {
      for (ref1 = expr1->ref; ref1; ref1 = ref1->next)
	{
	  if (ref1->type != REF_COMPONENT)
	    continue;

	  if (ref1->u.c.component->ts.type == BT_DERIVED)
	    return false;

	  if ((sym2->attr.pointer || ref1->u.c.component->attr.pointer)
		&& gfc_compare_types (&ref1->u.c.component->ts, &sym2->ts))
	    return false;

	  seen_component_ref = true;
	}
    }

  if (sym1->ts.type == BT_DERIVED && !seen_component_ref)
    {
      for (cm1 = sym1->ts.u.derived->components; cm1; cm1 = cm1->next)
	{
	  if (cm1->ts.type == BT_DERIVED)
	    return false;

	  if ((sym2->attr.pointer || cm1->attr.pointer)
		&& gfc_compare_types (&cm1->ts, &sym2->ts))
	    return false;
	}
    }

  return true;
}


/* Return true if the statement body redefines the condition.  Returns
   true if expr2 depends on expr1.  expr1 should be a single term
   suitable for the lhs of an assignment.  The IDENTICAL flag indicates
   whether array references to the same symbol with identical range
   references count as a dependency or not.  Used for forall and where
   statements.  Also used with functions returning arrays without a
   temporary.  */

int
gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
{
  gfc_actual_arglist *actual;
  gfc_constructor *c;
  int n;

  /* -fcoarray=lib can end up here with expr1->expr_type set to EXPR_FUNCTION
     and a reference to _F.caf_get, so skip the assert.  */
  if (expr1->expr_type == EXPR_FUNCTION
      && strcmp (expr1->value.function.name, "_F.caf_get") == 0)
    return 0;

  if (expr1->expr_type != EXPR_VARIABLE)
    gfc_internal_error ("gfc_check_dependency: expecting an EXPR_VARIABLE");

  switch (expr2->expr_type)
    {
    case EXPR_OP:
      n = gfc_check_dependency (expr1, expr2->value.op.op1, identical);
      if (n)
	return n;
      if (expr2->value.op.op2)
	return gfc_check_dependency (expr1, expr2->value.op.op2, identical);
      return 0;

    case EXPR_VARIABLE:
      /* The interesting cases are when the symbols don't match.  */
      if (expr1->symtree->n.sym != expr2->symtree->n.sym)
	{
	  symbol_attribute attr1, attr2;
	  gfc_typespec *ts1 = &expr1->symtree->n.sym->ts;
	  gfc_typespec *ts2 = &expr2->symtree->n.sym->ts;

	  /* Return 1 if expr1 and expr2 are equivalenced arrays.  */
	  if (gfc_are_equivalenced_arrays (expr1, expr2))
	    return 1;

	  /* Symbols can only alias if they have the same type.  */
	  if (ts1->type != BT_UNKNOWN && ts2->type != BT_UNKNOWN
	      && ts1->type != BT_DERIVED && ts2->type != BT_DERIVED)
	    {
	      if (ts1->type != ts2->type || ts1->kind != ts2->kind)
		return 0;
	    }

	  /* We have to also include target-target as ptr%comp is not a
	     pointer but it still alias with "dt%comp" for "ptr => dt".  As
	     subcomponents and array access to pointers retains the target
	     attribute, that's sufficient.  */
	  attr1 = gfc_expr_attr (expr1);
	  attr2 = gfc_expr_attr (expr2);
	  if ((attr1.pointer || attr1.target) && (attr2.pointer || attr2.target))
	    {
	      if (check_data_pointer_types (expr1, expr2)
		    && check_data_pointer_types (expr2, expr1))
		return 0;

	      return 1;
	    }
	  else
	    {
	      gfc_symbol *sym1 = expr1->symtree->n.sym;
	      gfc_symbol *sym2 = expr2->symtree->n.sym;
	      if (sym1->attr.target && sym2->attr.target
		  && ((sym1->attr.dummy && !sym1->attr.contiguous
		       && (!sym1->attr.dimension
		           || sym2->as->type == AS_ASSUMED_SHAPE))
		      || (sym2->attr.dummy && !sym2->attr.contiguous
			  && (!sym2->attr.dimension
			      || sym2->as->type == AS_ASSUMED_SHAPE))))
		return 1;
	    }

	  /* Otherwise distinct symbols have no dependencies.  */
	  return 0;
	}

      /* Identical and disjoint ranges return 0,
	 overlapping ranges return 1.  */
      if (expr1->ref && expr2->ref)
	return gfc_dep_resolver (expr1->ref, expr2->ref, NULL, identical);

      return 1;

    case EXPR_FUNCTION:
      if (gfc_get_noncopying_intrinsic_argument (expr2) != NULL)
	identical = 1;

      /* Remember possible differences between elemental and
	 transformational functions.  All functions inside a FORALL
	 will be pure.  */
      for (actual = expr2->value.function.actual;
	   actual; actual = actual->next)
	{
	  if (!actual->expr)
	    continue;
	  n = gfc_check_dependency (expr1, actual->expr, identical);
	  if (n)
	    return n;
	}
      return 0;

    case EXPR_CONSTANT:
    case EXPR_NULL:
      return 0;

    case EXPR_ARRAY:
      /* Loop through the array constructor's elements.  */
      for (c = gfc_constructor_first (expr2->value.constructor);
	   c; c = gfc_constructor_next (c))
	{
	  /* If this is an iterator, assume the worst.  */
	  if (c->iterator)
	    return 1;
	  /* Avoid recursion in the common case.  */
	  if (c->expr->expr_type == EXPR_CONSTANT)
	    continue;
	  if (gfc_check_dependency (expr1, c->expr, 1))
	    return 1;
	}
      return 0;

    default:
      return 1;
    }
}


/* Determines overlapping for two array sections.  */

static gfc_dependency
check_section_vs_section (gfc_array_ref *l_ar, gfc_array_ref *r_ar, int n)
{
  gfc_expr *l_start;
  gfc_expr *l_end;
  gfc_expr *l_stride;
  gfc_expr *l_lower;
  gfc_expr *l_upper;
  int l_dir;

  gfc_expr *r_start;
  gfc_expr *r_end;
  gfc_expr *r_stride;
  gfc_expr *r_lower;
  gfc_expr *r_upper;
  gfc_expr *one_expr;
  int r_dir;
  int stride_comparison;
  int start_comparison;
  mpz_t tmp;

  /* If they are the same range, return without more ado.  */
  if (is_same_range (l_ar, r_ar, n))
    return GFC_DEP_EQUAL;

  l_start = l_ar->start[n];
  l_end = l_ar->end[n];
  l_stride = l_ar->stride[n];

  r_start = r_ar->start[n];
  r_end = r_ar->end[n];
  r_stride = r_ar->stride[n];

  /* If l_start is NULL take it from array specifier.  */
  if (l_start == NULL && IS_ARRAY_EXPLICIT (l_ar->as))
    l_start = l_ar->as->lower[n];
  /* If l_end is NULL take it from array specifier.  */
  if (l_end == NULL && IS_ARRAY_EXPLICIT (l_ar->as))
    l_end = l_ar->as->upper[n];

  /* If r_start is NULL take it from array specifier.  */
  if (r_start == NULL && IS_ARRAY_EXPLICIT (r_ar->as))
    r_start = r_ar->as->lower[n];
  /* If r_end is NULL take it from array specifier.  */
  if (r_end == NULL && IS_ARRAY_EXPLICIT (r_ar->as))
    r_end = r_ar->as->upper[n];

  /* Determine whether the l_stride is positive or negative.  */
  if (!l_stride)
    l_dir = 1;
  else if (l_stride->expr_type == EXPR_CONSTANT
	   && l_stride->ts.type == BT_INTEGER)
    l_dir = mpz_sgn (l_stride->value.integer);
  else if (l_start && l_end)
    l_dir = gfc_dep_compare_expr (l_end, l_start);
  else
    l_dir = -2;

  /* Determine whether the r_stride is positive or negative.  */
  if (!r_stride)
    r_dir = 1;
  else if (r_stride->expr_type == EXPR_CONSTANT
	   && r_stride->ts.type == BT_INTEGER)
    r_dir = mpz_sgn (r_stride->value.integer);
  else if (r_start && r_end)
    r_dir = gfc_dep_compare_expr (r_end, r_start);
  else
    r_dir = -2;

  /* The strides should never be zero.  */
  if (l_dir == 0 || r_dir == 0)
    return GFC_DEP_OVERLAP;

  /* Determine the relationship between the strides.  Set stride_comparison to
     -2 if the dependency cannot be determined
     -1 if l_stride < r_stride
      0 if l_stride == r_stride
      1 if l_stride > r_stride
     as determined by gfc_dep_compare_expr.  */

  one_expr = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);

  stride_comparison = gfc_dep_compare_expr (l_stride ? l_stride : one_expr,
					    r_stride ? r_stride : one_expr);

  if (l_start && r_start)
    start_comparison = gfc_dep_compare_expr (l_start, r_start);
  else
    start_comparison = -2;

  gfc_free_expr (one_expr);

  /* Determine LHS upper and lower bounds.  */
  if (l_dir == 1)
    {
      l_lower = l_start;
      l_upper = l_end;
    }
  else if (l_dir == -1)
    {
      l_lower = l_end;
      l_upper = l_start;
    }
  else
    {
      l_lower = NULL;
      l_upper = NULL;
    }

  /* Determine RHS upper and lower bounds.  */
  if (r_dir == 1)
    {
      r_lower = r_start;
      r_upper = r_end;
    }
  else if (r_dir == -1)
    {
      r_lower = r_end;
      r_upper = r_start;
    }
  else
    {
      r_lower = NULL;
      r_upper = NULL;
    }

  /* Check whether the ranges are disjoint.  */
  if (l_upper && r_lower && gfc_dep_compare_expr (l_upper, r_lower) == -1)
    return GFC_DEP_NODEP;
  if (r_upper && l_lower && gfc_dep_compare_expr (r_upper, l_lower) == -1)
    return GFC_DEP_NODEP;

  /* Handle cases like x:y:1 vs. x:z:-1 as GFC_DEP_EQUAL.  */
  if (l_start && r_start && gfc_dep_compare_expr (l_start, r_start) == 0)
    {
      if (l_dir == 1 && r_dir == -1)
	return GFC_DEP_EQUAL;
      if (l_dir == -1 && r_dir == 1)
	return GFC_DEP_EQUAL;
    }

  /* Handle cases like x:y:1 vs. z:y:-1 as GFC_DEP_EQUAL.  */
  if (l_end && r_end && gfc_dep_compare_expr (l_end, r_end) == 0)
    {
      if (l_dir == 1 && r_dir == -1)
	return GFC_DEP_EQUAL;
      if (l_dir == -1 && r_dir == 1)
	return GFC_DEP_EQUAL;
    }

  /* Handle cases like x:y:2 vs. x+1:z:4 as GFC_DEP_NODEP.
     There is no dependency if the remainder of
     (l_start - r_start) / gcd(l_stride, r_stride) is
     nonzero.
     TODO:
       - Cases like a(1:4:2) = a(2:3) are still not handled.
  */

#define IS_CONSTANT_INTEGER(a) ((a) && ((a)->expr_type == EXPR_CONSTANT) \
			      && (a)->ts.type == BT_INTEGER)

  if (IS_CONSTANT_INTEGER (l_stride) && IS_CONSTANT_INTEGER (r_stride)
      && gfc_dep_difference (l_start, r_start, &tmp))
    {
      mpz_t gcd;
      int result;

      mpz_init (gcd);
      mpz_gcd (gcd, l_stride->value.integer, r_stride->value.integer);

      mpz_fdiv_r (tmp, tmp, gcd);
      result = mpz_cmp_si (tmp, 0L);

      mpz_clear (gcd);
      mpz_clear (tmp);

      if (result != 0)
	return GFC_DEP_NODEP;
    }

#undef IS_CONSTANT_INTEGER

  /* Check for forward dependencies x:y vs. x+1:z and x:y:z vs. x:y:z+1.  */

  if (l_dir == 1 && r_dir == 1 &&
      (start_comparison == 0 || start_comparison == -1)
      && (stride_comparison == 0 || stride_comparison == -1))
	  return GFC_DEP_FORWARD;

  /* Check for forward dependencies x:y:-1 vs. x-1:z:-1 and
     x:y:-1 vs. x:y:-2.  */
  if (l_dir == -1 && r_dir == -1 &&
      (start_comparison == 0 || start_comparison == 1)
      && (stride_comparison == 0 || stride_comparison == 1))
    return GFC_DEP_FORWARD;

  if (stride_comparison == 0 || stride_comparison == -1)
    {
      if (l_start && IS_ARRAY_EXPLICIT (l_ar->as))
	{

	  /* Check for a(low:y:s) vs. a(z:x:s) or
	     a(low:y:s) vs. a(z:x:s+1) where a has a lower bound
	     of low, which is always at least a forward dependence.  */

	  if (r_dir == 1
	      && gfc_dep_compare_expr (l_start, l_ar->as->lower[n]) == 0)
	    return GFC_DEP_FORWARD;
	}
    }

  if (stride_comparison == 0 || stride_comparison == 1)
    {
      if (l_start && IS_ARRAY_EXPLICIT (l_ar->as))
	{

	  /* Check for a(high:y:-s) vs. a(z:x:-s) or
	     a(high:y:-s vs. a(z:x:-s-1) where a has a higher bound
	     of high, which is always at least a forward dependence.  */

	  if (r_dir == -1
	      && gfc_dep_compare_expr (l_start, l_ar->as->upper[n]) == 0)
	    return GFC_DEP_FORWARD;
	}
    }


  if (stride_comparison == 0)
    {
      /* From here, check for backwards dependencies.  */
      /* x+1:y vs. x:z.  */
      if (l_dir == 1 && r_dir == 1  && start_comparison == 1)
	return GFC_DEP_BACKWARD;

      /* x-1:y:-1 vs. x:z:-1.  */
      if (l_dir == -1 && r_dir == -1 && start_comparison == -1)
	return GFC_DEP_BACKWARD;
    }

  return GFC_DEP_OVERLAP;
}


/* Determines overlapping for a single element and a section.  */

static gfc_dependency
gfc_check_element_vs_section( gfc_ref *lref, gfc_ref *rref, int n)
{
  gfc_array_ref *ref;
  gfc_expr *elem;
  gfc_expr *start;
  gfc_expr *end;
  gfc_expr *stride;
  int s;

  elem = lref->u.ar.start[n];
  if (!elem)
    return GFC_DEP_OVERLAP;

  ref = &rref->u.ar;
  start = ref->start[n] ;
  end = ref->end[n] ;
  stride = ref->stride[n];

  if (!start && IS_ARRAY_EXPLICIT (ref->as))
    start = ref->as->lower[n];
  if (!end && IS_ARRAY_EXPLICIT (ref->as))
    end = ref->as->upper[n];

  /* Determine whether the stride is positive or negative.  */
  if (!stride)
    s = 1;
  else if (stride->expr_type == EXPR_CONSTANT
	   && stride->ts.type == BT_INTEGER)
    s = mpz_sgn (stride->value.integer);
  else
    s = -2;

  /* Stride should never be zero.  */
  if (s == 0)
    return GFC_DEP_OVERLAP;

  /* Positive strides.  */
  if (s == 1)
    {
      /* Check for elem < lower.  */
      if (start && gfc_dep_compare_expr (elem, start) == -1)
	return GFC_DEP_NODEP;
      /* Check for elem > upper.  */
      if (end && gfc_dep_compare_expr (elem, end) == 1)
	return GFC_DEP_NODEP;

      if (start && end)
	{
	  s = gfc_dep_compare_expr (start, end);
	  /* Check for an empty range.  */
	  if (s == 1)
	    return GFC_DEP_NODEP;
	  if (s == 0 && gfc_dep_compare_expr (elem, start) == 0)
	    return GFC_DEP_EQUAL;
	}
    }
  /* Negative strides.  */
  else if (s == -1)
    {
      /* Check for elem > upper.  */
      if (end && gfc_dep_compare_expr (elem, start) == 1)
	return GFC_DEP_NODEP;
      /* Check for elem < lower.  */
      if (start && gfc_dep_compare_expr (elem, end) == -1)
	return GFC_DEP_NODEP;

      if (start && end)
	{
	  s = gfc_dep_compare_expr (start, end);
	  /* Check for an empty range.  */
	  if (s == -1)
	    return GFC_DEP_NODEP;
	  if (s == 0 && gfc_dep_compare_expr (elem, start) == 0)
	    return GFC_DEP_EQUAL;
	}
    }
  /* Unknown strides.  */
  else
    {
      if (!start || !end)
	return GFC_DEP_OVERLAP;
      s = gfc_dep_compare_expr (start, end);
      if (s <= -2)
	return GFC_DEP_OVERLAP;
      /* Assume positive stride.  */
      if (s == -1)
	{
	  /* Check for elem < lower.  */
	  if (gfc_dep_compare_expr (elem, start) == -1)
	    return GFC_DEP_NODEP;
	  /* Check for elem > upper.  */
	  if (gfc_dep_compare_expr (elem, end) == 1)
	    return GFC_DEP_NODEP;
	}
      /* Assume negative stride.  */
      else if (s == 1)
	{
	  /* Check for elem > upper.  */
	  if (gfc_dep_compare_expr (elem, start) == 1)
	    return GFC_DEP_NODEP;
	  /* Check for elem < lower.  */
	  if (gfc_dep_compare_expr (elem, end) == -1)
	    return GFC_DEP_NODEP;
	}
      /* Equal bounds.  */
      else if (s == 0)
	{
	  s = gfc_dep_compare_expr (elem, start);
	  if (s == 0)
	    return GFC_DEP_EQUAL;
	  if (s == 1 || s == -1)
	    return GFC_DEP_NODEP;
	}
    }

  return GFC_DEP_OVERLAP;
}


/* Traverse expr, checking all EXPR_VARIABLE symbols for their
   forall_index attribute.  Return true if any variable may be
   being used as a FORALL index.  Its safe to pessimistically
   return true, and assume a dependency.  */

static bool
contains_forall_index_p (gfc_expr *expr)
{
  gfc_actual_arglist *arg;
  gfc_constructor *c;
  gfc_ref *ref;
  int i;

  if (!expr)
    return false;

  switch (expr->expr_type)
    {
    case EXPR_VARIABLE:
      if (expr->symtree->n.sym->forall_index)
	return true;
      break;

    case EXPR_OP:
      if (contains_forall_index_p (expr->value.op.op1)
	  || contains_forall_index_p (expr->value.op.op2))
	return true;
      break;

    case EXPR_FUNCTION:
      for (arg = expr->value.function.actual; arg; arg = arg->next)
	if (contains_forall_index_p (arg->expr))
	  return true;
      break;

    case EXPR_CONSTANT:
    case EXPR_NULL:
    case EXPR_SUBSTRING:
      break;

    case EXPR_STRUCTURE:
    case EXPR_ARRAY:
      for (c = gfc_constructor_first (expr->value.constructor);
	   c; gfc_constructor_next (c))
	if (contains_forall_index_p (c->expr))
	  return true;
      break;

    default:
      gcc_unreachable ();
    }

  for (ref = expr->ref; ref; ref = ref->next)
    switch (ref->type)
      {
      case REF_ARRAY:
	for (i = 0; i < ref->u.ar.dimen; i++)
	  if (contains_forall_index_p (ref->u.ar.start[i])
	      || contains_forall_index_p (ref->u.ar.end[i])
	      || contains_forall_index_p (ref->u.ar.stride[i]))
	    return true;
	break;

      case REF_COMPONENT:
	break;

      case REF_SUBSTRING:
	if (contains_forall_index_p (ref->u.ss.start)
	    || contains_forall_index_p (ref->u.ss.end))
	  return true;
	break;

      default:
	gcc_unreachable ();
      }

  return false;
}

/* Determines overlapping for two single element array references.  */

static gfc_dependency
gfc_check_element_vs_element (gfc_ref *lref, gfc_ref *rref, int n)
{
  gfc_array_ref l_ar;
  gfc_array_ref r_ar;
  gfc_expr *l_start;
  gfc_expr *r_start;
  int i;

  l_ar = lref->u.ar;
  r_ar = rref->u.ar;
  l_start = l_ar.start[n] ;
  r_start = r_ar.start[n] ;
  i = gfc_dep_compare_expr (r_start, l_start);
  if (i == 0)
    return GFC_DEP_EQUAL;

  /* Treat two scalar variables as potentially equal.  This allows
     us to prove that a(i,:) and a(j,:) have no dependency.  See
     Gerald Roth, "Evaluation of Array Syntax Dependence Analysis",
     Proceedings of the International Conference on Parallel and
     Distributed Processing Techniques and Applications (PDPTA2001),
     Las Vegas, Nevada, June 2001.  */
  /* However, we need to be careful when either scalar expression
     contains a FORALL index, as these can potentially change value
     during the scalarization/traversal of this array reference.  */
  if (contains_forall_index_p (r_start) || contains_forall_index_p (l_start))
    return GFC_DEP_OVERLAP;

  if (i > -2)
    return GFC_DEP_NODEP;

  return GFC_DEP_EQUAL;
}

/* Callback function for checking if an expression depends on a
   dummy variable which is any other than INTENT(IN).  */

static int
callback_dummy_intent_not_in (gfc_expr **ep,
			      int *walk_subtrees ATTRIBUTE_UNUSED,
			      void *data ATTRIBUTE_UNUSED)
{
  gfc_expr *e = *ep;

  if (e->expr_type == EXPR_VARIABLE && e->symtree
      && e->symtree->n.sym->attr.dummy)
    return e->symtree->n.sym->attr.intent != INTENT_IN;
  else
    return 0;
}

/* Auxiliary function to check if subexpressions have dummy variables which
   are not intent(in).
*/

static bool
dummy_intent_not_in (gfc_expr **ep)
{
  return gfc_expr_walker (ep, callback_dummy_intent_not_in, NULL);
}

/* Determine if an array ref, usually an array section specifies the
   entire array.  In addition, if the second, pointer argument is
   provided, the function will return true if the reference is
   contiguous; eg. (:, 1) gives true but (1,:) gives false.
   If one of the bounds depends on a dummy variable which is
   not INTENT(IN), also return false, because the user may
   have changed the variable.  */

bool
gfc_full_array_ref_p (gfc_ref *ref, bool *contiguous)
{
  int i;
  int n;
  bool lbound_OK = true;
  bool ubound_OK = true;

  if (contiguous)
    *contiguous = false;

  if (ref->type != REF_ARRAY)
    return false;

  if (ref->u.ar.type == AR_FULL)
    {
      if (contiguous)
	*contiguous = true;
      return true;
    }

  if (ref->u.ar.type != AR_SECTION)
    return false;
  if (ref->next)
    return false;

  for (i = 0; i < ref->u.ar.dimen; i++)
    {
      /* If we have a single element in the reference, for the reference
	 to be full, we need to ascertain that the array has a single
	 element in this dimension and that we actually reference the
	 correct element.  */
      if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT)
	{
	  /* This is unconditionally a contiguous reference if all the
	     remaining dimensions are elements.  */
	  if (contiguous)
	    {
	      *contiguous = true;
	      for (n = i + 1; n < ref->u.ar.dimen; n++)
		if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
		  *contiguous = false;
	    }

	  if (!ref->u.ar.as
	      || !ref->u.ar.as->lower[i]
	      || !ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (ref->u.ar.as->lower[i],
				       ref->u.ar.as->upper[i])
	      || !ref->u.ar.start[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       ref->u.ar.as->lower[i]))
	    return false;
	  else
	    continue;
	}

      /* Check the lower bound.  */
      if (ref->u.ar.start[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->lower[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       ref->u.ar.as->lower[i])
	      || dummy_intent_not_in (&ref->u.ar.start[i])))
	lbound_OK = false;
      /* Check the upper bound.  */
      if (ref->u.ar.end[i]
	  && (!ref->u.ar.as
	      || !ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (ref->u.ar.end[i],
				       ref->u.ar.as->upper[i])
	      || dummy_intent_not_in (&ref->u.ar.end[i])))
	ubound_OK = false;
      /* Check the stride.  */
      if (ref->u.ar.stride[i]
	    && !gfc_expr_is_one (ref->u.ar.stride[i], 0))
	return false;

      /* This is unconditionally a contiguous reference as long as all
	 the subsequent dimensions are elements.  */
      if (contiguous)
	{
	  *contiguous = true;
	  for (n = i + 1; n < ref->u.ar.dimen; n++)
	    if (ref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
	      *contiguous = false;
	}

      if (!lbound_OK || !ubound_OK)
	return false;
    }
  return true;
}


/* Determine if a full array is the same as an array section with one
   variable limit.  For this to be so, the strides must both be unity
   and one of either start == lower or end == upper must be true.  */

static bool
ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
{
  int i;
  bool upper_or_lower;

  if (full_ref->type != REF_ARRAY)
    return false;
  if (full_ref->u.ar.type != AR_FULL)
    return false;
  if (ref->type != REF_ARRAY)
    return false;
  if (ref->u.ar.type == AR_FULL)
    return true;
  if (ref->u.ar.type != AR_SECTION)
    return false;

  for (i = 0; i < ref->u.ar.dimen; i++)
    {
      /* If we have a single element in the reference, we need to check
	 that the array has a single element and that we actually reference
	 the correct element.  */
      if (ref->u.ar.dimen_type[i] == DIMEN_ELEMENT)
	{
	  if (!full_ref->u.ar.as
	      || !full_ref->u.ar.as->lower[i]
	      || !full_ref->u.ar.as->upper[i]
	      || gfc_dep_compare_expr (full_ref->u.ar.as->lower[i],
				       full_ref->u.ar.as->upper[i])
	      || !ref->u.ar.start[i]
	      || gfc_dep_compare_expr (ref->u.ar.start[i],
				       full_ref->u.ar.as->lower[i]))
	    return false;
	}

      /* Check the strides.  */
      if (full_ref->u.ar.stride[i] && !gfc_expr_is_one (full_ref->u.ar.stride[i], 0))
	return false;
      if (ref->u.ar.stride[i] && !gfc_expr_is_one (ref->u.ar.stride[i], 0))
	return false;

      upper_or_lower = false;
      /* Check the lower bound.  */
      if (ref->u.ar.start[i]
	  && (ref->u.ar.as
	        && full_ref->u.ar.as->lower[i]
	        && gfc_dep_compare_expr (ref->u.ar.start[i],
				         full_ref->u.ar.as->lower[i]) == 0))
	upper_or_lower =  true;
      /* Check the upper bound.  */
      if (ref->u.ar.end[i]
	  && (ref->u.ar.as
	        && full_ref->u.ar.as->upper[i]
	        && gfc_dep_compare_expr (ref->u.ar.end[i],
				         full_ref->u.ar.as->upper[i]) == 0))
	upper_or_lower =  true;
      if (!upper_or_lower)
	return false;
    }
  return true;
}


/* Finds if two array references are overlapping or not.
   Return value
	2 : array references are overlapping but reversal of one or
	    more dimensions will clear the dependency.
	1 : array references are overlapping, or identical is true and
	    there is some kind of overlap.
	0 : array references are identical or not overlapping.  */

int
gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
		  bool identical)
{
  int n;
  int m;
  gfc_dependency fin_dep;
  gfc_dependency this_dep;
  bool same_component = false;

  this_dep = GFC_DEP_ERROR;
  fin_dep = GFC_DEP_ERROR;
  /* Dependencies due to pointers should already have been identified.
     We only need to check for overlapping array references.  */

  while (lref && rref)
    {
      /* The refs might come in mixed, one with a _data component and one
	 without.  Look at their next reference in order to avoid an
	 ICE.  */

      if (lref && lref->type == REF_COMPONENT && lref->u.c.component
	  && strcmp (lref->u.c.component->name, "_data") == 0)
	lref = lref->next;

      if (rref && rref->type == REF_COMPONENT && rref->u.c.component
	  && strcmp (rref->u.c.component->name, "_data") == 0)
	rref = rref->next;

      /* We're resolving from the same base symbol, so both refs should be
	 the same type.  We traverse the reference chain until we find ranges
	 that are not equal.  */
      gcc_assert (lref->type == rref->type);
      switch (lref->type)
	{
	case REF_COMPONENT:
	  /* The two ranges can't overlap if they are from different
	     components.  */
	  if (lref->u.c.component != rref->u.c.component)
	    return 0;

	  same_component = true;
	  break;

	case REF_SUBSTRING:
	  /* Substring overlaps are handled by the string assignment code
	     if there is not an underlying dependency.  */
	  return (fin_dep == GFC_DEP_OVERLAP) ? 1 : 0;

	case REF_ARRAY:
	  /* Coarrays: If there is a coindex, either the image differs and there
	     is no overlap or the image is the same - then the normal analysis
	     applies.  Hence, return early if either ref is coindexed and more
	     than one image can exist.  */
	  if (flag_coarray != GFC_FCOARRAY_SINGLE
	      && ((lref->u.ar.codimen
		   && lref->u.ar.dimen_type[lref->u.ar.dimen]
		      != DIMEN_THIS_IMAGE)
		  || (rref->u.ar.codimen
		      && lref->u.ar.dimen_type[lref->u.ar.dimen]
			 != DIMEN_THIS_IMAGE)))
	    return 1;
	  if (lref->u.ar.dimen == 0 || rref->u.ar.dimen == 0)
	    {
	      /* Coindexed scalar coarray with GFC_FCOARRAY_SINGLE.  */
	      if (lref->u.ar.dimen || rref->u.ar.dimen)
		return 1;  /* Just to be sure.  */
	      fin_dep = GFC_DEP_EQUAL;
	      break;
	    }

	  if (ref_same_as_full_array (lref, rref))
	    return identical;

	  if (ref_same_as_full_array (rref, lref))
	    return identical;

	  if (lref->u.ar.dimen != rref->u.ar.dimen)
	    {
	      if (lref->u.ar.type == AR_FULL)
		fin_dep = gfc_full_array_ref_p (rref, NULL) ? GFC_DEP_EQUAL
							    : GFC_DEP_OVERLAP;
	      else if (rref->u.ar.type == AR_FULL)
		fin_dep = gfc_full_array_ref_p (lref, NULL) ? GFC_DEP_EQUAL
							    : GFC_DEP_OVERLAP;
	      else
		return 1;
	      break;
	    }

	  /* Index for the reverse array.  */
	  m = -1;
	  for (n = 0; n < lref->u.ar.dimen; n++)
	    {
	      /* Handle dependency when either of array reference is vector
		 subscript. There is no dependency if the vector indices
		 are equal or if indices are known to be different in a
		 different dimension.  */
	      if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR
		  || rref->u.ar.dimen_type[n] == DIMEN_VECTOR)
		{
		  if (lref->u.ar.dimen_type[n] == DIMEN_VECTOR
		      && rref->u.ar.dimen_type[n] == DIMEN_VECTOR
		      && gfc_dep_compare_expr (lref->u.ar.start[n],
					       rref->u.ar.start[n]) == 0)
		    this_dep = GFC_DEP_EQUAL;
		  else
		    this_dep = GFC_DEP_OVERLAP;

		  goto update_fin_dep;
		}

	      if (lref->u.ar.dimen_type[n] == DIMEN_RANGE
		  && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
		this_dep = check_section_vs_section (&lref->u.ar,
						     &rref->u.ar, n);
	      else if (lref->u.ar.dimen_type[n] == DIMEN_ELEMENT
		       && rref->u.ar.dimen_type[n] == DIMEN_RANGE)
		this_dep = gfc_check_element_vs_section (lref, rref, n);
	      else if (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
		       && lref->u.ar.dimen_type[n] == DIMEN_RANGE)
		this_dep = gfc_check_element_vs_section (rref, lref, n);
	      else
		{
		  gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
			      && lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
		  this_dep = gfc_check_element_vs_element (rref, lref, n);
		  if (identical && this_dep == GFC_DEP_EQUAL)
		    this_dep = GFC_DEP_OVERLAP;
		}

	      /* If any dimension doesn't overlap, we have no dependency.  */
	      if (this_dep == GFC_DEP_NODEP)
		return 0;

	      /* Now deal with the loop reversal logic:  This only works on
		 ranges and is activated by setting
				reverse[n] == GFC_ENABLE_REVERSE
		 The ability to reverse or not is set by previous conditions
		 in this dimension.  If reversal is not activated, the
		 value GFC_DEP_BACKWARD is reset to GFC_DEP_OVERLAP.  */

	      /* Get the indexing right for the scalarizing loop. If this
		 is an element, there is no corresponding loop.  */
	      if (lref->u.ar.dimen_type[n] != DIMEN_ELEMENT)
		m++;

	      if (rref->u.ar.dimen_type[n] == DIMEN_RANGE
		    && lref->u.ar.dimen_type[n] == DIMEN_RANGE)
		{
		  if (reverse)
		    {
		      /* Reverse if backward dependence and not inhibited.  */
		      if (reverse[m] == GFC_ENABLE_REVERSE
			  && this_dep == GFC_DEP_BACKWARD)
			reverse[m] = GFC_REVERSE_SET;

		      /* Forward if forward dependence and not inhibited.  */
		      if (reverse[m] == GFC_ENABLE_REVERSE
			  && this_dep == GFC_DEP_FORWARD)
			reverse[m] = GFC_FORWARD_SET;

		      /* Flag up overlap if dependence not compatible with
			 the overall state of the expression.  */
		      if (reverse[m] == GFC_REVERSE_SET
			  && this_dep == GFC_DEP_FORWARD)
			{
			  reverse[m] = GFC_INHIBIT_REVERSE;
			  this_dep = GFC_DEP_OVERLAP;
			}
		      else if (reverse[m] == GFC_FORWARD_SET
			       && this_dep == GFC_DEP_BACKWARD)
			{
			  reverse[m] = GFC_INHIBIT_REVERSE;
			  this_dep = GFC_DEP_OVERLAP;
			}
		    }

		  /* If no intention of reversing or reversing is explicitly
		     inhibited, convert backward dependence to overlap.  */
		  if ((!reverse && this_dep == GFC_DEP_BACKWARD)
		      || (reverse && reverse[m] == GFC_INHIBIT_REVERSE))
		    this_dep = GFC_DEP_OVERLAP;
		}

	      /* Overlap codes are in order of priority.  We only need to
		 know the worst one.*/

	    update_fin_dep:
	      if (identical && this_dep == GFC_DEP_EQUAL)
		this_dep = GFC_DEP_OVERLAP;

	      if (this_dep > fin_dep)
		fin_dep = this_dep;
	    }

	  /* If this is an equal element, we have to keep going until we find
	     the "real" array reference.  */
	  if (lref->u.ar.type == AR_ELEMENT
		&& rref->u.ar.type == AR_ELEMENT
		&& fin_dep == GFC_DEP_EQUAL)
	    break;

	  /* Exactly matching and forward overlapping ranges don't cause a
	     dependency.  */
	  if (fin_dep < GFC_DEP_BACKWARD && !identical)
	    return 0;

	  /* Keep checking.  We only have a dependency if
	     subsequent references also overlap.  */
	  break;

	case REF_INQUIRY:
	  if (lref->u.i != rref->u.i)
	    return 0;

	  break;

	default:
	  gcc_unreachable ();
	}
      lref = lref->next;
      rref = rref->next;
    }

  /* Assume the worst if we nest to different depths.  */
  if (lref || rref)
    return 1;

  /* This can result from concatenation of assumed length string components.  */
  if (same_component && fin_dep == GFC_DEP_ERROR)
    return 1;

  /* If we haven't seen any array refs then something went wrong.  */
  gcc_assert (fin_dep != GFC_DEP_ERROR);

  if (identical && fin_dep != GFC_DEP_NODEP)
    return 1;

  return fin_dep == GFC_DEP_OVERLAP;
}
