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]

Re: [PATCH] Improve VR computation for [x, y] & z or [x, y] | z (PR tree-optimization/80558)


On Fri, May 05, 2017 at 01:59:17PM +0200, Richard Biener wrote:
> On Thu, 4 May 2017, Jakub Jelinek wrote:
> 
> > Hi!
> > 
> > This patch improves value range computation of BIT_{AND,IOR}_EXPR
> > with one singleton range and one range_int_cst_p, where the singleton
> > range has n clear least significant bits, then m set bits and either
> > that is all it has (i.e. negation of a power of 2), or the bits above
> > those two sets of bits are the same for all values in the range (i.e.
> > min and max range have those bits identical).
> > During x86_64-linux and i686-linux bootstraps together this triggers
> > 214000 times, though I have not actually gathered statistics on whether
> > the range computed without this patch would be wider in all cases.
> 
> You could try to intersect the ranges produced and assert the
> result is equal to the new one.

I've done the following statistics incremental patch, and on x86_64-linux
and i686-linux bootstraps/regtests it gave (first column is number of
occurrences of those 2 numbers):
   6877 -4 -4 # Range where previously we'd end up VARYING
  15430 -1 1 # Bigger minimum and smaller maximum than before
  17767 -1 0 # Same maximum, with the patch bigger minimum than before
  20014 0 1 # Same minimum, with the patch smaller maximum than before
 153948 0 0 # These are cases where we return the same range as before
So there are no cases where we'd give wider range than before.

Committing the patch now (of course not the following one).

--- gcc/tree-vrp.c.jj	2017-05-05 15:08:36.000000000 +0200
+++ gcc/tree-vrp.c	2017-05-05 15:33:35.094546653 +0200
@@ -2857,6 +2857,7 @@ extract_range_from_binary_expr_1 (value_
       bool int_cst_range0, int_cst_range1;
       wide_int may_be_nonzero0, may_be_nonzero1;
       wide_int must_be_nonzero0, must_be_nonzero1;
+      tree minxx = NULL_TREE, maxxx = NULL_TREE;
 
       int_cst_range0 = zero_nonzero_bits_from_vr (expr_type, &vr0,
 						  &may_be_nonzero0,
@@ -2908,8 +2909,8 @@ extract_range_from_binary_expr_1 (value_
 	      wide_int mask = wi::mask (m + n, true, w.get_precision ());
 	      if (wi::eq_p (mask & vr0p->min, mask & vr0p->max))
 		{
-		  min = int_const_binop (code, vr0p->min, vr1p->min);
-		  max = int_const_binop (code, vr0p->max, vr1p->min);
+		  minxx = int_const_binop (code, vr0p->min, vr1p->min);
+		  maxxx = int_const_binop (code, vr0p->max, vr1p->min);
 		}
 	    }
 	}
@@ -3000,6 +3001,33 @@ extract_range_from_binary_expr_1 (value_
 	  else
 	    max = min = NULL_TREE;
 	}
+      if (minxx && maxxx)
+	{
+	  int z1, z2;
+	  if (min && !TREE_OVERFLOW (min))
+	    z1 = compare_values (min, minxx);
+	  else
+	    z1 = -3;
+	  if (max && !TREE_OVERFLOW (max))
+	    z2 = compare_values (max, maxxx);
+	  else
+	    z2 = -3;
+          if (min && max)
+	    {
+	      int z3 = compare_values (min, max);
+	      if (z3 == -2 || z3 == 1)
+		{
+		  z1 = -4;
+		  z2 = -4;
+	        }
+	    }
+
+	  FILE *f = fopen ("/tmp/vrpz", "a");
+	  fprintf (f, "%d %d %d %s %s\n", z1, z2, (int) BITS_PER_WORD, main_input_filename ? main_input_filename : "-", current_function_name ());
+	  fclose (f);
+	  min = minxx;
+	  max = maxxx;
+	}
     }
   else
     gcc_unreachable ();


	Jakub


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