From: Kyrylo Tkachov Date: Tue, 20 Dec 2016 09:39:44 +0000 (+0000) Subject: [ARM] PR target/78694: Avoid invalid RTL sharing in minipool code X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2a1d4076c463ea534209b5e1b53089521321133b;p=gcc.git [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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba3c4daa9a3..0ad59ba9bc3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-12-20 Kyrylo Tkachov + + 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 * config/rs6000/rs6000-protos.h (expand_strn_compare): Declare. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index d0104f99a2e..bbf10f23987 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b0deccac881..eab8cd8c4f7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-12-20 Kyrylo Tkachov + + PR target/78694 + * gcc.c-torture/compile/pr78694.c: New test. + 2016-12-20 Eric Botcazou PR testsuite/71232 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr78694.c b/gcc/testsuite/gcc.c-torture/compile/pr78694.c new file mode 100644 index 00000000000..bc3194426a0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr78694.c @@ -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; +}