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]

[PATCH] Add BIT_XOR_EXPR support to VRP


This adds BIT_XOR_EXPR support to propagation, similar to how we
have BIT_IOR_EXPR and BIT_AND_EXPR support (but without the
adjustment for constant vr0/1 min/max which I think we cannot do
for XOR).

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2011-08-05  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/49984
	* tree-vrp.c (extract_range_from_binary_expr_1): Handle BIT_XOR_EXPR.

	* gcc.dg/tree-ssa/vrp59.c: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 177423)
--- gcc/tree-vrp.c	(working copy)
*************** extract_range_from_binary_expr_1 (value_
*** 2214,2220 ****
        && code != MIN_EXPR
        && code != MAX_EXPR
        && code != BIT_AND_EXPR
!       && code != BIT_IOR_EXPR)
      {
        set_value_range_to_varying (vr);
        return;
--- 2214,2221 ----
        && code != MIN_EXPR
        && code != MAX_EXPR
        && code != BIT_AND_EXPR
!       && code != BIT_IOR_EXPR
!       && code != BIT_XOR_EXPR)
      {
        set_value_range_to_varying (vr);
        return;
*************** extract_range_from_binary_expr_1 (value_
*** 2635,2641 ****
        min = vrp_int_const_binop (code, vr0.min, vr1.max);
        max = vrp_int_const_binop (code, vr0.max, vr1.min);
      }
!   else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
      {
        bool int_cst_range0, int_cst_range1;
        double_int may_be_nonzero0, may_be_nonzero1;
--- 2636,2642 ----
        min = vrp_int_const_binop (code, vr0.min, vr1.max);
        max = vrp_int_const_binop (code, vr0.max, vr1.min);
      }
!   else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
      {
        bool int_cst_range0, int_cst_range1;
        double_int may_be_nonzero0, may_be_nonzero1;
*************** extract_range_from_binary_expr_1 (value_
*** 2694,2699 ****
--- 2695,2729 ----
  	  if (int_cst_range1)
  	    min = vrp_int_const_binop (MAX_EXPR, min, vr1.min);
  	}
+       else if (code == BIT_XOR_EXPR)
+ 	{
+ 	  double_int result_zero_bits, result_one_bits;
+ 	  result_zero_bits
+ 	    = double_int_ior (double_int_and (must_be_nonzero0,
+ 					      must_be_nonzero1),
+ 			      double_int_not
+ 			        (double_int_ior (may_be_nonzero0,
+ 						 may_be_nonzero1)));
+ 	  result_one_bits
+ 	    = double_int_ior (double_int_and
+ 			        (must_be_nonzero0,
+ 				 double_int_not (may_be_nonzero1)),
+ 			      double_int_and
+ 			        (must_be_nonzero1,
+ 				 double_int_not (may_be_nonzero0)));
+ 	  max = double_int_to_tree (expr_type,
+ 				    double_int_not (result_zero_bits));
+ 	  min = double_int_to_tree (expr_type, result_one_bits);
+ 	  /* Return a [min, max] range if we know the
+ 	     result range is either positive or negative.  */
+ 	  if (tree_int_cst_sgn (max) >= 0)
+ 	    /* The range is bound by a lower value of 0.  */;
+ 	  else if (tree_int_cst_sgn (min) < 0)
+ 	    /* The range is bound by an upper value of -1.  */;
+ 	  else
+ 	    /* We don't know whether the sign bit is set or not.  */
+ 	    max = min = NULL_TREE;
+ 	}
        else
  	{
  	  set_value_range_to_varying (vr);
Index: gcc/testsuite/gcc.dg/tree-ssa/vrp59.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/vrp59.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/vrp59.c	(revision 0)
***************
*** 0 ****
--- 1,35 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -fno-tree-ccp -fdump-tree-vrp1" } */
+ 
+ int f(int x)
+ {
+   if (x >= 0 && x <= 3)
+     {
+       x = x ^ 3;
+       x = x & 3;
+     }
+   return x;
+ }
+ 
+ int g(int x)
+ {
+   if (x >= 0 && x <= 3)
+     {
+       x = x ^ 2;
+       x = x & 3;
+     }
+   return x;
+ }
+ 
+ int h(int x)
+ {
+   if (x >= 0 && x <= 3)
+     {
+       x = x ^ 1;
+       x = x & 3;
+     }
+   return x;
+ }
+ 
+ /* { dg-final { scan-tree-dump-not " & 3;" "vrp1" } } */
+ /* { dg-final { cleanup-tree-dump "vrp1" } } */


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