[PATCH] Remove vr_values::extract_range_builtin.

Aldy Hernandez aldyh@redhat.com
Tue Oct 20 16:43:54 GMT 2020


As promised.

Now that we know the vr_values and ranger versions are in sync, it
is safe to remove the vr_values version and just call the ranger one.

I am holding off on pushing this for a week or two, or until Fedora gets
rebuilt with the current compiler.

gcc/ChangeLog:

	* vr-values.h (class vr_values): Remove extract_range_builtin.
	* vr-values.c (vr_values::extract_range_basic): Remove call to
	extract_range_builtin.
	(vr_values::extract_range_builtin): Remove.
---
 gcc/vr-values.c | 277 +-----------------------------------------------
 gcc/vr-values.h |   1 -
 2 files changed, 3 insertions(+), 275 deletions(-)

diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 11beef82a64..1dac1cfc49f 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -1155,271 +1155,6 @@ check_for_binary_op_overflow (range_query *query,
   return true;
 }
 
-/* Derive a range from a builtin.  Set range in VR and return TRUE if
-   successful.  */
-
-bool
-vr_values::extract_range_builtin (value_range_equiv *vr, gimple *stmt)
-{
-  gcc_assert (is_gimple_call (stmt));
-  tree type = gimple_expr_type (stmt);
-  tree arg;
-  int mini, maxi, zerov = 0, prec;
-  enum tree_code subcode = ERROR_MARK;
-  combined_fn cfn = gimple_call_combined_fn (stmt);
-  scalar_int_mode mode;
-
-  switch (cfn)
-    {
-    case CFN_BUILT_IN_CONSTANT_P:
-      /* Resolve calls to __builtin_constant_p after inlining.  */
-      if (cfun->after_inlining)
-	{
-	  vr->set_zero (type);
-	  vr->equiv_clear ();
-	  return true;
-	}
-      break;
-      /* Both __builtin_ffs* and __builtin_popcount return
-	 [0, prec].  */
-    CASE_CFN_FFS:
-    CASE_CFN_POPCOUNT:
-      arg = gimple_call_arg (stmt, 0);
-      prec = TYPE_PRECISION (TREE_TYPE (arg));
-      mini = 0;
-      maxi = prec;
-      if (TREE_CODE (arg) == SSA_NAME)
-	{
-	  const value_range_equiv *vr0 = get_value_range (arg);
-	  /* If arg is non-zero, then ffs or popcount are non-zero.  */
-	  if (range_includes_zero_p (vr0) == 0)
-	    mini = 1;
-	  /* If some high bits are known to be zero,
-	     we can decrease the maximum.  */
-	  if (vr0->kind () == VR_RANGE
-	      && TREE_CODE (vr0->max ()) == INTEGER_CST
-	      && !operand_less_p (vr0->min (),
-				  build_zero_cst (TREE_TYPE (vr0->min ()))))
-	    maxi = tree_floor_log2 (vr0->max ()) + 1;
-	}
-      goto bitop_builtin;
-      /* __builtin_parity* returns [0, 1].  */
-    CASE_CFN_PARITY:
-      mini = 0;
-      maxi = 1;
-      goto bitop_builtin;
-      /* __builtin_clz* return [0, prec-1], except for
-	 when the argument is 0, but that is undefined behavior.
-	 Always handle __builtin_clz* which can be only written
-	 by user as UB on 0 and so [0, prec-1] range, and the internal-fn
-	 calls depending on how CLZ_DEFINED_VALUE_AT_ZERO is defined.  */
-    CASE_CFN_CLZ:
-      arg = gimple_call_arg (stmt, 0);
-      prec = TYPE_PRECISION (TREE_TYPE (arg));
-      mini = 0;
-      maxi = prec - 1;
-      mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
-      if (gimple_call_internal_p (stmt))
-	{
-	  if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
-	      && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
-	    {
-	      /* Handle only the single common value.  */
-	      if (zerov == prec)
-		maxi = prec;
-	      /* Magic value to give up, unless vr0 proves
-		 arg is non-zero.  */
-	      else
-		mini = -2;
-	    }
-	}
-      if (TREE_CODE (arg) == SSA_NAME)
-	{
-	  const value_range_equiv *vr0 = get_value_range (arg);
-	  /* From clz of VR_RANGE minimum we can compute
-	     result maximum.  */
-	  if (vr0->kind () == VR_RANGE
-	      && TREE_CODE (vr0->min ()) == INTEGER_CST
-	      && integer_nonzerop (vr0->min ()))
-	    {
-	      maxi = prec - 1 - tree_floor_log2 (vr0->min ());
-	      if (mini == -2)
-		mini = 0;
-	    }
-	  else if (vr0->kind () == VR_ANTI_RANGE
-		   && integer_zerop (vr0->min ()))
-	    {
-	      maxi = prec - 1;
-	      mini = 0;
-	    }
-	  if (mini == -2)
-	    break;
-	  /* From clz of VR_RANGE maximum we can compute
-	     result minimum.  */
-	  if (vr0->kind () == VR_RANGE
-	      && TREE_CODE (vr0->max ()) == INTEGER_CST)
-	    {
-	      int newmini = prec - 1 - tree_floor_log2 (vr0->max ());
-	      if (newmini == prec)
-		{
-		  if (maxi == prec)
-		    mini = prec;
-		}
-	      else
-		mini = newmini;
-	    }
-	}
-      if (mini == -2)
-	break;
-      goto bitop_builtin;
-      /* __builtin_ctz* return [0, prec-1], except for
-	 when the argument is 0, but that is undefined behavior.
-	 Always handle __builtin_ctz* which can be only written
-	 by user as UB on 0 and so [0, prec-1] range, and the internal-fn
-	 calls depending on how CTZ_DEFINED_VALUE_AT_ZERO is defined.  */
-    CASE_CFN_CTZ:
-      arg = gimple_call_arg (stmt, 0);
-      prec = TYPE_PRECISION (TREE_TYPE (arg));
-      mini = 0;
-      maxi = prec - 1;
-      mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
-      if (gimple_call_internal_p (stmt))
-	{
-	  if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
-	      && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov) == 2)
-	    {
-	      /* Handle only the two common values.  */
-	      if (zerov == -1)
-		mini = -1;
-	      else if (zerov == prec)
-		maxi = prec;
-	      else
-		/* Magic value to give up, unless vr0 proves
-		   arg is non-zero.  */
-		mini = -2;
-	    }
-	}
-      if (TREE_CODE (arg) == SSA_NAME)
-	{
-	  const value_range_equiv *vr0 = get_value_range (arg);
-	  /* If arg is non-zero, then use [0, prec - 1].  */
-	  if ((vr0->kind () == VR_RANGE
-	       && integer_nonzerop (vr0->min ()))
-	      || (vr0->kind () == VR_ANTI_RANGE
-		  && integer_zerop (vr0->min ())))
-	    {
-	      mini = 0;
-	      maxi = prec - 1;
-	    }
-	  /* If some high bits are known to be zero,
-	     we can decrease the result maximum.  */
-	  if (vr0->kind () == VR_RANGE
-	      && TREE_CODE (vr0->max ()) == INTEGER_CST)
-	    {
-	      int newmaxi = tree_floor_log2 (vr0->max ());
-	      if (newmaxi == -1)
-		{
-		  if (mini == -1)
-		    maxi = -1;
-		  else if (maxi == prec)
-		    mini = prec;
-		}
-	      else if (maxi != prec)
-		maxi = newmaxi;
-	    }
-	}
-      if (mini == -2)
-	break;
-      goto bitop_builtin;
-      /* __builtin_clrsb* returns [0, prec-1].  */
-    CASE_CFN_CLRSB:
-      arg = gimple_call_arg (stmt, 0);
-      prec = TYPE_PRECISION (TREE_TYPE (arg));
-      mini = 0;
-      maxi = prec - 1;
-      goto bitop_builtin;
-    bitop_builtin:
-      vr->set (build_int_cst (type, mini), build_int_cst (type, maxi));
-      return true;
-    case CFN_UBSAN_CHECK_ADD:
-      subcode = PLUS_EXPR;
-      break;
-    case CFN_UBSAN_CHECK_SUB:
-      subcode = MINUS_EXPR;
-      break;
-    case CFN_UBSAN_CHECK_MUL:
-      subcode = MULT_EXPR;
-      break;
-    case CFN_GOACC_DIM_SIZE:
-    case CFN_GOACC_DIM_POS:
-      /* Optimizing these two internal functions helps the loop
-	 optimizer eliminate outer comparisons.  Size is [1,N]
-	 and pos is [0,N-1].  */
-      {
-	bool is_pos = cfn == CFN_GOACC_DIM_POS;
-	int axis = oacc_get_ifn_dim_arg (stmt);
-	int size = oacc_get_fn_dim_size (current_function_decl, axis);
-
-	if (!size)
-	  /* If it's dynamic, the backend might know a hardware
-	     limitation.  */
-	  size = targetm.goacc.dim_limit (axis);
-
-	tree type = TREE_TYPE (gimple_call_lhs (stmt));
-	vr->set(build_int_cst (type, is_pos ? 0 : 1),
-		size
-		? build_int_cst (type, size - is_pos) : vrp_val_max (type));
-      }
-      return true;
-    case CFN_BUILT_IN_STRLEN:
-      if (tree lhs = gimple_call_lhs (stmt))
-	if (ptrdiff_type_node
-	    && (TYPE_PRECISION (ptrdiff_type_node)
-		== TYPE_PRECISION (TREE_TYPE (lhs))))
-	  {
-	    tree type = TREE_TYPE (lhs);
-	    tree max = vrp_val_max (ptrdiff_type_node);
-	    wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
-	    tree range_min = build_zero_cst (type);
-	    /* To account for the terminating NUL, the maximum length
-	       is one less than the maximum array size, which in turn
-	       is one  less than PTRDIFF_MAX (or SIZE_MAX where it's
-	       smaller than the former type).
-	       FIXME: Use max_object_size() - 1 here.  */
-	    tree range_max = wide_int_to_tree (type, wmax - 2);
-	    vr->set (range_min, range_max);
-	    return true;
-	  }
-      break;
-    default:
-      break;
-    }
-  if (subcode != ERROR_MARK)
-    {
-      bool saved_flag_wrapv = flag_wrapv;
-      /* Pretend the arithmetics is wrapping.  If there is
-	 any overflow, we'll complain, but will actually do
-	 wrapping operation.  */
-      flag_wrapv = 1;
-      extract_range_from_binary_expr (vr, subcode, type,
-				      gimple_call_arg (stmt, 0),
-				      gimple_call_arg (stmt, 1));
-      flag_wrapv = saved_flag_wrapv;
-
-      /* If for both arguments vrp_valueize returned non-NULL,
-	 this should have been already folded and if not, it
-	 wasn't folded because of overflow.  Avoid removing the
-	 UBSAN_CHECK_* calls in that case.  */
-      if (vr->kind () == VR_RANGE
-	  && (vr->min () == vr->max ()
-	      || operand_equal_p (vr->min (), vr->max (), 0)))
-	vr->set_varying (vr->type ());
-
-      return !vr->varying_p ();
-    }
-  return false;
-}
-
 /* Try to derive a nonnegative or nonzero range out of STMT relying
    primarily on generic routines in fold in conjunction with range data.
    Store the result in *VR */
