re PR c/81687 (Compiler drops label in OpenMP region)
authorJakub Jelinek <jakub@redhat.com>
Thu, 10 Aug 2017 00:33:20 +0000 (02:33 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 10 Aug 2017 00:33:20 +0000 (02:33 +0200)
PR c/81687
* omp-low.c (omp_copy_decl): Don't remap FORCED_LABEL or DECL_NONLOCAL
LABEL_DECLs.
* tree-cfg.c (move_stmt_op): Don't adjust DECL_CONTEXT of FORCED_LABEL
or DECL_NONLOCAL labels.
(move_stmt_r) <case GIMPLE_LABEL>: Adjust DECL_CONTEXT of FORCED_LABEL
or DECL_NONLOCAL labels here.

* testsuite/libgomp.c/pr81687-1.c: New test.
* testsuite/libgomp.c/pr81687-2.c: New test.

From-SVN: r251019

gcc/ChangeLog
gcc/omp-low.c
gcc/tree-cfg.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/pr81687-1.c [new file with mode: 0644]
libgomp/testsuite/libgomp.c/pr81687-2.c [new file with mode: 0644]

index 251b0f6..1b02925 100644 (file)
@@ -1,3 +1,13 @@
+2017-08-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/81687
+       * omp-low.c (omp_copy_decl): Don't remap FORCED_LABEL or DECL_NONLOCAL
+       LABEL_DECLs.
+       * tree-cfg.c (move_stmt_op): Don't adjust DECL_CONTEXT of FORCED_LABEL
+       or DECL_NONLOCAL labels.
+       (move_stmt_r) <case GIMPLE_LABEL>: Adjust DECL_CONTEXT of FORCED_LABEL
+       or DECL_NONLOCAL labels here.
+
 2017-08-09  Will Schmidt  <will_schmidt@vnet.ibm.com>
 
        * config/rs6000/rs6000.c (rs6000_option_override_internal): Add blurb
index 3df6056..dffdb77 100644 (file)
@@ -798,6 +798,8 @@ omp_copy_decl (tree var, copy_body_data *cb)
 
   if (TREE_CODE (var) == LABEL_DECL)
     {
+      if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
+       return var;
       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
       DECL_CONTEXT (new_var) = current_function_decl;
       insert_decl_map (&ctx->cb, var, new_var);
index 733c92f..f26b12f 100644 (file)
@@ -6718,7 +6718,15 @@ move_stmt_op (tree *tp, int *walk_subtrees, void *data)
                *tp = t = out->to;
            }
 
-         DECL_CONTEXT (t) = p->to_context;
+         /* For FORCED_LABELs we can end up with references from other
+            functions if some SESE regions are outlined.  It is UB to
+            jump in between them, but they could be used just for printing
+            addresses etc.  In that case, DECL_CONTEXT on the label should
+            be the function containing the glabel stmt with that LABEL_DECL,
+            rather than whatever function a reference to the label was seen
+            last time.  */
+         if (!FORCED_LABEL (t) && !DECL_NONLOCAL (t))
+           DECL_CONTEXT (t) = p->to_context;
        }
       else if (p->remap_decls_p)
        {
@@ -6836,6 +6844,21 @@ move_stmt_r (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
     case GIMPLE_OMP_RETURN:
     case GIMPLE_OMP_CONTINUE:
       break;
+
+    case GIMPLE_LABEL:
+      {
+       /* For FORCED_LABEL, move_stmt_op doesn't adjust DECL_CONTEXT,
+          so that such labels can be referenced from other regions.
+          Make sure to update it when seeing a GIMPLE_LABEL though,
+          that is the owner of the label.  */
+       walk_gimple_op (stmt, move_stmt_op, wi);
+       *handled_ops_p = true;
+       tree label = gimple_label_label (as_a <glabel *> (stmt));
+       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
+         DECL_CONTEXT (label) = p->to_context;
+      }
+      break;
+
     default:
       if (is_gimple_omp (stmt))
        {
index f17a17b..434cca7 100644 (file)
@@ -1,3 +1,9 @@
+2017-08-09  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c/81687
+       * testsuite/libgomp.c/pr81687-1.c: New test.
+       * testsuite/libgomp.c/pr81687-2.c: New test.
+
 2017-08-07  Jakub Jelinek  <jakub@redhat.com>
 
        PR c/69389
diff --git a/libgomp/testsuite/libgomp.c/pr81687-1.c b/libgomp/testsuite/libgomp.c/pr81687-1.c
new file mode 100644 (file)
index 0000000..768ec44
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+extern int printf (const char *, ...);
+
+int
+main ()
+{
+  #pragma omp parallel
+  {
+   lab1:
+    printf ("lab1=%p\n", (void *)(&&lab1));
+  }
+ lab2:
+  #pragma omp parallel
+  {
+   lab3:
+    printf ("lab2=%p\n", (void *)(&&lab2));
+  }
+  printf ("lab3=%p\n", (void *)(&&lab3));
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pr81687-2.c b/libgomp/testsuite/libgomp.c/pr81687-2.c
new file mode 100644 (file)
index 0000000..e819f76
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+int
+main ()
+{
+  __label__ lab4, lab5, lab6;
+  volatile int l = 0;
+  int m = l;
+  void foo (int x) { if (x == 1) goto lab4; }
+  void bar (int x) { if (x == 2) goto lab5; }
+  void baz (int x) { if (x == 3) goto lab6; }
+  #pragma omp parallel
+  {
+    foo (m + 1);
+   lab4:;
+  }
+  #pragma omp task
+  {
+    bar (m + 2);
+   lab5:;
+  }
+  baz (m + 3);
+ lab6:;
+  return 0;
+}