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 PR80887


The following limits the number of mprts_hook invocations from a single
simplification in SCCVN to avoid endless recursion.

I thought a GIMPLE testcase is in order here and thus extended
parsing to handle a_10 + -1 aka a_10 + _Literal (int) -1.  I did
so in a straight-forward way rather than simply do constexpr like
simplification of the operand after _Literal (type) which in the
end is going to be necessary for things like
_Literal (v4si) { 1, 2, 3, 4 }.  Well - one thing at a time.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

Richard.

2017-06-19  Richard Biener  <rguenther@suse.de>

	c/
	* gimple-parser.c (c_parser_gimple_postfix_expression): Handle
	negated _Literals to parse _Literal (int) -1.
	* tree-ssa-sccvn.c (mprts_hook_cnt): New global.
	(vn_lookup_simplify_result): Allow only mprts_hook_cnt succesful
	simplified lookups, then reset mprts_hook.
	(vn_nary_build_or_lookup_1): Set mprts_hook_cnt to 9 before
	simplifying.
	(try_to_simplify): Likewise.

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

Index: gcc/c/gimple-parser.c
===================================================================
*** gcc/c/gimple-parser.c	(revision 249358)
--- gcc/c/gimple-parser.c	(working copy)
*************** c_parser_gimple_postfix_expression (c_pa
*** 850,856 ****
  	    }
  	  else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
  	    {
! 	      /* _Literal '(' type-name ')' number  */
  	      c_parser_consume_token (parser);
  	      tree type = NULL_TREE;
  	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
--- 850,856 ----
  	    }
  	  else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
  	    {
! 	      /* _Literal '(' type-name ')' [ '-' ] constant */
  	      c_parser_consume_token (parser);
  	      tree type = NULL_TREE;
  	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
*************** c_parser_gimple_postfix_expression (c_pa
*** 862,876 ****
  		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
  					     "expected %<)%>");
  		}
  	      tree val = c_parser_gimple_postfix_expression (parser).value;
  	      if (! type
  		  || ! val
  		  || val == error_mark_node
! 		  || TREE_CODE (val) != INTEGER_CST)
  		{
  		  c_parser_error (parser, "invalid _Literal");
  		  return expr;
  		}
  	      expr.value = fold_convert (type, val);
  	      return expr;
  	    }
--- 862,888 ----
  		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
  					     "expected %<)%>");
  		}
+ 	      bool neg_p;
+ 	      if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS)))
+ 		c_parser_consume_token (parser);
  	      tree val = c_parser_gimple_postfix_expression (parser).value;
  	      if (! type
  		  || ! val
  		  || val == error_mark_node
! 		  || ! CONSTANT_CLASS_P (val))
  		{
  		  c_parser_error (parser, "invalid _Literal");
  		  return expr;
  		}
+ 	      if (neg_p)
+ 		{
+ 		  val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val);
+ 		  if (! val)
+ 		    {
+ 		      c_parser_error (parser, "invalid _Literal");
+ 		      return expr;
+ 		    }
+ 		}
  	      expr.value = fold_convert (type, val);
  	      return expr;
  	    }
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 249358)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** vn_reference_lookup_or_insert_for_pieces
*** 1639,1644 ****
--- 1639,1645 ----
  }
  
  static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result);
+ static unsigned mprts_hook_cnt;
  
  /* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables.  */
  
*************** vn_lookup_simplify_result (code_helper r
*** 1648,1655 ****
    if (!rcode.is_tree_code ())
      return NULL_TREE;
    vn_nary_op_t vnresult = NULL;
!   return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
! 				   (tree_code) rcode, type, ops, &vnresult);
  }
  
  /* Return a value-number for RCODE OPS... either by looking up an existing
--- 1649,1670 ----
    if (!rcode.is_tree_code ())
      return NULL_TREE;
    vn_nary_op_t vnresult = NULL;
!   tree res = vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
! 				       (tree_code) rcode, type, ops, &vnresult);
!   /* We can end up endlessly recursing simplifications if the lookup above
!      presents us with a def-use chain that mirrors the original simplification.
!      See PR80887 for an example.  Limit successful lookup artificially
!      to 10 times if we are called as mprts_hook.  */
!   if (res
!       && mprts_hook
!       && --mprts_hook_cnt == 0)
!     {
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	fprintf (dump_file, "Resetting mprts_hook after too many "
! 		 "invocations.\n");
!       mprts_hook = NULL;
!     }
!   return res;
  }
  
  /* Return a value-number for RCODE OPS... either by looking up an existing
*************** vn_nary_build_or_lookup_1 (code_helper r
*** 1666,1671 ****
--- 1681,1687 ----
       So first simplify and lookup this expression to see if it
       is already available.  */
    mprts_hook = vn_lookup_simplify_result;
+   mprts_hook_cnt = 9;
    bool res = false;
    switch (TREE_CODE_LENGTH ((tree_code) rcode))
      {
*************** try_to_simplify (gassign *stmt)
*** 3896,3901 ****
--- 3912,3918 ----
  
    /* First try constant folding based on our current lattice.  */
    mprts_hook = vn_lookup_simplify_result;
+   mprts_hook_cnt = 9;
    tem = gimple_fold_stmt_to_constant_1 (stmt, vn_valueize, vn_valueize);
    mprts_hook = NULL;
    if (tem
Index: gcc/testsuite/gcc.dg/tree-ssa/pr80887.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/pr80887.c	(nonexistent)
--- gcc/testsuite/gcc.dg/tree-ssa/pr80887.c	(working copy)
***************
*** 0 ****
--- 1,32 ----
+ /* { dg-do compile } */
+ /* { dg-options "-fgimple -O" } */
+ 
+ int pos;
+ void __GIMPLE (startwith("fre"))
+ f()
+ {
+   unsigned int t2;
+   unsigned int t1;
+   int a;
+   unsigned int u;
+   int _1;
+   int _2;
+   int _3;
+   unsigned int _4;
+   int _5;
+   unsigned int _6;
+ 
+ bb_2:
+   _1 = pos;
+   _2 = _1 + 1;
+   pos = _2;
+   _3 = pos;
+   _4 = (unsigned int) _3;
+   u_9 = _4 + 4294967295u;
+   a_10 = pos;
+   _5 = a_10 + _Literal (int) -1;
+   t1_11 = (unsigned int) _5;
+   _6 = (unsigned int) a_10;
+   t2_12 = _6 + 4294967294u;
+   return;
+ }


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