re PR tree-optimization/58653 (wrong code (segfaults) at -O3 on x86_64-linux-gnu in 64-bit mode (affecting gcc 4.6 to trunk))
2013-11-06 Richard Biener <rguenther@suse.de> PR tree-optimization/58653 * tree-predcom.c (ref_at_iteration): Rewrite to generate a MEM_REF. (prepare_initializers_chain): Adjust. * gcc.dg/tree-ssa/predcom-6.c: New testcase. * gcc.dg/tree-ssa/predcom-7.c: Likewise. From-SVN: r204458
This commit is contained in:
parent
28d31e4074
commit
9f2b860bed
5 changed files with 65 additions and 86 deletions
|
@ -1,3 +1,10 @@
|
|||
2013-11-06 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/58653
|
||||
* tree-predcom.c (ref_at_iteration): Rewrite to generate
|
||||
a MEM_REF.
|
||||
(prepare_initializers_chain): Adjust.
|
||||
|
||||
2013-11-06 Andrew MacLeod <amacleod@redhat.com>
|
||||
|
||||
* gimple.h (block_in_transaction): Move to basic-block.h and rename.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2013-11-06 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/58653
|
||||
* gcc.dg/tree-ssa/predcom-6.c: New testcase.
|
||||
* gcc.dg/tree-ssa/predcom-7.c: Likewise.
|
||||
|
||||
2013-11-05 Balaji V. Iyer <balaji.v.iyer@intel.com>
|
||||
|
||||
* c-c++-common/cilk-plus/CK/fib.c: Reduced the iteration from
|
||||
|
|
13
gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c
Normal file
13
gcc/testsuite/gcc.dg/tree-ssa/predcom-6.c
Normal file
|
@ -0,0 +1,13 @@
|
|||
/* { dg-do run } */
|
||||
|
||||
int a, c, e[5][2];
|
||||
unsigned int d;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (d = 0; d < 2; d++)
|
||||
if (a ? 0 : e[c + 3][d] & e[c + 4][d])
|
||||
break;
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c
Normal file
18
gcc/testsuite/gcc.dg/tree-ssa/predcom-7.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do run } */
|
||||
/* { dg-options "-O3 -fdump-tree-pcom-details" } */
|
||||
|
||||
int b, f, d[5][2];
|
||||
unsigned int c;
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
for (c = 0; c < 2; c++)
|
||||
if (d[b + 3][c] & d[b + 4][c])
|
||||
if (f)
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "Executing predictive commoning" "pcom" } } */
|
||||
/* { dg-final { cleanup-tree-dump "pcom" } } */
|
|
@ -1334,90 +1334,29 @@ replace_ref_with (gimple stmt, tree new_tree, bool set, bool in_lhs)
|
|||
gsi_insert_after (&bsi, new_stmt, GSI_NEW_STMT);
|
||||
}
|
||||
|
||||
/* Returns the reference to the address of REF in the ITER-th iteration of
|
||||
LOOP, or NULL if we fail to determine it (ITER may be negative). We
|
||||
try to preserve the original shape of the reference (not rewrite it
|
||||
as an indirect ref to the address), to make tree_could_trap_p in
|
||||
prepare_initializers_chain return false more often. */
|
||||
/* Returns a memory reference to DR in the ITER-th iteration of
|
||||
the loop it was analyzed in. Append init stmts to STMTS. */
|
||||
|
||||
static tree
|
||||
ref_at_iteration (struct loop *loop, tree ref, int iter)
|
||||
static tree
|
||||
ref_at_iteration (data_reference_p dr, int iter, gimple_seq *stmts)
|
||||
{
|
||||
tree idx, *idx_p, type, val, op0 = NULL_TREE, ret;
|
||||
affine_iv iv;
|
||||
bool ok;
|
||||
|
||||
if (handled_component_p (ref))
|
||||
{
|
||||
op0 = ref_at_iteration (loop, TREE_OPERAND (ref, 0), iter);
|
||||
if (!op0)
|
||||
return NULL_TREE;
|
||||
}
|
||||
else if (!INDIRECT_REF_P (ref)
|
||||
&& TREE_CODE (ref) != MEM_REF)
|
||||
return unshare_expr (ref);
|
||||
|
||||
if (TREE_CODE (ref) == MEM_REF)
|
||||
{
|
||||
ret = unshare_expr (ref);
|
||||
idx = TREE_OPERAND (ref, 0);
|
||||
idx_p = &TREE_OPERAND (ret, 0);
|
||||
}
|
||||
else if (TREE_CODE (ref) == COMPONENT_REF)
|
||||
{
|
||||
/* Check that the offset is loop invariant. */
|
||||
if (TREE_OPERAND (ref, 2)
|
||||
&& !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2)))
|
||||
return NULL_TREE;
|
||||
|
||||
return build3 (COMPONENT_REF, TREE_TYPE (ref), op0,
|
||||
unshare_expr (TREE_OPERAND (ref, 1)),
|
||||
unshare_expr (TREE_OPERAND (ref, 2)));
|
||||
}
|
||||
else if (TREE_CODE (ref) == ARRAY_REF)
|
||||
{
|
||||
/* Check that the lower bound and the step are loop invariant. */
|
||||
if (TREE_OPERAND (ref, 2)
|
||||
&& !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 2)))
|
||||
return NULL_TREE;
|
||||
if (TREE_OPERAND (ref, 3)
|
||||
&& !expr_invariant_in_loop_p (loop, TREE_OPERAND (ref, 3)))
|
||||
return NULL_TREE;
|
||||
|
||||
ret = build4 (ARRAY_REF, TREE_TYPE (ref), op0, NULL_TREE,
|
||||
unshare_expr (TREE_OPERAND (ref, 2)),
|
||||
unshare_expr (TREE_OPERAND (ref, 3)));
|
||||
idx = TREE_OPERAND (ref, 1);
|
||||
idx_p = &TREE_OPERAND (ret, 1);
|
||||
}
|
||||
tree off = DR_OFFSET (dr);
|
||||
tree coff = DR_INIT (dr);
|
||||
if (iter == 0)
|
||||
;
|
||||
else if (TREE_CODE (DR_STEP (dr)) == INTEGER_CST)
|
||||
coff = size_binop (PLUS_EXPR, coff,
|
||||
size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter)));
|
||||
else
|
||||
return NULL_TREE;
|
||||
|
||||
ok = simple_iv (loop, loop, idx, &iv, true);
|
||||
if (!ok)
|
||||
return NULL_TREE;
|
||||
iv.base = expand_simple_operations (iv.base);
|
||||
if (integer_zerop (iv.step))
|
||||
*idx_p = unshare_expr (iv.base);
|
||||
else
|
||||
{
|
||||
type = TREE_TYPE (iv.base);
|
||||
if (POINTER_TYPE_P (type))
|
||||
{
|
||||
val = fold_build2 (MULT_EXPR, sizetype, iv.step,
|
||||
size_int (iter));
|
||||
val = fold_build_pointer_plus (iv.base, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
val = fold_build2 (MULT_EXPR, type, iv.step,
|
||||
build_int_cst_type (type, iter));
|
||||
val = fold_build2 (PLUS_EXPR, type, iv.base, val);
|
||||
}
|
||||
*idx_p = unshare_expr (val);
|
||||
}
|
||||
|
||||
return ret;
|
||||
off = size_binop (PLUS_EXPR, off,
|
||||
size_binop (MULT_EXPR, DR_STEP (dr), ssize_int (iter)));
|
||||
tree addr = fold_build_pointer_plus (DR_BASE_ADDRESS (dr), off);
|
||||
addr = force_gimple_operand_1 (addr, stmts, is_gimple_mem_ref_addr,
|
||||
NULL_TREE);
|
||||
return fold_build2 (MEM_REF, TREE_TYPE (DR_REF (dr)),
|
||||
addr,
|
||||
fold_convert (reference_alias_ptr_type (DR_REF (dr)),
|
||||
coff));
|
||||
}
|
||||
|
||||
/* Get the initialization expression for the INDEX-th temporary variable
|
||||
|
@ -2376,14 +2315,10 @@ prepare_initializers_chain (struct loop *loop, chain_p chain)
|
|||
if (chain->inits[i] != NULL_TREE)
|
||||
continue;
|
||||
|
||||
init = ref_at_iteration (loop, DR_REF (dr), (int) i - n);
|
||||
if (!init)
|
||||
return false;
|
||||
|
||||
init = ref_at_iteration (dr, (int) i - n, &stmts);
|
||||
if (!chain->all_always_accessed && tree_could_trap_p (init))
|
||||
return false;
|
||||
|
||||
init = force_gimple_operand (init, &stmts, false, NULL_TREE);
|
||||
if (stmts)
|
||||
gsi_insert_seq_on_edge_immediate (entry, stmts);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue