[ARM] PR target/78694: Avoid invalid RTL sharing in minipool code

PR target/78694
	* config/arm/arm.c (dump_minipool): Copy mp->value before emitting it
	in the minipool to avoid invalid RTL sharing.

	* gcc.c-torture/compile/pr78694.c: New test.

From-SVN: r243820
This commit is contained in:
Kyrylo Tkachov 2016-12-20 09:39:44 +00:00 committed by Kyrylo Tkachov
parent 48e512b698
commit 2a1d4076c4
4 changed files with 136 additions and 5 deletions

View File

@ -1,3 +1,9 @@
2016-12-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/78694
* config/arm/arm.c (dump_minipool): Copy mp->value before emitting it
in the minipool to avoid invalid RTL sharing.
2016-12-19 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
* config/rs6000/rs6000-protos.h (expand_strn_compare): Declare.

View File

@ -16111,35 +16111,37 @@ dump_minipool (rtx_insn *scan)
fputc ('\n', dump_file);
}
rtx val = copy_rtx (mp->value);
switch (GET_MODE_SIZE (mp->mode))
{
#ifdef HAVE_consttable_1
case 1:
scan = emit_insn_after (gen_consttable_1 (mp->value), scan);
scan = emit_insn_after (gen_consttable_1 (val), scan);
break;
#endif
#ifdef HAVE_consttable_2
case 2:
scan = emit_insn_after (gen_consttable_2 (mp->value), scan);
scan = emit_insn_after (gen_consttable_2 (val), scan);
break;
#endif
#ifdef HAVE_consttable_4
case 4:
scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
scan = emit_insn_after (gen_consttable_4 (val), scan);
break;
#endif
#ifdef HAVE_consttable_8
case 8:
scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
scan = emit_insn_after (gen_consttable_8 (val), scan);
break;
#endif
#ifdef HAVE_consttable_16
case 16:
scan = emit_insn_after (gen_consttable_16 (mp->value), scan);
scan = emit_insn_after (gen_consttable_16 (val), scan);
break;
#endif

View File

@ -1,3 +1,8 @@
2016-12-20 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR target/78694
* gcc.c-torture/compile/pr78694.c: New test.
2016-12-20 Eric Botcazou <ebotcazou@adacore.com>
PR testsuite/71232

View File

@ -0,0 +1,118 @@
/* PR target/78694. */
enum
{
MEMMODEL_RELAXED,
MEMMODEL_ACQUIRE,
PRIORITY_INSERT_END
};
enum
{
PQ_CHILDREN,
PQ_TASKGROUP
};
struct gomp_team_state
{
struct gomp_team *team;
};
enum gomp_task_kind
{
GOMP_TASK_UNDEFERRED,
GOMP_TASK_WAITING
};
struct gomp_taskwait
{
_Bool in_taskwait;
};
struct gomp_task
{
struct gomp_task *parent;
int children_queue;
struct gomp_taskgroup *taskgroup;
int dependers;
struct gomp_taskwait taskwait;
enum gomp_task_kind kind;
_Bool in_tied_task;
} j, q, *n;
struct gomp_taskgroup
{
_Bool in_taskgroup_wait;
int num_children;
} l;
struct gomp_team
{
int task_queue;
int task_running_count;
};
struct gomp_thread
{
struct gomp_team_state ts;
struct gomp_task task;
} extern __thread a;
int b, c, d, e, f, g, h, i, k, m, o, p, r;
void priority_queue_next_task (struct gomp_task *, int, int);
int gomp_task_run_pre (struct gomp_task *, struct gomp_task, struct gomp_team);
void priority_queue_insert (int, struct gomp_task);
void priority_queue_insert2 (int, struct gomp_task, int, int, int);
void priority_queue_insert3 (int, struct gomp_task, int, int, int);
void gomp_sem_post (int);
void free (void *);
_Bool s;
int
GOMP_taskgroup_end ()
{
struct gomp_thread *t = &a;
struct gomp_team u = *t->ts.team;
struct gomp_task *v = &t->task, *w;
if (__atomic_load_n (&l.num_children, MEMMODEL_ACQUIRE))
while (1)
{
if (l.num_children)
priority_queue_next_task (v, u.task_queue, r);
else if (w)
free (w);
if (n->kind == GOMP_TASK_WAITING)
{
s = gomp_task_run_pre (n, q, u);
if (__builtin_expect (s, 0))
{
if (w)
free (w);
goto finish_cancelled;
}
n = 0;
l.in_taskgroup_wait = 1;
}
if (w)
{
t->task = *n;
if (__builtin_expect (p, 0))
if (o)
t->task = *v;
}
if (n)
{
struct gomp_task x = x;
for (; i; b++)
{
struct gomp_task y = j;
if (g)
continue;
priority_queue_insert (PQ_CHILDREN, x);
if (x.taskwait.in_taskwait)
priority_queue_insert2 (PQ_TASKGROUP, y, e, 0, d);
if (h)
gomp_sem_post (f);
priority_queue_insert3 (k, y, PRIORITY_INSERT_END, 0, d);
++c;
}
}
finish_cancelled:
w = (struct gomp_task *) (n - u.task_running_count - v);
}
v->taskgroup = (struct gomp_taskgroup *) m;
return 1;
}