Commit 229d576c by Richard Biener Committed by Richard Biener

re PR tree-optimization/87609 (miscompilation with restrict and loop)

2019-02-22  Richard Biener  <rguenther@suse.de>

	PR middle-end/87609
	* cfghooks.h (dependence_hash): New typedef.
	(struct copy_bb_data): New type.
	(cfg_hooks::duplicate_block): Adjust to take a copy_bb_data argument.
	(duplicate_block): Likewise.
	* cfghooks.c (duplicate_block): Pass down copy_bb_data.
	(copy_bbs): Create and pass down copy_bb_data.
	* cfgrtl.c (cfg_layout_duplicate_bb): Adjust.
	(rtl_duplicate_bb): Likewise.
	* tree-cfg.c (gimple_duplicate_bb): If the copy_bb_data arg is not NULL
	remap dependence info.

	* gcc.dg/torture/restrict-7.c: New testcase.

From-SVN: r269098
parent 3c8b06dc
2019-02-22 Richard Biener <rguenther@suse.de> 2019-02-22 Richard Biener <rguenther@suse.de>
PR middle-end/87609
* cfghooks.h (dependence_hash): New typedef.
(struct copy_bb_data): New type.
(cfg_hooks::duplicate_block): Adjust to take a copy_bb_data argument.
(duplicate_block): Likewise.
* cfghooks.c (duplicate_block): Pass down copy_bb_data.
(copy_bbs): Create and pass down copy_bb_data.
* cfgrtl.c (cfg_layout_duplicate_bb): Adjust.
(rtl_duplicate_bb): Likewise.
* tree-cfg.c (gimple_duplicate_bb): If the copy_bb_data arg is not NULL
remap dependence info.
2019-02-22 Richard Biener <rguenther@suse.de>
PR tree-optimization/87609 PR tree-optimization/87609
* tree-core.h (tree_base): Document special clique values. * tree-core.h (tree_base): Document special clique values.
* tree-inline.c (remap_dependence_clique): Do not use the * tree-inline.c (remap_dependence_clique): Do not use the
......
...@@ -1066,7 +1066,7 @@ can_duplicate_block_p (const_basic_block bb) ...@@ -1066,7 +1066,7 @@ can_duplicate_block_p (const_basic_block bb)
AFTER. */ AFTER. */
basic_block basic_block
duplicate_block (basic_block bb, edge e, basic_block after) duplicate_block (basic_block bb, edge e, basic_block after, copy_bb_data *id)
{ {
edge s, n; edge s, n;
basic_block new_bb; basic_block new_bb;
...@@ -1082,7 +1082,7 @@ duplicate_block (basic_block bb, edge e, basic_block after) ...@@ -1082,7 +1082,7 @@ duplicate_block (basic_block bb, edge e, basic_block after)
gcc_checking_assert (can_duplicate_block_p (bb)); gcc_checking_assert (can_duplicate_block_p (bb));
new_bb = cfg_hooks->duplicate_block (bb); new_bb = cfg_hooks->duplicate_block (bb, id);
if (after) if (after)
move_block_after (new_bb, after); move_block_after (new_bb, after);
...@@ -1337,6 +1337,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, ...@@ -1337,6 +1337,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
unsigned i, j; unsigned i, j;
basic_block bb, new_bb, dom_bb; basic_block bb, new_bb, dom_bb;
edge e; edge e;
copy_bb_data id;
/* Mark the blocks to be copied. This is used by edge creation hooks /* Mark the blocks to be copied. This is used by edge creation hooks
to decide whether to reallocate PHI nodes capacity to avoid reallocating to decide whether to reallocate PHI nodes capacity to avoid reallocating
...@@ -1349,7 +1350,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, ...@@ -1349,7 +1350,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
{ {
/* Duplicate. */ /* Duplicate. */
bb = bbs[i]; bb = bbs[i];
new_bb = new_bbs[i] = duplicate_block (bb, NULL, after); new_bb = new_bbs[i] = duplicate_block (bb, NULL, after, &id);
after = new_bb; after = new_bb;
if (bb->loop_father) if (bb->loop_father)
{ {
......
...@@ -54,6 +54,19 @@ struct profile_record ...@@ -54,6 +54,19 @@ struct profile_record
bool run; bool run;
}; };
typedef int_hash <unsigned short, 0> dependence_hash;
/* Optional data for duplicate_block. */
struct copy_bb_data
{
copy_bb_data() : dependence_map (NULL) {}
~copy_bb_data () { delete dependence_map; }
/* A map from the copied BBs dependence info cliques to
equivalents in the BBs duplicated to. */
hash_map<dependence_hash, unsigned short> *dependence_map;
};
struct cfg_hooks struct cfg_hooks
{ {
...@@ -112,7 +125,7 @@ struct cfg_hooks ...@@ -112,7 +125,7 @@ struct cfg_hooks
bool (*can_duplicate_block_p) (const_basic_block a); bool (*can_duplicate_block_p) (const_basic_block a);
/* Duplicate block A. */ /* Duplicate block A. */
basic_block (*duplicate_block) (basic_block a); basic_block (*duplicate_block) (basic_block a, copy_bb_data *);
/* Higher level functions representable by primitive operations above if /* Higher level functions representable by primitive operations above if
we didn't have some oddities in RTL and Tree representations. */ we didn't have some oddities in RTL and Tree representations. */
...@@ -227,7 +240,8 @@ extern void tidy_fallthru_edges (void); ...@@ -227,7 +240,8 @@ extern void tidy_fallthru_edges (void);
extern void predict_edge (edge e, enum br_predictor predictor, int probability); extern void predict_edge (edge e, enum br_predictor predictor, int probability);
extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor); extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
extern bool can_duplicate_block_p (const_basic_block); extern bool can_duplicate_block_p (const_basic_block);
extern basic_block duplicate_block (basic_block, edge, basic_block); extern basic_block duplicate_block (basic_block, edge, basic_block,
copy_bb_data * = NULL);
extern bool block_ends_with_call_p (basic_block bb); extern bool block_ends_with_call_p (basic_block bb);
extern bool empty_block_p (basic_block); extern bool empty_block_p (basic_block);
extern basic_block split_block_before_cond_jump (basic_block); extern basic_block split_block_before_cond_jump (basic_block);
......
...@@ -4250,7 +4250,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to) ...@@ -4250,7 +4250,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to)
/* Create a duplicate of the basic block BB. */ /* Create a duplicate of the basic block BB. */
static basic_block static basic_block
cfg_layout_duplicate_bb (basic_block bb) cfg_layout_duplicate_bb (basic_block bb, copy_bb_data *)
{ {
rtx_insn *insn; rtx_insn *insn;
basic_block new_bb; basic_block new_bb;
...@@ -5080,9 +5080,9 @@ rtl_can_remove_branch_p (const_edge e) ...@@ -5080,9 +5080,9 @@ rtl_can_remove_branch_p (const_edge e)
} }
static basic_block static basic_block
rtl_duplicate_bb (basic_block bb) rtl_duplicate_bb (basic_block bb, copy_bb_data *id)
{ {
bb = cfg_layout_duplicate_bb (bb); bb = cfg_layout_duplicate_bb (bb, id);
bb->aux = NULL; bb->aux = NULL;
return bb; return bb;
} }
......
2019-02-22 Richard Biener <rguenther@suse.de>
PR middle-end/87609
* gcc.dg/torture/restrict-7.c: New testcase.
2019-02-21 Jakub Jelinek <jakub@redhat.com> 2019-02-21 Jakub Jelinek <jakub@redhat.com>
PR c++/89285 PR c++/89285
......
/* { dg-do run } */
extern void abort (void);
static inline __attribute__((always_inline)) void
copy(int *restrict a, int *restrict b)
{
*b = *a;
*a = 7;
}
void __attribute__((noinline))
floppy(int mat[static 2], unsigned idxs[static 3])
{
for (int i = 0; i < 3; i++)
copy(&mat[i%2], &mat[idxs[i]]);
}
int main()
{
int mat[2] = {10, 20};
unsigned idxs[3] = {1, 0, 1};
floppy(mat, idxs);
if (mat[0] != 7 || mat[1] != 10)
abort ();
return 0;
}
...@@ -6164,7 +6164,7 @@ gimple_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED) ...@@ -6164,7 +6164,7 @@ gimple_can_duplicate_bb_p (const_basic_block bb ATTRIBUTE_UNUSED)
preserve SSA form. */ preserve SSA form. */
static basic_block static basic_block
gimple_duplicate_bb (basic_block bb) gimple_duplicate_bb (basic_block bb, copy_bb_data *id)
{ {
basic_block new_bb; basic_block new_bb;
gimple_stmt_iterator gsi_tgt; gimple_stmt_iterator gsi_tgt;
...@@ -6228,6 +6228,36 @@ gimple_duplicate_bb (basic_block bb) ...@@ -6228,6 +6228,36 @@ gimple_duplicate_bb (basic_block bb)
&& (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base))) && (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
DECL_NONSHAREABLE (base) = 1; DECL_NONSHAREABLE (base) = 1;
} }
if (id)
for (unsigned i = 0; i < gimple_num_ops (copy); ++i)
{
tree op = gimple_op (copy, i);
if (!op)
continue;
if (TREE_CODE (op) == ADDR_EXPR
|| TREE_CODE (op) == WITH_SIZE_EXPR)
op = TREE_OPERAND (op, 0);
while (handled_component_p (op))
op = TREE_OPERAND (op, 0);
if ((TREE_CODE (op) == MEM_REF
|| TREE_CODE (op) == TARGET_MEM_REF)
&& MR_DEPENDENCE_CLIQUE (op) != 0)
{
if (!id->dependence_map)
id->dependence_map = new hash_map<dependence_hash,
unsigned short>;
bool existed;
unsigned short &newc = id->dependence_map->get_or_insert
(MR_DEPENDENCE_CLIQUE (op), &existed);
if (!existed)
{
gcc_assert (MR_DEPENDENCE_CLIQUE (op) <= cfun->last_clique);
newc = ++cfun->last_clique;
}
MR_DEPENDENCE_CLIQUE (op) = newc;
}
}
/* Create new names for all the definitions created by COPY and /* Create new names for all the definitions created by COPY and
add replacement mappings for each new name. */ add replacement mappings for each new name. */
......
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