Re: VRP: abstract out MIN/MAX/ABS wide int code

2018-08-20 Thread Aldy Hernandez




On 08/20/2018 06:40 PM, Jeff Law wrote:

On 08/17/2018 01:11 AM, Aldy Hernandez wrote:

No change in functionality, just a straight up conversion.

OK for trunk?

curr.patch


gcc/

* wide-int-range.cc (wide_int_range_abs): New.
(wide_int_range_order_set): Rename from wide_int_range_min_max.
* wide-int-range.h (wide_int_range_abs): New.
(wide_int_range_min_max): New.
* tree-vrp.c (extract_range_from_unary_expr): Rewrite ABS_EXPR
case to call wide_int_range_abs.
Rewrite MIN/MAX_EXPR to call wide_int_range_min_max.
(extract_range_from_abs_expr): Delete.

OK.  It was a bit hard to follow because parts of the original
implementation were split and handled in different places.  But AFAICT
it looks like everything got transferred to their new locations.


That was my bad.

ABS_EXPR was convoluted because when I started this work I had a 
different approach and had abstracted it into 
extract_range_from_abs_expr().  That was before I had settled into 
splitting the wide int implementation from the VRP use.


Thanks.

Aldy


Re: VRP: abstract out MIN/MAX/ABS wide int code

2018-08-20 Thread Jeff Law
On 08/17/2018 01:11 AM, Aldy Hernandez wrote:
> No change in functionality, just a straight up conversion.
> 
> OK for trunk?
> 
> curr.patch
> 
> 
> gcc/
> 
>   * wide-int-range.cc (wide_int_range_abs): New.
>   (wide_int_range_order_set): Rename from wide_int_range_min_max.
>   * wide-int-range.h (wide_int_range_abs): New.
>   (wide_int_range_min_max): New.
>   * tree-vrp.c (extract_range_from_unary_expr): Rewrite ABS_EXPR
>   case to call wide_int_range_abs.
>   Rewrite MIN/MAX_EXPR to call wide_int_range_min_max.
>   (extract_range_from_abs_expr): Delete.
OK.  It was a bit hard to follow because parts of the original
implementation were split and handled in different places.  But AFAICT
it looks like everything got transferred to their new locations.

jeff


VRP: abstract out MIN/MAX/ABS wide int code

2018-08-17 Thread Aldy Hernandez

No change in functionality, just a straight up conversion.

