[ARM] PR target/78694: Avoid invalid RTL sharing in minipool code
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 20 Dec 2016 09:39:44 +0000 (09:39 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 20 Dec 2016 09:39:44 +0000 (09:39 +0000)
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

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr78694.c [new file with mode: 0644]

index ba3c4daa9a3d3fe9d8ded6b57bf83157678b1704..0ad59ba9bc3ac82dc20e196ff0ac6704b24c63f8 100644 (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.
index d0104f99a2e91df80d774c833522306d396b09d1..bbf10f23987e58a1e066715e2168772da0245ff1 100644 (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
index b0deccac8819bebb2b6b5bc49f0f49dec4fad171..eab8cd8c4f7311bf0c2796af92fd7698bd24ec5a 100644 (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
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr78694.c b/gcc/testsuite/gcc.c-torture/compile/pr78694.c
new file mode 100644 (file)
index 0000000..bc31944
--- /dev/null
@@ -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;
+}