[PATCH] Fix PR67889

Richard Biener rguenther@suse.de
Fri Oct 9 08:11:00 GMT 2015


This fixes PR67889.

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

Richard.

2015-10-09  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/67891
	* gimple-match.h (gimple_simplified_result_is_gimple_val):
	New helper.
	(gimple_resimplify1): Declare.
	(gimple_resimplify2): Likewise.
	(gimple_resimplify3): Likewise.
	* gimple-match-head.c (gimple_resimplify1): Export.
	(gimple_resimplify2): Likewise.
	(gimple_resimplify3): Likewise.
	(maybe_push_res_to_seq): Use gimple_simplified_result_is_gimple_val.
	* gimple-fold.c (gimple_fold_stmt_to_constant_1): Likewise.
	* tree-ssa-sccvn.c (visit_reference_op_load): Use gimple_resimplify1
	to avoid creating stmts without VN info.

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

Index: gcc/gimple-match.h
===================================================================
*** gcc/gimple-match.h	(revision 228594)
--- gcc/gimple-match.h	(working copy)
*************** private:
*** 40,49 ****
--- 40,67 ----
    int rep;
  };
  
+ /* Return whether OPS[0] with CODE is a non-expression result and
+    a gimple value.  */
+ 
+ inline bool
+ gimple_simplified_result_is_gimple_val (code_helper code, tree *ops)
+ {
+   return (code.is_tree_code ()
+ 	  && (TREE_CODE_LENGTH ((tree_code) code) == 0
+ 	      || ((tree_code) code) == ADDR_EXPR)
+ 	  && is_gimple_val (ops[0]));
+ }
+ 
  extern tree (*mprts_hook) (code_helper, tree, tree *);
  
  bool gimple_simplify (gimple *, code_helper *, tree *, gimple_seq *,
  		      tree (*)(tree), tree (*)(tree));
+ bool gimple_resimplify1 (gimple_seq *, code_helper *, tree, tree *,
+ 			 tree (*)(tree));
+ bool gimple_resimplify2 (gimple_seq *, code_helper *, tree, tree *,
+ 			 tree (*)(tree));
+ bool gimple_resimplify3 (gimple_seq *, code_helper *, tree, tree *,
+ 			 tree (*)(tree));
  tree maybe_push_res_to_seq (code_helper, tree, tree *,
  			    gimple_seq *, tree res = NULL_TREE);
  void maybe_build_generic_op (enum tree_code, tree, tree *, tree, tree);
Index: gcc/gimple-match-head.c
===================================================================
*** gcc/gimple-match-head.c	(revision 228594)
--- gcc/gimple-match-head.c	(working copy)
*************** constant_for_folding (tree t)
*** 83,89 ****
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! static bool
  gimple_resimplify1 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
--- 83,89 ----
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! bool
  gimple_resimplify1 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