OK for trunk?
gcc/

	* wide-int-range.cc (wide_int_range_abs): New.
	(wide_int_range_order_set): Rename from wide_int_range_min_max.
	* wide-int-range.h (wide_int_range_abs): New.
	(wide_int_range_min_max): New.
	* tree-vrp.c (extract_range_from_unary_expr): Rewrite ABS_EXPR
	case to call wide_int_range_abs.
	Rewrite MIN/MAX_EXPR to call wide_int_range_min_max.
	(extract_range_from_abs_expr): Delete.

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index d553a254878..50e9eb0da07 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1589,50 +1589,19 @@ extract_range_from_binary_expr_1 (value_range *vr,
   else if (code == MIN_EXPR
 	   || code == MAX_EXPR)
 {
-  if (vr0.type == VR_RANGE
-	  && !symbolic_range_p (&vr0))
-	{
-	  type = VR_RANGE;
-	  if (vr1.type == VR_RANGE
-	  && !symbolic_range_p (&vr1))
-	{
-	  /* For operations that make the resulting range directly
-		 proportional to the original ranges, apply the operation to
-		 the same end of each range.  */
-	  min = int_const_binop (code, vr0.min, vr1.min);
-	  max = int_const_binop (code, vr0.max, vr1.max);
-	}
-	  else if (code == MIN_EXPR)
-	{
-	  min = vrp_val_min (expr_type);
-	  max = vr0.max;
-	}
-	  else if (code == MAX_EXPR)
-	{
-	  min = vr0.min;
-	  max = vrp_val_max (expr_type);
-	}
-	}
-  else if (vr1.type == VR_RANGE
-	   && !symbolic_range_p (&vr1))
-	{
-	  type = VR_RANGE;
-	  if (code == MIN_EXPR)
-	{
-	  min = vrp_val_min (expr_type);
-	  max = vr1.max;
-	}
-	  else if (code == MAX_EXPR)
-	{
-	  min = vr1.min;
-	  max = vrp_val_max (expr_type);
-	}
-	}
+  wide_int wmin, wmax;
+  wide_int vr0_min, vr0_max;
+  wide_int vr1_min, vr1_max;
+  extract_range_into_wide_ints (&vr0, sign, prec, &vr0_min, &vr0_max);
+  extract_range_into_wide_ints (&vr1, sign, prec, &vr1_min, &vr1_max);
+  if (wide_int_range_min_max (wmin, wmax, code, sign, prec,
+  vr0_min, vr0_max, vr1_min, vr1_max))
+	set_value_range (vr, VR_RANGE,
+			 wide_int_to_tree (expr_type, wmin),
+			 wide_int_to_tree (expr_type, wmax), NULL);
   else
-	{
-	  set_value_range_to_varying (vr);
-	  return;
-	}
+	set_value_range_to_varying (vr);
+  return;
 }
   else if (code == MULT_EXPR)
 {
@@ -1919,85 +1888,6 @@ extract_range_from_binary_expr_1 (value_range *vr,
 set_value_range (vr, type, min, max, NULL);
 }
 
-/* Calculates the absolute value of a range and puts the result in VR.
-   VR0 is the input range.  TYPE is the type of the resulting
-   range.  */
-
-static void
-extract_range_from_abs_expr (value_range &vr, tree type, value_range &vr0)
-{
-  /* Pass through vr0 in the easy cases.  */
-  if (TYPE_UNSIGNED (type)
-  || value_range_nonnegative_p (&vr0))
-{
-  copy_value_range (&vr, &vr0);
-  return;
-}
-
-  /* For the remaining varying or symbolic ranges we can't do anything
- useful.  */
-  if (vr0.type == VR_VARYING
-  || symbolic_range_p (&vr0))
-{
-  set_value_range_to_varying (&vr);
-  return;
-}
-
-  /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
- useful range.  */
-  if (!TYPE_OVERFLOW_UNDEFINED (type)
-  && ((vr0.type == VR_RANGE
-	   && vrp_val_is_min (vr0.min))
-	  || (vr0.type == VR_ANTI_RANGE
-	  && !vrp_val_is_min (vr0.min
-{
-  set_value_range_to_varying (&vr);
-  return;
-}
-
-  /* ABS_EXPR may flip the range around, if the original range
- included negative values.  */
-  tree min, max;
-  if (!vrp_val_is_min (vr0.min))
-min = fold_unary_to_constant (ABS_EXPR, type, vr0.min);
-  else
-min = TYPE_MAX_VALUE (type);
-
-  if (!vrp_val_is_min (vr0.max))
-max = fold_unary_to_constant (ABS_EXPR, type, vr0.max);
-  else
-max = TYPE_MAX_VALUE (type);
-
-  int cmp = compare_values (min, max);
-  gcc_assert (vr0.type != VR_ANTI_RANGE);
-
-  /* If the range contains zero then we know that the minimum value in the
- range will be zero.  */
-  if (range_includes_zero_p (vr0.min, vr0.max) == 1)
-{
-  if (cmp == 1)
-	max = min;
-  min = build_int_cst (type, 0);
-}
-  else
-{
-  /* If the range was reversed, swap MIN and MAX.  */
-  if (cmp == 1)
-	std::swap (min, max);
-}
-
-  cmp = compare_values (min, max);
-  if (cmp == -2 || cmp == 1)
-{
-  /* If the new range has its limits swapped around (MIN > MAX),
-	 then the operation caused one of them to wrap around, mark
-	 the new range VARYING.  */
-  set_value_range_to_varying (&vr);
-}
-  else
-set_value_range (&vr, vr0.type, min, max, NULL);
-}
-
 /* Extract range information from a unary operation CODE based on
the range of its operand *VR0 with type OP0_TYPE with resulting type TYPE.
The resulting range is stored in *VR.  */
@@ -2007,6 +1897,8 @@ extract_range_from_unary_expr (value_range *vr,
 			   enum tree_code code, tree ty