re PR middle-end/29965 (OpenMP vs always throw in a loop)
authorJakub Jelinek <jakub@redhat.com>
Mon, 4 Dec 2006 10:20:51 +0000 (11:20 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 4 Dec 2006 10:20:51 +0000 (11:20 +0100)
PR middle-end/29965
* omp-low.c (determine_parallel_type): Don't try to optimize combined
parallels if region->exit or region->inner->exit is NULL.
(expand_omp_parallel): Handle NULL region->exit even if cfg is already
built.
(expand_omp_for_generic): Handle NULL region->cond and region->exit.
(expand_omp_for): Use expand_omp_for_generic if either region->cond
or region->exit is NULL.
(expand_omp_sections): Handle NULL region->cond or region->exit.
(expand_omp_synch):

* gcc.dg/gomp/pr29965-1.c: New test.
* gcc.dg/gomp/pr29965-2.c: New test.
* gcc.dg/gomp/pr29965-3.c: New test.
* gcc.dg/gomp/pr29965-4.c: New test.
* gcc.dg/gomp/pr29965-5.c: New test.
* gcc.dg/gomp/pr29965-6.c: New test.
* g++.dg/gomp/pr29965-1.C: New test.
* g++.dg/gomp/pr29965-2.C: New test.
* g++.dg/gomp/pr29965-3.C: New test.
* g++.dg/gomp/pr29965-4.C: New test.
* g++.dg/gomp/pr29965-5.C: New test.
* g++.dg/gomp/pr29965-6.C: New test.
* g++.dg/gomp/pr29965-7.C: New test.
* g++.dg/gomp/pr29965-8.C: New test.
* g++.dg/gomp/pr29965-9.C: New test.
* g++.dg/gomp/pr29965-10.C: New test.

From-SVN: r119483

19 files changed:
gcc/ChangeLog
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/gomp/pr29965-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-10.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-4.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-5.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-6.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-7.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/gomp/pr29965-9.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/gomp/pr29965-6.c [new file with mode: 0644]

index 79ab4fe..d544736 100644 (file)
@@ -1,3 +1,16 @@
+2006-12-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/29965
+       * omp-low.c (determine_parallel_type): Don't try to optimize combined
+       parallels if region->exit or region->inner->exit is NULL.
+       (expand_omp_parallel): Handle NULL region->exit even if cfg is already
+       built.
+       (expand_omp_for_generic): Handle NULL region->cond and region->exit.
+       (expand_omp_for): Use expand_omp_for_generic if either region->cond
+       or region->exit is NULL.
+       (expand_omp_sections): Handle NULL region->cond or region->exit.
+       (expand_omp_synch): 
+
 2006-12-04  Eric Botcazou  <ebotcazou@libertysurf.fr>
 
        * config/sparc/sp64-elf.h (JUMP_TABLES_IN_TEXT_SECTION): Delete.
index 0816103..30dbc71 100644 (file)
@@ -365,7 +365,8 @@ determine_parallel_type (struct omp_region *region)
   basic_block par_entry_bb, par_exit_bb;
   basic_block ws_entry_bb, ws_exit_bb;
 
-  if (region == NULL || region->inner == NULL)
+  if (region == NULL || region->inner == NULL
+      || region->exit == NULL || region->inner->exit == NULL)
     return;
 
   /* We only support parallel+for and parallel+sections.  */
@@ -2443,7 +2444,6 @@ expand_omp_parallel (struct omp_region *region)
       block_stmt_iterator si;
 
       entry_succ_e = single_succ_edge (entry_bb);
-      exit_succ_e = single_succ_edge (exit_bb);
 
       si = bsi_last (entry_bb);
       gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
@@ -2451,7 +2451,11 @@ expand_omp_parallel (struct omp_region *region)
 
       new_bb = entry_bb;
       remove_edge (entry_succ_e);
-      make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
+      if (exit_bb)
+       {
+         exit_succ_e = single_succ_edge (exit_bb);
+         make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
+       }
     }
   else
     {
@@ -2574,10 +2578,11 @@ expand_omp_for_generic (struct omp_region *region,
                        enum built_in_function start_fn,
                        enum built_in_function next_fn)
 {
-  tree l0, l1, l2, l3;
+  tree l0, l1, l2 = NULL, l3 = NULL;
   tree type, istart0, iend0, iend;
   tree t, args, list;
-  basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l3_bb;
+  basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
+  basic_block l2_bb = NULL, l3_bb = NULL;
   block_stmt_iterator si;
   bool in_combined_parallel = is_combined_parallel (region);
 
@@ -2589,18 +2594,25 @@ expand_omp_for_generic (struct omp_region *region,
   TREE_ADDRESSABLE (istart0) = 1;
   TREE_ADDRESSABLE (iend0) = 1;
 
+  gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
+
   entry_bb = region->entry;
   l0_bb = create_empty_bb (entry_bb);
   l1_bb = single_succ (entry_bb);
-  cont_bb = region->cont;
-  l2_bb = create_empty_bb (cont_bb);
-  l3_bb = single_succ (cont_bb);
-  exit_bb = region->exit;
 
   l0 = tree_block_label (l0_bb);
   l1 = tree_block_label (l1_bb);
-  l2 = tree_block_label (l2_bb);
-  l3 = tree_block_label (l3_bb);
+
+  cont_bb = region->cont;
+  exit_bb = region->exit;
+  if (cont_bb)
+    {
+      l2_bb = create_empty_bb (cont_bb);
+      l3_bb = single_succ (cont_bb);
+
+      l2 = tree_block_label (l2_bb);
+      l3 = tree_block_label (l3_bb);
+    }
 
   si = bsi_last (entry_bb);
   gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
@@ -2626,9 +2638,12 @@ expand_omp_for_generic (struct omp_region *region,
       args = tree_cons (NULL, t, args);
       t = build_function_call_expr (built_in_decls[start_fn], args);
       t = get_formal_tmp_var (t, &list);
-      t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
-                 build_and_jump (&l3));
-      append_to_statement_list (t, &list);
+      if (cont_bb)
+       {
+         t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
+                     build_and_jump (&l3));
+         append_to_statement_list (t, &list);
+       }
       bsi_insert_after (&si, list, BSI_SAME_STMT);
     }
   bsi_remove (&si, true);
@@ -2646,6 +2661,15 @@ expand_omp_for_generic (struct omp_region *region,
   si = bsi_start (l0_bb);
   bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
 
+  /* Handle the rare case where BODY doesn't ever return.  */
+  if (cont_bb == NULL)
+    {
+      remove_edge (single_succ_edge (entry_bb));
+      make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
+      make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
+      return;
+    }
+
   /* Code to control the increment and predicate for the sequential
      loop goes in the first half of EXIT_BB (we split EXIT_BB so
      that we can inherit all the edges going out of the loop
@@ -3098,7 +3122,10 @@ expand_omp_for (struct omp_region *region)
   extract_omp_for_data (last_stmt (region->entry), &fd);
   region->sched_kind = fd.sched_kind;
 
-  if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC && !fd.have_ordered)
+  if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
+      && !fd.have_ordered
+      && region->cont
+      && region->exit)
     {
       if (fd.chunk_size == NULL)
        expand_omp_for_static_nochunk (region, &fd);
@@ -3156,15 +3183,28 @@ expand_omp_sections (struct omp_region *region)
 
   entry_bb = region->entry;
   l0_bb = create_empty_bb (entry_bb);
+  l0 = tree_block_label (l0_bb);
+
+  gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
   l1_bb = region->cont;
-  l2_bb = single_succ (l1_bb);
-  default_bb = create_empty_bb (l1_bb->prev_bb);
-  exit_bb = region->exit;
+  if (l1_bb)
+    {
+      l2_bb = single_succ (l1_bb);
+      default_bb = create_empty_bb (l1_bb->prev_bb);
 
-  l0 = tree_block_label (l0_bb);
-  l1 = tree_block_label (l1_bb);
+      l1 = tree_block_label (l1_bb);
+    }
+  else
+    {
+      l2_bb = create_empty_bb (l0_bb);
+      default_bb = l2_bb;
+
+      l1 = NULL;
+    }
   l2 = tree_block_label (l2_bb);
 
+  exit_bb = region->exit;
+
   v = create_tmp_var (unsigned_type_node, ".section");
 
   /* We will build a switch() with enough cases for all the
@@ -3201,7 +3241,7 @@ expand_omp_sections (struct omp_region *region)
              build_int_cst (unsigned_type_node, 0), NULL, l2);
   TREE_VEC_ELT (label_vec, 0) = t;
   make_edge (l0_bb, l2_bb, 0);
-  
+
   /* Convert each OMP_SECTION into a CASE_LABEL_EXPR.  */
   for (inner = region->inner, i = 1; inner; inner = inner->next, ++i)
     {
@@ -3220,15 +3260,19 @@ expand_omp_sections (struct omp_region *region)
       gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
       bsi_remove (&si, true);
 
-      si = bsi_last (s_exit_bb);
-      gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
-      bsi_remove (&si, true);
-
       e = single_pred_edge (s_entry_bb);
       e->flags = 0;
       redirect_edge_pred (e, l0_bb);
 
       single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
+
+      if (s_exit_bb == NULL)
+       continue;
+
+      si = bsi_last (s_exit_bb);
+      gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
+      bsi_remove (&si, true);
+
       single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
     }
 
@@ -3244,24 +3288,30 @@ expand_omp_sections (struct omp_region *region)
   bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
 
   /* Code to get the next section goes in L1_BB.  */
-  si = bsi_last (l1_bb);
-  gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
+  if (l1_bb)
+    {
+      si = bsi_last (l1_bb);
+      gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
 
-  t = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
-  t = build_function_call_expr (t, NULL);
-  t = build2 (MODIFY_EXPR, void_type_node, v, t);
-  bsi_insert_after (&si, t, BSI_SAME_STMT);
-  bsi_remove (&si, true);
+      t = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
+      t = build_function_call_expr (t, NULL);
+      t = build2 (MODIFY_EXPR, void_type_node, v, t);
+      bsi_insert_after (&si, t, BSI_SAME_STMT);
+      bsi_remove (&si, true);
+    }
 
   /* Cleanup function replaces OMP_RETURN in EXIT_BB.  */
-  si = bsi_last (exit_bb);
-  if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
-    t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
-  else
-    t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
-  t = build_function_call_expr (t, NULL);
-  bsi_insert_after (&si, t, BSI_SAME_STMT);
-  bsi_remove (&si, true);
+  if (exit_bb)
+    {
+      si = bsi_last (exit_bb);
+      if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
+       t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
+      else
+       t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
+      t = build_function_call_expr (t, NULL);
+      bsi_insert_after (&si, t, BSI_SAME_STMT);
+      bsi_remove (&si, true);
+    }
 
   /* Connect the new blocks.  */
   if (is_combined_parallel (region))
@@ -3274,9 +3324,12 @@ expand_omp_sections (struct omp_region *region)
   else
     make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
 
-  e = single_succ_edge (l1_bb);
-  redirect_edge_succ (e, l0_bb);
-  e->flags = EDGE_FALLTHRU;
+  if (l1_bb)
+    {
+      e = single_succ_edge (l1_bb);
+      redirect_edge_succ (e, l0_bb);
+      e->flags = EDGE_FALLTHRU;
+    }
 }
 
 
@@ -3337,10 +3390,13 @@ expand_omp_synch (struct omp_region *region)
   bsi_remove (&si, true);
   single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
 
-  si = bsi_last (exit_bb);
-  gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
-  bsi_remove (&si, true);
-  single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
+  if (exit_bb)
+    {
+      si = bsi_last (exit_bb);
+      gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
+      bsi_remove (&si, true);
+      single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
+    }
 }
 
 
