This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR44831
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 8 Jul 2010 13:37:20 +0200 (CEST)
- Subject: [PATCH] Fix PR44831
This fixes PR44831, phiprop needs to be careful about embedded conversions
in MEM_REFs.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2010-07-08 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44831
* tree-ssa-phiprop.c (phiprop_insert_phi): Properly build
a MEM_REF preserving TBAA info of the original dereference.
Dereference the original pointer if the address is not
invariant.
(propagate_with_phi): Fixup type checks wrt MEM_REFs. Require
at least one invariant address that we are going to dereference.
* gcc.c-torture/compile/pr44831.c: New testcase.
* gcc.dg/tree-ssa/pr21463.c: Adjust.
Index: gcc/tree-ssa-phiprop.c
===================================================================
*** gcc/tree-ssa-phiprop.c (revision 161946)
--- gcc/tree-ssa-phiprop.c (working copy)
*************** phiprop_insert_phi (basic_block bb, gimp
*** 187,196 ****
}
else
{
gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
! old_arg = TREE_OPERAND (old_arg, 0);
! new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL);
! tmp = gimple_build_assign (new_var, unshare_expr (old_arg));
gcc_assert (is_gimple_reg (new_var));
add_referenced_var (new_var);
new_var = make_ssa_name (new_var, tmp);
--- 187,203 ----
}
else
{
+ tree rhs = gimple_assign_rhs1 (use_stmt);
gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
! new_var = create_tmp_reg (TREE_TYPE (rhs), NULL);
! if (!is_gimple_min_invariant (old_arg))
! old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
! else
! old_arg = unshare_expr (old_arg);
! tmp = gimple_build_assign (new_var,
! fold_build2 (MEM_REF, TREE_TYPE (rhs),
! old_arg,
! TREE_OPERAND (rhs, 1)));
gcc_assert (is_gimple_reg (new_var));
add_referenced_var (new_var);
new_var = make_ssa_name (new_var, tmp);
*************** propagate_with_phi (basic_block bb, gimp
*** 246,251 ****
--- 253,260 ----
use_operand_p arg_p, use;
ssa_op_iter i;
bool phi_inserted;
+ tree type = NULL_TREE;
+ bool one_invariant = false;
if (!POINTER_TYPE_P (TREE_TYPE (ptr))
|| !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
*************** propagate_with_phi (basic_block bb, gimp
*** 268,283 ****
return false;
arg = gimple_assign_rhs1 (def_stmt);
}
! if ((TREE_CODE (arg) != ADDR_EXPR
! /* Avoid to have to decay *&a to a[0] later. */
! || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0))))
&& !(TREE_CODE (arg) == SSA_NAME
&& SSA_NAME_VERSION (arg) < n
&& phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
&& phivn_valid_p (phivn, arg, bb)))
return false;
}
/* Find a dereferencing use. First follow (single use) ssa
copy chains for ptr. */
while (single_imm_use (ptr, &use, &use_stmt)
--- 277,305 ----
return false;
arg = gimple_assign_rhs1 (def_stmt);
}
! if (TREE_CODE (arg) != ADDR_EXPR
&& !(TREE_CODE (arg) == SSA_NAME
&& SSA_NAME_VERSION (arg) < n
&& phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
+ && (!type
+ || types_compatible_p
+ (type, TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value)))
&& phivn_valid_p (phivn, arg, bb)))
return false;
+ if (!type
+ && TREE_CODE (arg) == SSA_NAME)
+ type = TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value);
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && is_gimple_min_invariant (arg))
+ one_invariant = true;
}
+ /* If we neither have an address of a decl nor can reuse a previously
+ inserted load, do not hoist anything. */
+ if (!one_invariant
+ && !type)
+ return false;
+
/* Find a dereferencing use. First follow (single use) ssa
copy chains for ptr. */
while (single_imm_use (ptr, &use, &use_stmt)
*************** propagate_with_phi (basic_block bb, gimp
*** 298,305 ****
&& gimple_assign_rhs_code (use_stmt) == MEM_REF
&& TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
&& integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1))
! && types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
! TREE_TYPE (TREE_TYPE (ptr)))
/* We cannot replace a load that may throw or is volatile. */
&& !stmt_can_throw_internal (use_stmt)))
continue;
--- 320,328 ----
&& gimple_assign_rhs_code (use_stmt) == MEM_REF
&& TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
&& integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1))
! && (!type
! || types_compatible_p
! (TREE_TYPE (gimple_assign_lhs (use_stmt)), type))
/* We cannot replace a load that may throw or is volatile. */
&& !stmt_can_throw_internal (use_stmt)))
continue;
*************** propagate_with_phi (basic_block bb, gimp
*** 319,324 ****
--- 342,348 ----
if (!phi_inserted)
{
res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
+ type = TREE_TYPE (res);
/* Remember the value we created for *ptr. */
phivn[SSA_NAME_VERSION (ptr)].value = res;
Index: gcc/testsuite/gcc.c-torture/compile/pr44831.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr44831.c (revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr44831.c (revision 0)
***************
*** 0 ****
--- 1,15 ----
+ typedef unsigned char UCHAR, *PUCHAR;
+ typedef void *HANDLE;
+ typedef struct _NCB {
+ UCHAR ncb_reserve[10];
+ } NCB, *PNCB;
+ struct NBCmdQueue {
+ PNCB head;
+ };
+ PNCB *NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
+ {
+ PNCB *ret = &queue->head;
+ while (ret && *ret != ncb)
+ ret = (PNCB *)((*ret)->ncb_reserve + sizeof(HANDLE));
+ }
+
Index: gcc/testsuite/gcc.dg/tree-ssa/pr21463.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/pr21463.c (revision 161946)
--- gcc/testsuite/gcc.dg/tree-ssa/pr21463.c (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-phiprop" } */
struct f
{
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-phiprop-details" } */
struct f
{
*************** int g(int i, int c, struct f *ff, int g)
*** 16,20 ****
return *t;
}
! /* { dg-final { scan-tree-dump-not "\\*t" "phiprop" } } */
/* { dg-final { cleanup-tree-dump "phiprop" } } */
--- 16,20 ----
return *t;
}
! /* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1 "phiprop" } } */
/* { dg-final { cleanup-tree-dump "phiprop" } } */