diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2016-12-20 09:39:44 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2016-12-20 09:39:44 +0000 |
commit | 2a1d4076c463ea534209b5e1b53089521321133b (patch) | |
tree | e93a241a140f1bdce70c906fd42167dc1085b4e2 /gcc | |
parent | 48e512b6984ab25185bd1239a042ab0e8fb3f95c (diff) | |
download | gcc-2a1d4076c463ea534209b5e1b53089521321133b.zip gcc-2a1d4076c463ea534209b5e1b53089521321133b.tar.gz gcc-2a1d4076c463ea534209b5e1b53089521321133b.tar.bz2 |
[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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr78694.c | 118 |
4 files changed, 136 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba3c4da..0ad59ba 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index d0104f9..bbf10f2 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 b0decca..eab8cd8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 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 0000000..bc31944 --- /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; +} |