[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