This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix forwprop ICE
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 19 May 2009 13:46:26 +0200 (CEST)
- Subject: [PATCH] Fix forwprop ICE
This fixes an ICE that happens because forwprop deletes the definition
of an SSA name even though it is still used. The issue is that when
propagation into the LHS fails and into the RHS succeeds we may not
return true. The testcase makes this happen via a self-assignment
that on the rhs is converted to a V_C_E but not on the lhs.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk
and branch.
Richard.
2009-05-19 Richard Guenther <rguenther@suse.de>
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Do
not falsely claim to have propagated into all uses.
* gcc.c-torture/compile/20090519-1.c: New testcase.
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c (revision 147657)
--- gcc/tree-ssa-forwprop.c (working copy)
*************** forward_propagate_addr_expr_1 (tree name
*** 683,688 ****
--- 683,689 ----
tree *rhsp, *lhsp;
gimple use_stmt = gsi_stmt (*use_stmt_gsi);
enum tree_code rhs_code;
+ bool res = true;
gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
*************** forward_propagate_addr_expr_1 (tree name
*** 726,744 ****
/* Now see if the LHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (lhs) == INDIRECT_REF
! && TREE_OPERAND (lhs, 0) == name
! && may_propagate_address_into_dereference (def_rhs, lhs)
! && (lhsp != gimple_assign_lhs_ptr (use_stmt)
! || useless_type_conversion_p (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
! TREE_TYPE (rhs))))
{
! *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
! fold_stmt_inplace (use_stmt);
! tidy_after_forward_propagate_addr (use_stmt);
!
! /* Continue propagating into the RHS if this was not the only use. */
! if (single_use_p)
! return true;
}
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
--- 727,752 ----
/* Now see if the LHS node is an INDIRECT_REF using NAME. If so,
propagate the ADDR_EXPR into the use of NAME and fold the result. */
if (TREE_CODE (lhs) == INDIRECT_REF
! && TREE_OPERAND (lhs, 0) == name)
{
! if (may_propagate_address_into_dereference (def_rhs, lhs)
! && (lhsp != gimple_assign_lhs_ptr (use_stmt)
! || useless_type_conversion_p
! (TREE_TYPE (TREE_OPERAND (def_rhs, 0)), TREE_TYPE (rhs))))
! {
! *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
! fold_stmt_inplace (use_stmt);
! tidy_after_forward_propagate_addr (use_stmt);
!
! /* Continue propagating into the RHS if this was not the only use. */
! if (single_use_p)
! return true;
! }
! else
! /* We can have a struct assignment dereferencing our name twice.
! Note that we didn't propagate into the lhs to not falsely
! claim we did when propagating into the rhs. */
! res = false;
}
/* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
*************** forward_propagate_addr_expr_1 (tree name
*** 758,764 ****
*rhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
! return true;
}
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
--- 766,772 ----
*rhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
! return res;
}
/* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
*************** forward_propagate_addr_expr_1 (tree name
*** 789,795 ****
true, GSI_NEW_STMT);
gimple_assign_set_rhs1 (use_stmt, new_rhs);
tidy_after_forward_propagate_addr (use_stmt);
! return true;
}
/* If the defining rhs comes from an indirect reference, then do not
convert into a VIEW_CONVERT_EXPR. */
--- 797,803 ----
true, GSI_NEW_STMT);
gimple_assign_set_rhs1 (use_stmt, new_rhs);
tidy_after_forward_propagate_addr (use_stmt);
! return res;
}
/* If the defining rhs comes from an indirect reference, then do not
convert into a VIEW_CONVERT_EXPR. */
*************** forward_propagate_addr_expr_1 (tree name
*** 803,809 ****
*rhsp = new_rhs;
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
! return true;
}
}
--- 811,817 ----
*rhsp = new_rhs;
fold_stmt_inplace (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
! return res;
}
}
Index: gcc/testsuite/gcc.c-torture/compile/20090519-1.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/20090519-1.c (revision 0)
--- gcc/testsuite/gcc.c-torture/compile/20090519-1.c (revision 0)
***************
*** 0 ****
--- 1,11 ----
+ typedef struct { int licensed; } __pmPDUInfo;
+ void __pmDecodeXtendError (int *);
+ void do_handshake(void)
+ {
+ __pmPDUInfo *pduinfo;
+ int challenge;
+ __pmDecodeXtendError(&challenge);
+ pduinfo = (__pmPDUInfo *)&challenge;
+ *pduinfo = *pduinfo;
+ }
+