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
This commit is contained in:
parent
3c8b06dcc6
commit
229d576cde
@ -1,3 +1,17 @@
|
||||
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
|
||||
|
@ -1066,7 +1066,7 @@ can_duplicate_block_p (const_basic_block bb)
|
||||
AFTER. */
|
||||
|
||||
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;
|
||||
basic_block new_bb;
|
||||
@ -1082,7 +1082,7 @@ duplicate_block (basic_block bb, edge e, basic_block after)
|
||||
|
||||
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)
|
||||
move_block_after (new_bb, after);
|
||||
|
||||
@ -1337,6 +1337,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
|
||||
unsigned i, j;
|
||||
basic_block bb, new_bb, dom_bb;
|
||||
edge e;
|
||||
copy_bb_data id;
|
||||
|
||||
/* Mark the blocks to be copied. This is used by edge creation hooks
|
||||
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,
|
||||
{
|
||||
/* Duplicate. */
|
||||
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;
|
||||
if (bb->loop_father)
|
||||
{
|
||||
|
@ -54,6 +54,19 @@ struct profile_record
|
||||
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
|
||||
{
|
||||
@ -112,7 +125,7 @@ struct cfg_hooks
|
||||
bool (*can_duplicate_block_p) (const_basic_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
|
||||
we didn't have some oddities in RTL and Tree representations. */
|
||||
@ -227,7 +240,8 @@ extern void tidy_fallthru_edges (void);
|
||||
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 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 empty_block_p (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)
|
||||
/* Create a duplicate of the basic block BB. */
|
||||
|
||||
static basic_block
|
||||
cfg_layout_duplicate_bb (basic_block bb)
|
||||
cfg_layout_duplicate_bb (basic_block bb, copy_bb_data *)
|
||||
{
|
||||
rtx_insn *insn;
|
||||
basic_block new_bb;
|
||||
@ -5080,9 +5080,9 @@ rtl_can_remove_branch_p (const_edge e)
|
||||
}
|
||||
|
||||
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;
|
||||
return bb;
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
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>
|
||||
|
||||
PR c++/89285
|
||||
|
27
gcc/testsuite/gcc.dg/torture/restrict-7.c
Normal file
27
gcc/testsuite/gcc.dg/torture/restrict-7.c
Normal file
@ -0,0 +1,27 @@
|
||||
/* { 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)
|
||||
preserve SSA form. */
|
||||
|
||||
static basic_block
|
||||
gimple_duplicate_bb (basic_block bb)
|
||||
gimple_duplicate_bb (basic_block bb, copy_bb_data *id)
|
||||
{
|
||||
basic_block new_bb;
|
||||
gimple_stmt_iterator gsi_tgt;
|
||||
@ -6228,6 +6228,36 @@ gimple_duplicate_bb (basic_block bb)
|
||||
&& (!VAR_P (base) || !DECL_HAS_VALUE_EXPR_P (base)))
|
||||
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
|
||||
add replacement mappings for each new name. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user