re PR middle-end/36506 (Broken #pragma omp sections reduction (+:x))
authorJakub Jelinek <jakub@redhat.com>
Thu, 12 Jun 2008 11:03:50 +0000 (13:03 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 12 Jun 2008 11:03:50 +0000 (13:03 +0200)
PR middle-end/36506
* omp-low.c (expand_omp_sections): Handle #pragma omp sections with
reductions.

* testsuite/libgomp.c/reduction-5.c: New test.

From-SVN: r136696

gcc/ChangeLog
gcc/omp-low.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.c/reduction-5.c [new file with mode: 0644]

index eb6c434e6ff09353f3343dc8a7c21fa71b6ca5da..f2c51854bcd63458a6218afe835fcfb3a6c25fea 100644 (file)
@@ -1,3 +1,9 @@
+2008-06-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/36506
+       * omp-low.c (expand_omp_sections): Handle #pragma omp sections with
+       reductions.
+
 2008-06-12  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/36345
index e9223b2afb208747dbc70e75c1a2c039527d596b..85b83332ff80614dde1c7c1522fbc76e447793d4 100644 (file)
@@ -4389,6 +4389,8 @@ expand_omp_sections (struct omp_region *region)
   unsigned i, casei, len;
   basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
   block_stmt_iterator si;
+  edge_iterator ei;
+  edge e;
   struct omp_region *inner;
   bool exit_reachable = region->cont != NULL;
 
@@ -4399,10 +4401,30 @@ expand_omp_sections (struct omp_region *region)
   l2_bb = region->exit;
   if (exit_reachable)
     {
-      gcc_assert (single_pred (l2_bb) == l0_bb);
+      if (single_pred (l2_bb) == l0_bb)
+       l2 = tree_block_label (l2_bb);
+      else
+       {
+         /* This can happen if there are reductions.  */
+         len = EDGE_COUNT (l0_bb->succs);
+         gcc_assert (len > 0);
+         e = EDGE_SUCC (l0_bb, len - 1);
+         si = bsi_last (e->dest);
+         if (bsi_end_p (si) || TREE_CODE (bsi_stmt (si)) != OMP_SECTION)
+           l2 = tree_block_label (e->dest);
+         else
+           FOR_EACH_EDGE (e, ei, l0_bb->succs)
+             {
+               si = bsi_last (e->dest);
+               if (bsi_end_p (si) || TREE_CODE (bsi_stmt (si)) != OMP_SECTION)
+                 {
+                   l2 = tree_block_label (e->dest);
+                   break;
+                 }
+             }
+       }
       default_bb = create_empty_bb (l1_bb->prev_bb);
       l1 = tree_block_label (l1_bb);
-      l2 = tree_block_label (l2_bb);
     }
   else
     {
@@ -4480,6 +4502,14 @@ expand_omp_sections (struct omp_region *region)
     {
       basic_block s_entry_bb, s_exit_bb;
 
+      /* Skip optional reduction region.  */
+      if (inner->type == OMP_ATOMIC_LOAD)
+       {
+         --i;
+         --casei;
+         continue;
+       }
+
       s_entry_bb = inner->entry;
       s_exit_bb = inner->exit;
 
index fb70823cfcc44cf3de62a62c73eaee3e0f8f9d4b..ff9ed0374c935f80029a31b550e6a26118c2e6c3 100644 (file)
@@ -1,3 +1,8 @@
+2008-06-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/36506
+       * testsuite/libgomp.c/reduction-5.c: New test.
+
 2008-06-11  Jakub Jelinek  <jakub@redhat.com>
 
        * libgomp.h (struct gomp_task): Add in_tied_task field.
diff --git a/libgomp/testsuite/libgomp.c/reduction-5.c b/libgomp/testsuite/libgomp.c/reduction-5.c
new file mode 100644 (file)
index 0000000..de87d9f
--- /dev/null
@@ -0,0 +1,78 @@
+/* PR middle-end/36506 */
+
+extern void abort (void);
+
+int
+main (void)
+{
+  int sum = 0, prod = 1;
+#pragma omp parallel
+  #pragma omp sections reduction (+:sum)
+    {
+    #pragma omp section
+      sum += 2;
+    #pragma omp section
+      sum += 2;
+    #pragma omp section
+      sum += 2;
+    }
+  if (sum != 6)
+    abort ();
+  sum = 0;
+#pragma omp parallel sections reduction (+:sum)
+  {
+  #pragma omp section
+    sum += 2;
+  #pragma omp section
+    sum += 2;
+  #pragma omp section
+    sum += 2;
+  }
+  if (sum != 6)
+    abort ();
+  sum = 0;
+#pragma omp parallel
+  #pragma omp sections reduction (+:sum) reduction (*:prod)
+    {
+    #pragma omp section
+      {
+       sum += 2;
+       prod *= 2;
+      }
+    #pragma omp section
+      {
+       sum += 2;
+       prod *= 2;
+      }
+    #pragma omp section
+      {
+       sum += 2;
+       prod *= 2;
+      }
+    }
+  if (sum != 6 || prod != 8)
+    abort ();
+  sum = 0;
+  prod = 1;
+#pragma omp parallel sections reduction (+:sum) reduction (*:prod)
+  {
+  #pragma omp section
+    {
+      sum += 2;
+      prod *= 2;
+    }
+  #pragma omp section
+    {
+      sum += 2;
+      prod *= 2;
+    }
+  #pragma omp section
+    {
+      sum += 2;
+      prod *= 2;
+    }
+  }
+  if (sum != 6 || prod != 8)
+    abort ();
+  return 0;
+}