Commit 315f5f1b by Richard Guenther Committed by Richard Biener

re PR tree-optimization/48571 (Missed data-dependence for (bogus?) reconstructed array-refs)

2011-08-30  Richard Guenther  <rguenther@suse.de>

	PR middle-end/48571
	* gimple.h (maybe_fold_offset_to_address): Remove.
	(maybe_fold_offset_to_reference): Likewise.
	(maybe_fold_stmt_addition): Likewise.
	(may_propagate_address_into_dereference): Likewise.
	* tree-inline.c (remap_gimple_op_r): Do not reconstruct
	array references.
	* gimple-fold.c (canonicalize_constructor_val): Likewise.
	Canonicalize invariant POINTER_PLUS_EXPRs to invariant MEM_REF
	addresses instead.
	(may_propagate_address_into_dereference): Remove.
	(maybe_fold_offset_to_array_ref): Likewise.
	(maybe_fold_offset_to_reference): Likewise.
	(maybe_fold_offset_to_address): Likewise.
	(maybe_fold_stmt_addition): Likewise.
	(fold_gimple_assign): Do not reconstruct array references but
	instead canonicalize invariant POINTER_PLUS_EXPRs to invariant
	MEM_REF addresses.
	(gimple_fold_stmt_to_constant_1): Likewise.
	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Likewise.
	* gimplify.c (gimplify_conversion): Likewise.
	(gimplify_expr): Likewise.

	* gcc.c-torture/execute/pr48571-1.c: New testcase.
	* gcc.dg/tree-ssa/ssa-ccp-25.c: Remove.
	* gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise.
	* gcc.dg/pr36902.c: XFAIL.

