diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eba838bab8e0302b1db2d621d94cca62394df0b9..02d59e08915a0c5c70496f9a49f44f0744fd6fed 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2008-09-04  Jan Hubicka  <jh@suse.cz>
+
+	* tree-vrp.c (vrp_evaluate_conditional_warnv_with_ops_using_ranges):
+	Break out from ...
+	(vrp_evaluate_conditional_warnv_with_ops): ... this one.  Add
+	using_ranges argument.
+	(vrp_evaluate_conditional): Avoid bogus warning for type range.
+	(vrp_visit_cond_stmt): Update call of
+	vrp_evaluate_conditional_warnv_with_ops
+
 2008-09-04  Jan Hubicka  <jh@suse.cz>
 
 	PR tree-optimization/37345
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8db35ca42d92f4689f3f4d7afdba16fa52d81b9d..46aa69d59ae04e297d88313d5706af79bd84cb17 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -57,7 +57,8 @@ static int compare_values (tree val1, tree val2);
 static int compare_values_warnv (tree val1, tree val2, bool *);
 static void vrp_meet (value_range_t *, value_range_t *);
 static tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
-						     tree, tree, bool, bool *);
+						     tree, tree, bool, bool *,
+						     bool *);
 
 /* Location information for ASSERT_EXPRs.  Each instance of this
    structure describes an ASSERT_EXPR for an SSA name.  Since a single
@@ -2905,7 +2906,8 @@ extract_range_from_comparison (value_range_t *vr, enum tree_code code,
   bool sop = false;
   tree val;
   
-  val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop);
+  val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop,
+  						 NULL);
 
   /* A disadvantage of using a special infinity as an overflow
      representation is that we lose the ability to record overflow
@@ -5447,13 +5449,39 @@ compare_names (enum tree_code comp, tree n1, tree n2,
   return NULL_TREE;
 }
 
+/* Helper function for vrp_evaluate_conditional_warnv.  */
+
+static tree
+vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code code,
+						      tree op0, tree op1,
+						      bool * strict_overflow_p)
+{
+  value_range_t *vr0, *vr1;
+
+  vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
+  vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
+
+  if (vr0 && vr1)
+    return compare_ranges (code, vr0, vr1, strict_overflow_p);
+  else if (vr0 && vr1 == NULL)
+    return compare_range_with_value (code, vr0, op1, strict_overflow_p);
+  else if (vr0 == NULL && vr1)
+    return (compare_range_with_value
+	    (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
+  return NULL;
+}
+
 /* Helper function for vrp_evaluate_conditional_warnv. */
 
 static tree
 vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
 					 tree op1, bool use_equiv_p,
-					 bool *strict_overflow_p)
+					 bool *strict_overflow_p, bool *only_ranges)
 {
+  tree ret;
+  if (only_ranges)
+    *only_ranges = true;
+
   /* We only deal with integral and pointer types.  */
   if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
       && !POINTER_TYPE_P (TREE_TYPE (op0)))
@@ -5461,6 +5489,11 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
 
   if (use_equiv_p)
     {
+      if (only_ranges
+          && (ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
+	              (code, op0, op1, strict_overflow_p)))
+	return ret;
+      *only_ranges = false;
       if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
 	return compare_names (code, op0, op1, strict_overflow_p);
       else if (TREE_CODE (op0) == SSA_NAME)
@@ -5470,20 +5503,8 @@ vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
 		(swap_tree_comparison (code), op1, op0, strict_overflow_p));
     }
   else
-    {
-      value_range_t *vr0, *vr1;
-
-      vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
-      vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
-
-      if (vr0 && vr1)
-	return compare_ranges (code, vr0, vr1, strict_overflow_p);
-      else if (vr0 && vr1 == NULL)
-	return compare_range_with_value (code, vr0, op1, strict_overflow_p);
-      else if (vr0 == NULL && vr1)
-	return (compare_range_with_value
-		(swap_tree_comparison (code), vr1, op0, strict_overflow_p));
-    }
+    return vrp_evaluate_conditional_warnv_with_ops_using_ranges (code, op0, op1,
+								 strict_overflow_p);
   return NULL_TREE;
 }
 
@@ -5499,9 +5520,11 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
 {
   bool sop;
   tree ret;
+  bool only_ranges;
 
   sop = false;
-  ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop);
+  ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop,
+  						 &only_ranges);
 
   if (ret && sop)
     {
@@ -5534,7 +5557,7 @@ vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
     }
 
   if (warn_type_limits
-      && ret
+      && ret && only_ranges
       && TREE_CODE_CLASS (code) == tcc_comparison
       && TREE_CODE (op0) == SSA_NAME)
     {
@@ -5658,7 +5681,7 @@ vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
   val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
 						 gimple_cond_lhs (stmt),
 						 gimple_cond_rhs (stmt),
-						 false, &sop);
+						 false, &sop, NULL);
   if (val)
     {
       if (!sop)