@@ -1430,15 +1165,9 @@ vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
   bool sop;
   tree type = gimple_expr_type (stmt);
 
-  if (is_gimple_call (stmt) && extract_range_builtin (vr, stmt))
-    {
-      value_range_equiv tmp;
-      /* Assert that any ranges vr_values::extract_range_builtin gets
-	 are also handled by the ranger counterpart.  */
-      gcc_assert (range_of_builtin_call (*this, tmp, as_a<gcall *> (stmt)));
-      gcc_assert (tmp.equal_p (*vr, /*ignore_equivs=*/false));
-      return;
-    }
+  if (is_gimple_call (stmt)
+      && range_of_builtin_call (*this, *vr, as_a<gcall *> (stmt)))
+    return;
   /* Handle extraction of the two results (result of arithmetics and
      a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
      internal function.  Similarly from ATOMIC_COMPARE_EXCHANGE.  */
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index b0ff68d8e34..30f06078c57 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -148,7 +148,6 @@ class vr_values : public range_query
   void extract_range_from_comparison (value_range_equiv *, gimple *);
   void vrp_visit_assignment_or_call (gimple*, tree *, value_range_equiv *);
   void vrp_visit_switch_stmt (gswitch *, edge *);
-  bool extract_range_builtin (value_range_equiv *, gimple *);
 
   /* This probably belongs in the lattice rather than in here.  */
   bool values_propagated;
-- 
2.26.2



More information about the Gcc-patches mailing list