From-SVN: r178312
parent 2ddd46d6
2011-08-30 Richard Guenther <rguenther@suse.de>
PR middle-end/48571
* gimple.h (maybe_fold_offset_to_address): Remove.
(maybe_fold_offset_to_reference): Likewise.
(maybe_fold_stmt_addition): Likewise.
(may_propagate_address_into_dereference): Likewise.
* tree-inline.c (remap_gimple_op_r): Do not reconstruct
array references.
* gimple-fold.c (canonicalize_constructor_val): Likewise.
Canonicalize invariant POINTER_PLUS_EXPRs to invariant MEM_REF
addresses instead.
(may_propagate_address_into_dereference): Remove.
(maybe_fold_offset_to_array_ref): Likewise.
(maybe_fold_offset_to_reference): Likewise.
(maybe_fold_offset_to_address): Likewise.
(maybe_fold_stmt_addition): Likewise.
(fold_gimple_assign): Do not reconstruct array references but
instead canonicalize invariant POINTER_PLUS_EXPRs to invariant
MEM_REF addresses.
(gimple_fold_stmt_to_constant_1): Likewise.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Likewise.
* gimplify.c (gimplify_conversion): Likewise.
(gimplify_expr): Likewise.
2011-08-30 Ilya Tocar <ilya.tocar@intel.com> 2011-08-30 Ilya Tocar <ilya.tocar@intel.com>
* config/i386/fmaintrin.h: New. * config/i386/fmaintrin.h: New.
...@@ -5069,12 +5069,8 @@ void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree); ...@@ -5069,12 +5069,8 @@ void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree);
tree gimple_fold_builtin (gimple); tree gimple_fold_builtin (gimple);
bool fold_stmt (gimple_stmt_iterator *); bool fold_stmt (gimple_stmt_iterator *);
bool fold_stmt_inplace (gimple); 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); tree get_symbol_constant_value (tree);
tree canonicalize_constructor_val (tree); tree canonicalize_constructor_val (tree);
bool may_propagate_address_into_dereference (tree, tree);
extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree, extern tree maybe_fold_and_comparisons (enum tree_code, tree, tree,
enum tree_code, tree, tree); enum tree_code, tree, tree);
extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree, extern tree maybe_fold_or_comparisons (enum tree_code, tree, tree,
......
...@@ -1799,7 +1799,6 @@ canonicalize_addr_expr (tree *expr_p) ...@@ -1799,7 +1799,6 @@ canonicalize_addr_expr (tree *expr_p)
static enum gimplify_status static enum gimplify_status
gimplify_conversion (tree *expr_p) gimplify_conversion (tree *expr_p)
{ {
tree tem;
location_t loc = EXPR_LOCATION (*expr_p); location_t loc = EXPR_LOCATION (*expr_p);
gcc_assert (CONVERT_EXPR_P (*expr_p)); gcc_assert (CONVERT_EXPR_P (*expr_p));
...@@ -1810,17 +1809,6 @@ gimplify_conversion (tree *expr_p) ...@@ -1810,17 +1809,6 @@ gimplify_conversion (tree *expr_p)
if (tree_ssa_useless_type_conversion (*expr_p)) if (tree_ssa_useless_type_conversion (*expr_p))
*expr_p = TREE_OPERAND (*expr_p, 0); *expr_p = TREE_OPERAND (*expr_p, 0);
/* Attempt to avoid NOP_EXPR by producing reference to a subtype.
For example this fold (subclass *)&A into &A->subclass avoiding
a need for statement. */
if (CONVERT_EXPR_P (*expr_p)
&& POINTER_TYPE_P (TREE_TYPE (*expr_p))
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (*expr_p, 0)))
&& (tem = maybe_fold_offset_to_address
(EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
integer_zero_node, TREE_TYPE (*expr_p))) != NULL_TREE)
*expr_p = tem;
/* If we still have a conversion at the toplevel, /* If we still have a conversion at the toplevel,
then canonicalize some constructs. */ then canonicalize some constructs. */
if (CONVERT_EXPR_P (*expr_p)) if (CONVERT_EXPR_P (*expr_p))
...@@ -7302,36 +7290,33 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, ...@@ -7302,36 +7290,33 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
goto expr_3; goto expr_3;
case POINTER_PLUS_EXPR: case POINTER_PLUS_EXPR:
/* Convert ((type *)A)+offset into &A->field_of_type_and_offset. {
The second is gimple immediate saving a need for extra statement. enum gimplify_status r0, r1;
*/ r0 = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p,
if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST post_p, is_gimple_val, fb_rvalue);
&& (tmp = maybe_fold_offset_to_address r1 = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p,
(EXPR_LOCATION (*expr_p), post_p, is_gimple_val, fb_rvalue);
TREE_OPERAND (*expr_p, 0), TREE_OPERAND (*expr_p, 1), recalculate_side_effects (*expr_p);
TREE_TYPE (*expr_p)))) ret = MIN (r0, r1);
{ /* Convert &X + CST to invariant &MEM[&X, CST]. Do this
*expr_p = tmp; after gimplifying operands - this is similar to how
ret = GS_OK; it would be folding all gimplified stmts on creation
break; to have them canonicalized, which is what we eventually
} should do anyway. */
/* Convert (void *)&a + 4 into (void *)&a[1]. */ if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST
if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == NOP_EXPR && is_gimple_min_invariant (TREE_OPERAND (*expr_p, 0)))
&& TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST {
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, *expr_p = build_fold_addr_expr_with_type_loc
0),0))) (input_location,
&& (tmp = maybe_fold_offset_to_address fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (*expr_p)),
(EXPR_LOCATION (*expr_p), TREE_OPERAND (*expr_p, 0),
TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 0), fold_convert (ptr_type_node,
TREE_OPERAND (*expr_p, 1), TREE_OPERAND (*expr_p, 1))),
TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0), TREE_TYPE (*expr_p));
0))))) ret = MIN (ret, GS_OK);
{ }
*expr_p = fold_convert (TREE_TYPE (*expr_p), tmp); break;
ret = GS_OK; }
break;
}
/* FALLTHRU */
default: default:
switch (TREE_CODE_CLASS (TREE_CODE (*expr_p))) switch (TREE_CODE_CLASS (TREE_CODE (*expr_p)))
......
2011-08-30 Richard Guenther <rguenther@suse.de>
PR middle-end/48571
* gcc.c-torture/execute/pr48571-1.c: New testcase.
* gcc.dg/tree-ssa/ssa-ccp-25.c: Remove.
* gcc.dg/tree-ssa/ssa-ccp-26.c: Likewise.
* gcc.dg/pr36902.c: XFAIL.
2011-08-30 Ilya Tocar <ilya.tocar@intel.com> 2011-08-30 Ilya Tocar <ilya.tocar@intel.com>
* gcc.target/i386/fma-check.h: New. * gcc.target/i386/fma-check.h: New.
......
unsigned int c[624];
void __attribute__((noinline))
bar (void)
{
unsigned int i;
/* Obfuscated c[i] = c[i-1] * 2. */
for (i = 1; i < 624; ++i)
*(unsigned int *)((void *)c + (__SIZE_TYPE__)i * 4)
= 2 * *(unsigned int *)((void *)c + ((__SIZE_TYPE__)i +
((__SIZE_TYPE__)-4)/4) * 4);
}
extern void abort (void);
int
main()
{
unsigned int i, j;
for (i = 0; i < 624; ++i)
c[i] = 1;
bar();
j = 1;
for (i = 0; i < 624; ++i)
{
if (c[i] != j)
abort ();
j = j * 2;
}
return 0;
}
...@@ -44,7 +44,7 @@ foo2(unsigned char * to, const unsigned char * from, int n) ...@@ -44,7 +44,7 @@ foo2(unsigned char * to, const unsigned char * from, int n)
*to = *from; *to = *from;
break; break;
case 5: case 5:
to[4] = from [4]; /* { dg-warning "array subscript is above array bounds" } */ to[4] = from [4]; /* { dg-warning "array subscript is above array bounds" "" { xfail *-*-* } } */
break; break;
} }
return to; return to;
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-ccp1 -fdump-tree-forwprop1" } */
int a[256];
int foo(int i)
{
int *p = &a[0];
return *(p + i);
}
/* { dg-final { scan-tree-dump "&a\\\[\[iD\]\\\." "ccp1" } } */
/* { dg-final { scan-tree-dump "= .*&a\\\]\\\[\[iD\]\\\." "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-forwprop1" } */
int a[256];
int foo(int i)
{
return (a + 1)[i];
}
/* { dg-final { scan-tree-dump "=.*&a\\\]\\\[D\\\." "forwprop1" } } */
/* { dg-final { cleanup-tree-dump "forwprop1" } } */
...@@ -853,43 +853,14 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data) ...@@ -853,43 +853,14 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
tree ptr = TREE_OPERAND (*tp, 0); tree ptr = TREE_OPERAND (*tp, 0);
tree type = remap_type (TREE_TYPE (*tp), id); tree type = remap_type (TREE_TYPE (*tp), id);
tree old = *tp; tree old = *tp;
tree tem;
/* We need to re-canonicalize MEM_REFs from inline substitutions /* We need to re-canonicalize MEM_REFs from inline substitutions
that can happen when a pointer argument is an ADDR_EXPR. that can happen when a pointer argument is an ADDR_EXPR.
Recurse here manually to allow that. */ Recurse here manually to allow that. */
walk_tree (&ptr, remap_gimple_op_r, data, NULL); walk_tree (&ptr, remap_gimple_op_r, data, NULL);
if ((tem = maybe_fold_offset_to_reference (EXPR_LOCATION (*tp), *tp = fold_build2 (MEM_REF, type,
ptr, ptr, TREE_OPERAND (*tp, 1));
TREE_OPERAND (*tp, 1), TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
type))
&& 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;
TREE_THIS_VOLATILE (*tem_basep) = TREE_THIS_VOLATILE (old);
TREE_THIS_NOTRAP (*tem_basep) = TREE_THIS_NOTRAP (old);
}
else
{
*tp = fold_build2 (MEM_REF, type,
ptr, TREE_OPERAND (*tp, 1));
TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old);
}
TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old);
TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old);
*walk_subtrees = 0; *walk_subtrees = 0;
......
...@@ -1002,31 +1002,21 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs, ...@@ -1002,31 +1002,21 @@ forward_propagate_addr_expr_1 (tree name, tree def_rhs,
return false; return false;
rhs2 = gimple_assign_rhs2 (use_stmt); rhs2 = gimple_assign_rhs2 (use_stmt);
/* Try to optimize &x[C1] p+ C2 where C2 is a multiple of the size /* Optimize &x[C1] p+ C2 to &x p+ C3 with C3 = C1 * element_size + C2. */
of the elements in X into &x[C1 + C2/element size]. */
if (TREE_CODE (rhs2) == INTEGER_CST) if (TREE_CODE (rhs2) == INTEGER_CST)
{ {
tree new_rhs = maybe_fold_stmt_addition (gimple_location (use_stmt), tree new_rhs = build1_loc (gimple_location (use_stmt),
TREE_TYPE (def_rhs), ADDR_EXPR, TREE_TYPE (def_rhs),
def_rhs, rhs2); fold_build2 (MEM_REF,
if (new_rhs) TREE_TYPE (TREE_TYPE (def_rhs)),
{ unshare_expr (def_rhs),
tree type = TREE_TYPE (gimple_assign_lhs (use_stmt)); fold_convert (ptr_type_node,
new_rhs = unshare_expr (new_rhs); rhs2)));
if (!useless_type_conversion_p (type, TREE_TYPE (new_rhs))) gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
{ use_stmt = gsi_stmt (*use_stmt_gsi);
if (!is_gimple_min_invariant (new_rhs)) update_stmt (use_stmt);
new_rhs = force_gimple_operand_gsi (use_stmt_gsi, new_rhs, tidy_after_forward_propagate_addr (use_stmt);
true, NULL_TREE, return true;
true, GSI_SAME_STMT);
new_rhs = fold_convert (type, new_rhs);
}
gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
use_stmt = gsi_stmt (*use_stmt_gsi);
update_stmt (use_stmt);
tidy_after_forward_propagate_addr (use_stmt);
return true;
}
} }
/* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by /* Try to optimize &x[0] p+ OFFSET where OFFSET is defined by
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment