This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Supress bogus VRP warning in profiledbootstrap


Hi,
at profiledbootstrap we get wrong warning compiling emit-rtl where gen_rtvec_v
is inlined into gen_rtvec:

rtvec
gen_rtvec (int n, ...)
{
  int i, save_n;
  rtx *vector;
  va_list p;

  __builtin_va_start(p,n);

  if (n == 0)
    return (rtvec) 0;

  vector = ((rtx *) __builtin_alloca(sizeof (rtx) * (n)));

  for (i = 0; i < n; i++)
    vector[i] = __builtin_va_arg(p,rtx);


  save_n = n;
  __builtin_va_end(p);

  return gen_rtvec_v (save_n, vector);
}

inline rtvec
gen_rtvec_v (int n, rtx *argp)
{
  int i;
  rtvec rt_val;

  if (n == 0)
    return (rtvec) 0;

  rt_val = rtvec_alloc (n);

  for (i = 0; i < n; i++)
    rt_val->elem[i] = *argp++;

  return rt_val;
}

there are two n == 0 checks in sequence. VRP correctly figure out that the
second if always false, but it produce bogus warning:

      /* If the comparison is being folded and the operand on the LHS
	 is being compared against a constant value that is outside of
	 the natural range of OP0's type, then the predicate will
	 always fold regardless of the value of OP0.  If -Wtype-limits
	 was specified, emit a warning.  */
      const char *warnmsg = NULL;
      tree type = TREE_TYPE (op0);
      value_range_t *vr0 = get_value_range (op0);

      if (vr0->type != VR_VARYING
	  && INTEGRAL_TYPE_P (type)
	  && vrp_val_is_min (vr0->min)
	  && vrp_val_is_max (vr0->max)
	  && is_gimple_min_invariant (op1))
	{
	  if (integer_zerop (ret))
	    warnmsg = G_("comparison always false due to limited range of "
		         "data type");
	  else
	    warnmsg = G_("comparison always true due to limited range of "
			 "data type");
	}

This code makes wrong assumption that whenever comparsion folded it must be
based on vr0 value range.  This is not true, because
vrp_evaluate_conditional_warnv_with_ops_using_ranges walks incomming edges and
without merging the ranges it tests if for every incomming range condition is
constant, it is constant overall.

This patch makes vrp_evaluate_conditional_warnv_with_ops_using_ranges to set
flag if the folding happent based on the range itself only and supress the
warning otehrwise.  This lets me progress in profiledbootstrap up to point
where we misoptimize read_rtx.

Bootstrapped/regtested i686-linux, seem sane?

	* 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
Index: tree-vrp.c
===================================================================
--- tree-vrp.c	(revision 139886)
+++ tree-vrp.c	(working copy)
@@ -57,7 +57,8 @@ static int compare_values (tree val1, tr
 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_ran
   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
@@ -5439,13 +5441,39 @@ compare_names (enum tree_code comp, tree
   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)))
@@ -5453,6 +5480,11 @@ vrp_evaluate_conditional_warnv_with_ops 
 
   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)
@@ -5462,20 +5494,8 @@ vrp_evaluate_conditional_warnv_with_ops 
 		(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;
 }
 
@@ -5491,9 +5511,11 @@ vrp_evaluate_conditional (enum tree_code
 {
   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)
     {
@@ -5526,7 +5548,7 @@ vrp_evaluate_conditional (enum tree_code
     }
 
   if (warn_type_limits
-      && ret
+      && ret && only_ranges
       && TREE_CODE_CLASS (code) == tcc_comparison
       && TREE_CODE (op0) == SSA_NAME)
     {
@@ -5650,7 +5672,7 @@ vrp_visit_cond_stmt (gimple stmt, edge *
   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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]