This fixes PR57685 - exponential behavior in VRP assert expression
insertion.  The fix below cuts off in the simplest possible way.

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

Richard.

2013-08-28  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/57685
        * tree-vrp.c (register_edge_assert_for_1): Recurse only for
        single-use operands to avoid exponential complexity.

        * gcc.dg/torture/pr57685.c: New testcase.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c      (revision 202050)
--- gcc/tree-vrp.c      (working copy)
*************** register_edge_assert_for_1 (tree op, enu
*** 5410,5419 ****
               && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
      {
        /* Recurse on each operand.  */
!       retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
!                                           code, e, bsi);
!       retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
!                                           code, e, bsi);
      }
    else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
           && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
--- 5410,5423 ----
               && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
      {
        /* Recurse on each operand.  */
!       tree op0 = gimple_assign_rhs1 (op_def);
!       tree op1 = gimple_assign_rhs2 (op_def);
!       if (TREE_CODE (op0) == SSA_NAME
!         && has_single_use (op0))
!       retval |= register_edge_assert_for_1 (op0, code, e, bsi);
!       if (TREE_CODE (op1) == SSA_NAME
!         && has_single_use (op1))
!       retval |= register_edge_assert_for_1 (op1, code, e, bsi);
      }
    else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
           && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
Index: gcc/testsuite/gcc.dg/torture/pr57685.c
===================================================================
*** gcc/testsuite/gcc.dg/torture/pr57685.c      (revision 0)
--- gcc/testsuite/gcc.dg/torture/pr57685.c      (working copy)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ 
+ unsigned f(void)
+ {
+   unsigned a;
+   int b, c, d, e;
+ 
+   for(c = 27; c < 40; c++)
+     b |= d |= b;
+ 
+   if(b)
+     a = e;
+ 
+   return a;
+ }

Reply via email to