This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][mem-ref2] Recover array-refs during inlining
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Jun 2010 15:19:59 +0200 (CEST)
- Subject: [PATCH][mem-ref2] Recover array-refs during inlining
This fixes the last warning regression. I'm not 100% sure we want
to do this (we don't do it during forwprop either).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2010-06-22 Richard Guenther <rguenther@suse.de>
* gimple.h (maybe_fold_offset_to_reference): Re-export.
* gimple-fold.c (maybe_fold_offset_to_reference): Re-export.
Use types_compatible_p for type comparison.
* tree-inline.c (remap_gimple_op_r): Try to recover array-refs.
testsuite/
* gcc.dg/pr36902.c: Adjust.
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h (revision 161081)
--- gcc/gimple.h (working copy)
*************** tree gimple_fold_builtin (gimple);
*** 4806,4811 ****
--- 4806,4813 ----
bool fold_stmt (gimple_stmt_iterator *);
bool fold_stmt_inplace (gimple);
tree maybe_fold_offset_to_address (location_t, tree, tree, tree);
+ tree maybe_fold_offset_to_reference (location_t, tree, tree, tree);
+
tree maybe_fold_stmt_addition (location_t, tree, tree, tree);
tree get_symbol_constant_value (tree);
bool may_propagate_address_into_dereference (tree, tree);
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c (revision 161081)
--- gcc/gimple-fold.c (working copy)
*************** maybe_fold_offset_to_array_ref (location
*** 244,250 ****
Before attempting the conversion strip off existing ADDR_EXPRs. */
! static tree
maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
tree orig_type)
{
--- 244,250 ----
Before attempting the conversion strip off existing ADDR_EXPRs. */
! tree
maybe_fold_offset_to_reference (location_t loc, tree base, tree offset,
tree orig_type)
{
*************** maybe_fold_offset_to_reference (location
*** 255,266 ****
return NULL_TREE;
base = TREE_OPERAND (base, 0);
! if (useless_type_conversion_p (orig_type, TREE_TYPE (base))
&& integer_zerop (offset))
return base;
ret = maybe_fold_offset_to_array_ref (loc, base, offset);
! if (ret && useless_type_conversion_p (orig_type, TREE_TYPE (ret)))
return ret;
return NULL_TREE;
}
--- 255,266 ----
return NULL_TREE;
base = TREE_OPERAND (base, 0);
! if (types_compatible_p (orig_type, TREE_TYPE (base))
&& integer_zerop (offset))
return base;
ret = maybe_fold_offset_to_array_ref (loc, base, offset);
! if (ret && types_compatible_p (orig_type, TREE_TYPE (ret)))
return ret;
return NULL_TREE;
}
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c (revision 161081)
--- gcc/tree-inline.c (working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 821,829 ****
if (n)
{
tree old = *tp;
! *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! unshare_expr (*n), TREE_OPERAND (*tp, 1));
! TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
*walk_subtrees = 0;
return NULL;
--- 821,857 ----
if (n)
{
tree old = *tp;
! tree ptr = unshare_expr (*n);
! tree tem;
! if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp),
! ptr,
! TREE_OPERAND (*tp, 1),
! TREE_TYPE (*tp)))
! && TREE_THIS_VOLATILE (tem) == TREE_THIS_VOLATILE (old))
! {
! tree *tem_basep = &tem;
! while (handled_component_p (*tem_basep))
! tem_basep = &TREE_OPERAND (*tem_basep, 0);
! if (TREE_CODE (*tem_basep) == MEM_REF)
! *tem_basep
! = build2 (MEM_REF, TREE_TYPE (*tem_basep),
! TREE_OPERAND (*tem_basep, 0),
! fold_convert (TREE_TYPE (TREE_OPERAND (*tp, 1)),
! TREE_OPERAND (*tem_basep, 1)));
! else
! *tem_basep
! = build2 (MEM_REF, TREE_TYPE (*tem_basep),
! build_fold_addr_expr (*tem_basep),
! build_int_cst
! (TREE_TYPE (TREE_OPERAND (*tp, 1)), 0));
! *tp = tem;
! }
! else
! {
! *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp),
! ptr, TREE_OPERAND (*tp, 1));
! TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
! }
TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
*walk_subtrees = 0;
return NULL;
Index: gcc/testsuite/gcc.dg/pr36902.c
===================================================================
*** gcc/testsuite/gcc.dg/pr36902.c (revision 161081)
--- gcc/testsuite/gcc.dg/pr36902.c (working copy)
*************** foo2(unsigned char * to, const unsigned
*** 44,50 ****
*to = *from;
break;
case 5:
! to[4] = from [4]; /* { dg-warning "20:array subscript is above array bounds" } */
break;
}
return to;
--- 44,50 ----
*to = *from;
break;
case 5:
! to[4] = from [4]; /* { dg-warning "array subscript is above array bounds" } */
break;
}
return to;