*************** gimple_resimplify1 (gimple_seq *seq,
*** 139,145 ****
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! static bool
  gimple_resimplify2 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
--- 139,145 ----
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! bool
  gimple_resimplify2 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
*************** gimple_resimplify2 (gimple_seq *seq,
*** 208,214 ****
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! static bool
  gimple_resimplify3 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
--- 208,214 ----
     *RES_CODE and *RES_OPS with a simplified and/or canonicalized
     result and returns whether any change was made.  */
  
! bool
  gimple_resimplify3 (gimple_seq *seq,
  		    code_helper *res_code, tree type, tree *res_ops,
  		    tree (*valueize)(tree))
*************** maybe_push_res_to_seq (code_helper rcode
*** 308,316 ****
    if (rcode.is_tree_code ())
      {
        if (!res
! 	  && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
! 	      || ((tree_code) rcode) == ADDR_EXPR)
! 	  && is_gimple_val (ops[0]))
  	return ops[0];
        if (mprts_hook)
  	{
--- 308,314 ----
    if (rcode.is_tree_code ())
      {
        if (!res
! 	  && gimple_simplified_result_is_gimple_val (rcode, ops))
  	return ops[0];
        if (mprts_hook)
  	{
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c	(revision 228594)
--- gcc/gimple-fold.c	(working copy)
*************** gimple_fold_stmt_to_constant_1 (gimple *
*** 4926,4935 ****
    if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize))
      {
        tree res = NULL_TREE;
!       if (rcode.is_tree_code ()
! 	  && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
! 	      || ((tree_code) rcode) == ADDR_EXPR)
! 	  && is_gimple_val (ops[0]))
  	res = ops[0];
        else if (mprts_hook)
  	res = mprts_hook (rcode, gimple_expr_type (stmt), ops);
--- 4932,4938 ----
    if (gimple_simplify (stmt, &rcode, ops, NULL, gvalueize, valueize))
      {
        tree res = NULL_TREE;
!       if (gimple_simplified_result_is_gimple_val (rcode, ops))
  	res = ops[0];
        else if (mprts_hook)
  	res = mprts_hook (rcode, gimple_expr_type (stmt), ops);
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c	(revision 228594)
--- gcc/tree-ssa-sccvn.c	(working copy)
*************** visit_reference_op_load (tree lhs, tree
*** 3043,3080 ****
  	 of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
  	 So first simplify and lookup this expression to see if it
  	 is already available.  */
-       gimple_seq stmts = NULL;
        mprts_hook = vn_lookup_simplify_result;
!       tree val = gimple_simplify (VIEW_CONVERT_EXPR, TREE_TYPE (op),
! 				  result, &stmts, vn_valueize);
        mprts_hook = NULL;
!       if (!val)
  	{
! 	  val = vn_nary_op_lookup_pieces (1, VIEW_CONVERT_EXPR,
! 					  TREE_TYPE (op), &result, NULL);
  	  if (!val)
  	    {
! 	      val = make_ssa_name (TREE_TYPE (op));
! 	      gimple *new_stmt = gimple_build_assign (val, VIEW_CONVERT_EXPR,
! 						      build1 (VIEW_CONVERT_EXPR,
! 							      TREE_TYPE (op),
! 							      result));
! 	      gimple_seq_add_stmt_without_update (&stmts, new_stmt);
  	    }
  	}
!       if (gimple_seq_empty_p (stmts))
! 	/* The expression is already available.  */
! 	result = val;
!       else
  	{
- 	  gcc_assert (gimple_seq_singleton_p (stmts));
  	  /* The expression is not yet available, value-number lhs to
  	     the new SSA_NAME we created.  */
- 	  result = val;
  	  /* Initialize value-number information properly.  */
  	  VN_INFO_GET (result)->valnum = result;
  	  VN_INFO (result)->value_id = get_next_value_id ();
! 	  VN_INFO (result)->expr = stmts;
  	  VN_INFO (result)->needs_insertion = true;
  	  /* As all "inserted" statements are singleton SCCs, insert
  	     to the valid table.  This is strictly needed to
--- 3089,3129 ----
  	 of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
  	 So first simplify and lookup this expression to see if it
  	 is already available.  */
        mprts_hook = vn_lookup_simplify_result;
!       code_helper rcode = VIEW_CONVERT_EXPR;
!       tree ops[3] = { result };
!       bool res = gimple_resimplify1 (NULL, &rcode, TREE_TYPE (op), ops,
! 				     vn_valueize);
        mprts_hook = NULL;
!       gimple *new_stmt = NULL;
!       if (res
! 	  && gimple_simplified_result_is_gimple_val (rcode, ops))
! 	/* The expression is already available.  */
! 	result = ops[0];
!       else
  	{
! 	  tree val = vn_lookup_simplify_result (rcode, TREE_TYPE (op), ops);
  	  if (!val)
  	    {
! 	      gimple_seq stmts = NULL;
! 	      result = maybe_push_res_to_seq (rcode, TREE_TYPE (op), ops,
! 					      &stmts);
! 	      gcc_assert (result && gimple_seq_singleton_p (stmts));
! 	      new_stmt = gimple_seq_first_stmt (stmts);
  	    }
+ 	  else
+ 	    /* The expression is already available.  */
+ 	    result = val;
  	}
!       if (new_stmt)
  	{
  	  /* The expression is not yet available, value-number lhs to
  	     the new SSA_NAME we created.  */
  	  /* Initialize value-number information properly.  */
  	  VN_INFO_GET (result)->valnum = result;
  	  VN_INFO (result)->value_id = get_next_value_id ();
! 	  gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
! 					      new_stmt);
  	  VN_INFO (result)->needs_insertion = true;
  	  /* As all "inserted" statements are singleton SCCs, insert
  	     to the valid table.  This is strictly needed to
*************** visit_reference_op_load (tree lhs, tree
*** 3086,3103 ****
  	  if (current_info == optimistic_info)
  	    {
  	      current_info = valid_info;
! 	      vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
  	      current_info = optimistic_info;
  	    }
  	  else
! 	    vn_nary_op_insert_stmt (gimple_seq_first_stmt (stmts), result);
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
  	      fprintf (dump_file, "Inserting name ");
  	      print_generic_expr (dump_file, result, 0);
  	      fprintf (dump_file, " for expression ");
! 	      print_gimple_expr (dump_file, gimple_seq_first_stmt (stmts),
! 				 0, TDF_SLIM);
  	      fprintf (dump_file, "\n");
  	    }
  	}
--- 3135,3151 ----
  	  if (current_info == optimistic_info)
  	    {
  	      current_info = valid_info;
! 	      vn_nary_op_insert_stmt (new_stmt, result);
  	      current_info = optimistic_info;
  	    }
  	  else
! 	    vn_nary_op_insert_stmt (new_stmt, result);
  	  if (dump_file && (dump_flags & TDF_DETAILS))
  	    {
  	      fprintf (dump_file, "Inserting name ");
  	      print_generic_expr (dump_file, result, 0);
  	      fprintf (dump_file, " for expression ");
! 	      print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
  	      fprintf (dump_file, "\n");
  	    }
  	}
Index: gcc/testsuite/gcc.dg/tree-ssa/pr67891.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/pr67891.c	(revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/pr67891.c	(working copy)
***************
*** 0 ****
--- 1,17 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-fre1" } */
+ 
+ unsigned int a, *b;
+ unsigned short c;
+ int d;
+ 
+ void 
+ fn1 ()
+ {
+   b = &d;
+   *b = c = a; 
+   *b = d;
+ }
+ 
+ /* We should remove all loads but that from a.  */
+ /* { dg-final { scan-tree-dump-not "= \[dbc\];" "fre1" } } */



More information about the Gcc-patches mailing list