/* See backwards thru casts if the range fits the LHS type. */
/* { dg-do compile } */
/* { dg-options "-O2  -fdump-tree-evrp" } */

extern void kill(int i);
extern void keep(int i);

void
foo (int i)
{
  if (i >= 10)
    {
      if (i <= 100)
	{
	  /* i has a range of [10, 100]  */
	  char c = (char) i;
	  if (c < 30)
	    {
	      /* If we wind back thru the cast with the range of c being [10,29]
	       * from the branch, and recognize that the range of i fits within
	       * a cast to c, then there is no missing information in a cast
	       * back to int. We can use the range calculated for 'c' with 'i'
	       * as well and Ranger should be able to kill the call.  */
	      if (i > 29)
		kill (i);
	    }
	}
      /* i has a range of [10, MAX]  */
      char d  = (char) i;
      if (d < 30)
	{
	  /* Here, a cast to a char and back is NOT equivalent, so we cannot use
	   * the value of d to remove the call.  */
	  if (i > 29)
	    keep (i);
	}

    }
}

/* { dg-final { scan-tree-dump-times "kill \\(" 0 "evrp"} } */
/* { dg-final { scan-tree-dump-times "keep \\(" 1 "evrp"} } */