index c460815..fadccd7 100644 (file)
@@ -1,3 +1,23 @@
+2006-12-04  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/29965
+       * gcc.dg/gomp/pr29965-1.c: New test.
+       * gcc.dg/gomp/pr29965-2.c: New test.
+       * gcc.dg/gomp/pr29965-3.c: New test.
+       * gcc.dg/gomp/pr29965-4.c: New test.
+       * gcc.dg/gomp/pr29965-5.c: New test.
+       * gcc.dg/gomp/pr29965-6.c: New test.
+       * g++.dg/gomp/pr29965-1.C: New test.
+       * g++.dg/gomp/pr29965-2.C: New test.
+       * g++.dg/gomp/pr29965-3.C: New test.
+       * g++.dg/gomp/pr29965-4.C: New test.
+       * g++.dg/gomp/pr29965-5.C: New test.
+       * g++.dg/gomp/pr29965-6.C: New test.
+       * g++.dg/gomp/pr29965-7.C: New test.
+       * g++.dg/gomp/pr29965-8.C: New test.
+       * g++.dg/gomp/pr29965-9.C: New test.
+       * g++.dg/gomp/pr29965-10.C: New test.
+
 2006-12-04  Eric Botcazou  <ebotcazou@adacore.com>
 
        * gnat.dg/pointer_variable_bounds.adb: New test.
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-1.C b/gcc/testsuite/g++.dg/gomp/pr29965-1.C
new file mode 100644 (file)
index 0000000..efb89ff
--- /dev/null
@@ -0,0 +1,45 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+static inline void
+foo ()
+{
+#pragma omp parallel
+  for (;;)
+    ;
+}
+
+static inline void
+bar ()
+{
+#pragma omp parallel
+  baz ();
+}
+
+void
+foo1 ()
+{
+  foo ();
+}
+
+void
+foo2 ()
+{
+  foo ();
+}
+
+void
+bar1 ()
+{
+  bar ();
+}
+
+void
+bar2 ()
+{
+  bar ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-10.C b/gcc/testsuite/g++.dg/gomp/pr29965-10.C
new file mode 100644 (file)
index 0000000..2e816da
--- /dev/null
@@ -0,0 +1,24 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// This is invalid code, but we don't emit diagnostics for it, nevertheless
+// we test that we don't ICE on it.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+void
+foo1 ()
+{
+  int i;
+#pragma omp for schedule (static)
+  for (i = 0; i < 2834; i++)
+    throw 0;
+}
+
+void
+foo2 ()
+{
+  int i;
+#pragma omp parallel for schedule (static)
+  for (i = 0; i < 2834; i++)
+    throw 0;
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-2.C b/gcc/testsuite/g++.dg/gomp/pr29965-2.C
new file mode 100644 (file)
index 0000000..0976ca7
--- /dev/null
@@ -0,0 +1,98 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+void
+foo1 ()
+{
+#pragma omp sections
+  {
+    for (;;)
+      ;
+  }
+}
+
+void
+bar1 ()
+{
+#pragma omp sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    baz ();
+  }
+}
+
+void
+foo2 ()
+{
+#pragma omp sections
+  {
+    ;
+#pragma omp section
+    for (;;)
+      ;    
+  }
+}
+
+void
+bar2 ()
+{
+#pragma omp sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    ;
+  }
+}
+
+void
+foo3 ()
+{
+#pragma omp parallel sections
+  {
+    for (;;)
+      ;
+  }
+}
+
+void
+bar3 ()
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    baz ();
+  }
+}
+
+void
+foo4 ()
+{
+#pragma omp parallel sections
+  {
+    ;
+#pragma omp section
+    for (;;)
+      ;    
+  }
+}
+
+void
+bar4 ()
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    ;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-3.C b/gcc/testsuite/g++.dg/gomp/pr29965-3.C
new file mode 100644 (file)
index 0000000..b98c24e
--- /dev/null
@@ -0,0 +1,62 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+void
+foo1 ()
+{
+#pragma omp single
+  for (;;);
+}
+
+void
+bar1 ()
+{
+#pragma omp single
+  baz ();
+}
+
+void
+foo2 ()
+{
+#pragma omp master
+  for (;;);
+}
+
+void
+bar2 ()
+{
+#pragma omp master
+  baz ();
+}
+
+void
+foo3 ()
+{
+#pragma omp ordered
+  for (;;);
+}
+
+void
+bar3 ()
+{
+#pragma omp ordered
+  baz ();
+}
+
+void
+foo4 ()
+{
+#pragma omp critical
+  for (;;);
+}
+
+void
+bar4 ()
+{
+#pragma omp critical
+  baz ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-4.C b/gcc/testsuite/g++.dg/gomp/pr29965-4.C
new file mode 100644 (file)
index 0000000..b044fdf
--- /dev/null
@@ -0,0 +1,44 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+void
+foo1 ()
+{
+  int i;
+#pragma omp for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 ()
+{
+  int i;
+#pragma omp for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 ()
+{
+  int i;
+#pragma omp parallel for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 ()
+{
+  int i;
+#pragma omp parallel for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-5.C b/gcc/testsuite/g++.dg/gomp/pr29965-5.C
new file mode 100644 (file)
index 0000000..cf91dd6
--- /dev/null
@@ -0,0 +1,44 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+void
+foo1 ()
+{
+  int i;
+#pragma omp for schedule (static)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 ()
+{
+  int i;
+#pragma omp for schedule (static)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 ()
+{
+  int i;
+#pragma omp parallel for schedule (static)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 ()
+{
+  int i;
+#pragma omp parallel for schedule (static)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-6.C b/gcc/testsuite/g++.dg/gomp/pr29965-6.C
new file mode 100644 (file)
index 0000000..6384d09
--- /dev/null
@@ -0,0 +1,44 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+extern void baz () __attribute__ ((noreturn));
+
+void
+foo1 ()
+{
+  int i;
+#pragma omp for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 ()
+{
+  int i;
+#pragma omp for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 ()
+{
+  int i;
+#pragma omp parallel for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 ()
+{
+  int i;
+#pragma omp parallel for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-7.C b/gcc/testsuite/g++.dg/gomp/pr29965-7.C
new file mode 100644 (file)
index 0000000..be7d6ae
--- /dev/null
@@ -0,0 +1,32 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// This is invalid code, but we don't emit diagnostics for it, nevertheless
+// we test that we don't ICE on it.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+void
+foo ()
+{
+#pragma omp parallel
+  throw 0;
+}
+
+static inline void
+bar ()
+{
+#pragma omp parallel
+  throw 0;
+}
+
+void
+bar1 ()
+{
+  bar ();
+}
+
+void
+bar2 ()
+{
+  bar ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-8.C b/gcc/testsuite/g++.dg/gomp/pr29965-8.C
new file mode 100644 (file)
index 0000000..b2a3528
--- /dev/null
@@ -0,0 +1,94 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// This is invalid code, but we don't emit diagnostics for it, nevertheless
+// we test that we don't ICE on it.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+void
+foo1 ()
+{
+#pragma omp sections
+  {
+    throw 0;
+  }
+}
+
+void
+bar1 ()
+{
+#pragma omp sections
+  {
+#pragma omp section
+    throw 0;
+#pragma omp section
+    throw 0;
+  }
+}
+
+void
+foo2 ()
+{
+#pragma omp sections
+  {
+    ;
+#pragma omp section
+    throw 0;
+  }
+}
+
+void
+bar2 ()
+{
+#pragma omp sections
+  {
+#pragma omp section
+    throw 0;
+#pragma omp section
+    ;
+  }
+}
+
+void
+foo3 ()
+{
+#pragma omp parallel sections
+  {
+    throw 0;
+  }
+}
+
+void
+bar3 ()
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    throw 0;
+#pragma omp section
+    throw 0;
+  }
+}
+
+void
+foo4 ()
+{
+#pragma omp parallel sections
+  {
+    ;
+#pragma omp section
+    throw 0;
+  }
+}
+
+void
+bar4 ()
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    throw 0;
+#pragma omp section
+    ;
+  }
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr29965-9.C b/gcc/testsuite/g++.dg/gomp/pr29965-9.C
new file mode 100644 (file)
index 0000000..b66a247
--- /dev/null
@@ -0,0 +1,34 @@
+// PR middle-end/29965
+// Test that OpenMP construct bodies which never return don't cause ICEs.
+// This is invalid code, but we don't emit diagnostics for it, nevertheless
+// we test that we don't ICE on it.
+// { dg-do compile }
+// { dg-options "-O2 -fopenmp" }
+
+void
+foo1 ()
+{
+#pragma omp single
+  throw 0;
+}
+
+void
+foo2 ()
+{
+#pragma omp master
+  throw 0;
+}
+
+void
+foo3 ()
+{
+#pragma omp ordered
+  throw 0;
+}
+
+void
+foo4 ()
+{
+#pragma omp critical
+  throw 0;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-1.c b/gcc/testsuite/gcc.dg/gomp/pr29965-1.c
new file mode 100644 (file)
index 0000000..b587d81
--- /dev/null
@@ -0,0 +1,45 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+static inline void
+foo (void)
+{
+#pragma omp parallel
+  for (;;)
+    ;
+}
+
+static inline void
+bar (void)
+{
+#pragma omp parallel
+  baz ();
+}
+
+void
+foo1 (void)
+{
+  foo ();
+}
+
+void
+foo2 (void)
+{
+  foo ();
+}
+
+void
+bar1 (void)
+{
+  bar ();
+}
+
+void
+bar2 (void)
+{
+  bar ();
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-2.c b/gcc/testsuite/gcc.dg/gomp/pr29965-2.c
new file mode 100644 (file)
index 0000000..1bee485
--- /dev/null
@@ -0,0 +1,98 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+void
+foo1 (void)
+{
+#pragma omp sections
+  {
+    for (;;)
+      ;
+  }
+}
+
+void
+bar1 (void)
+{
+#pragma omp sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    baz ();
+  }
+}
+
+void
+foo2 (void)
+{
+#pragma omp sections
+  {
+    ;
+#pragma omp section
+    for (;;)
+      ;    
+  }
+}
+
+void
+bar2 (void)
+{
+#pragma omp sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    ;
+  }
+}
+
+void
+foo3 (void)
+{
+#pragma omp parallel sections
+  {
+    for (;;)
+      ;
+  }
+}
+
+void
+bar3 (void)
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    baz ();
+  }
+}
+
+void
+foo4 (void)
+{
+#pragma omp parallel sections
+  {
+    ;
+#pragma omp section
+    for (;;)
+      ;    
+  }
+}
+
+void
+bar4 (void)
+{
+#pragma omp parallel sections
+  {
+#pragma omp section
+    baz ();
+#pragma omp section
+    ;
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-3.c b/gcc/testsuite/gcc.dg/gomp/pr29965-3.c
new file mode 100644 (file)
index 0000000..5901f5f
--- /dev/null
@@ -0,0 +1,62 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+void
+foo1 (void)
+{
+#pragma omp single
+  for (;;);
+}
+
+void
+bar1 (void)
+{
+#pragma omp single
+  baz ();
+}
+
+void
+foo2 (void)
+{
+#pragma omp master
+  for (;;);
+}
+
+void
+bar2 (void)
+{
+#pragma omp master
+  baz ();
+}
+
+void
+foo3 (void)
+{
+#pragma omp ordered
+  for (;;);
+}
+
+void
+bar3 (void)
+{
+#pragma omp ordered
+  baz ();
+}
+
+void
+foo4 (void)
+{
+#pragma omp critical
+  for (;;);
+}
+
+void
+bar4 (void)
+{
+#pragma omp critical
+  baz ();
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-4.c b/gcc/testsuite/gcc.dg/gomp/pr29965-4.c
new file mode 100644 (file)
index 0000000..7416d8e
--- /dev/null
@@ -0,0 +1,44 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+void
+foo1 (void)
+{
+  int i;
+#pragma omp for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 (void)
+{
+  int i;
+#pragma omp for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (dynamic)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-5.c b/gcc/testsuite/gcc.dg/gomp/pr29965-5.c
new file mode 100644 (file)
index 0000000..a948ec9
--- /dev/null
@@ -0,0 +1,44 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+void
+foo1 (void)
+{
+  int i;
+#pragma omp for schedule (static)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 (void)
+{
+  int i;
+#pragma omp for schedule (static)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (static)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (static)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/pr29965-6.c b/gcc/testsuite/gcc.dg/gomp/pr29965-6.c
new file mode 100644 (file)
index 0000000..6f69478
--- /dev/null
@@ -0,0 +1,44 @@
+/* PR middle-end/29965 */
+/* Test that OpenMP construct bodies which never return don't cause ICEs.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp" } */
+
+extern void baz (void) __attribute__ ((noreturn));
+
+void
+foo1 (void)
+{
+  int i;
+#pragma omp for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar1 (void)
+{
+  int i;
+#pragma omp for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}
+
+void
+foo2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    for (;;)
+      ;
+}
+
+void
+bar2 (void)
+{
+  int i;
+#pragma omp parallel for schedule (static, 16)
+  for (i = 0; i < 2834; i++)
+    baz ();
+}