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] Fix missed VRP with unhandled operations


VRP doesn't do range propagation on all operations but instead of
falling back to varying in all cases it should at least do what CCP
does, namely constant folding if all operands are single valued
ranges and constants.  Noted while removing the last DOM pass.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
trunk.

Richard.

2008-08-20  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (op_with_constant_singleton_value_range): New function.
	(extract_range_from_binary_expr): Fall back to constant propagation.
	(extract_range_from_unary_expr): Likewise.

	* gcc.dg/tree-ssa/pr21829.c: Scan optimized and cddce2 dumps
	instead of phicprop2.  Make sure all is fine after cddce2,
	add an XFAILed scan for merging the two remaining ifs.

Index: gcc/testsuite/gcc.dg/tree-ssa/pr21829.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/pr21829.c	(revision 139287)
--- gcc/testsuite/gcc.dg/tree-ssa/pr21829.c	(working copy)
***************
*** 1,5 ****
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-phicprop-details" } */
  
  int test(int v)
  {
--- 1,5 ----
  /* { dg-do compile } */
! /* { dg-options "-O2 -fdump-tree-optimized -fdump-tree-cddce2" } */
  
  int test(int v)
  {
*************** int test(int v)
*** 16,21 ****
    return x;
  }
  
! /* { dg-final { scan-tree-dump-times "Original statement:.*% 2\[ \t\n]*Updated statement.*=1" 0 "phicprop2" } } */
! /* { dg-final { cleanup-tree-dump "phicprop\[1-2\]" } } */
  
--- 16,48 ----
    return x;
  }
  
! /* This should be optimized to
  
+     if (v <= 0) goto <L1>; else goto <L3>;
+ 
+    <L1>:;
+ 
+     # x_1 = PHI <0(3), 1(1)>;
+    <L3>:;
+     return x_1;
+ 
+    retaining only a single conditional.  This doesn't work as nobody
+    combines the two tests
+ 
+     if (v < 0) goto <bb 4>; else goto <bb 3>;
+ 
+    <bb 3>:
+ 
+     if (v <= 0) goto <bb 4>; else goto <bb 5>;
+ 
+    this late in the game.  tree-ssa-ifcombine.c would do it if we would
+    unroll the loop during early loop unrolling though.
+ 
+    For now vrp2 does all the needed folding and threading and cddce2
+    provides a nice IL to scan.  */
+ 
+ /* { dg-final { scan-tree-dump-times "if " 1 "optimized" { xfail *-*-* } } } */
+ /* { dg-final { scan-tree-dump-times "if " 2 "cddce2" } } */
+ /* { dg-final { scan-tree-dump "x_. = PHI <0\\\(.\\\), 1\\\(.\\\)>" "cddce2" } } */
+ /* { dg-final { cleanup-tree-dump "cddce2" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 139287)
--- gcc/tree-vrp.c	(working copy)
*************** ssa_name_nonzero_p (const_tree t)
*** 1353,1358 ****
--- 1353,1382 ----
    return false;
  }
  
+ /* If OP has a value range with a single constant value return that,
+    otherwise return NULL_TREE.  This returns OP itself if OP is a
+    constant.  */
+ 
+ static tree
+ op_with_constant_singleton_value_range (tree op)
+ {
+   value_range_t *vr;
+ 
+   if (is_gimple_min_invariant (op))
+     return op;
+ 
+   if (TREE_CODE (op) != SSA_NAME)
+     return NULL_TREE;
+ 
+   vr = get_value_range (op);
+   if (vr->type == VR_RANGE
+       && operand_equal_p (vr->min, vr->max, 0)
+       && is_gimple_min_invariant (vr->min))
+     return vr->min;
+ 
+   return NULL_TREE;
+ }
+ 
  
  /* Extract value range information from an ASSERT_EXPR EXPR and store
     it in *VR_P.  */
*************** extract_range_from_binary_expr (value_ra
*** 2033,2038 ****
--- 2057,2074 ----
        && code != TRUTH_AND_EXPR
        && code != TRUTH_OR_EXPR)
      {
+       /* We can still do constant propagation here.  */
+       if ((op0 = op_with_constant_singleton_value_range (op0)) != NULL_TREE
+ 	  && (op1 = op_with_constant_singleton_value_range (op1)) != NULL_TREE)
+ 	{
+ 	  tree tem = fold_binary (code, expr_type, op0, op1);
+ 	  if (is_gimple_min_invariant (tem)
+ 	      && !is_overflow_infinity (tem))
+ 	    {
+ 	      set_value_range (vr, VR_RANGE, tem, tem, NULL);
+ 	      return;
+ 	    }
+ 	}
        set_value_range_to_varying (vr);
        return;
      }
*************** extract_range_from_unary_expr (value_ran
*** 2437,2442 ****
--- 2473,2489 ----
        || code == BIT_NOT_EXPR
        || code == CONJ_EXPR)
      {
+       /* We can still do constant propagation here.  */
+       if ((op0 = op_with_constant_singleton_value_range (op0)) != NULL_TREE)
+ 	{
+ 	  tree tem = fold_unary (code, type, op0);
+ 	  if (is_gimple_min_invariant (tem)
+ 	      && !is_overflow_infinity (tem))
+ 	    {
+ 	      set_value_range (vr, VR_RANGE, tem, tem, NULL);
+ 	      return;
+ 	    }
+ 	}
        set_value_range_to_varying (vr);
        return;
      }


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