aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-06-12 13:03:50 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2008-06-12 13:03:50 +0200
commitc34938a8aa48af61df1835c2c0dab95d4ef6ca1a (patch)
tree8845c75445d9484761a9f34010411ff92b5aefca
parentb377855627f22cdef5712621e89e68048a94a164 (diff)
downloadgcc-c34938a8aa48af61df1835c2c0dab95d4ef6ca1a.zip
gcc-c34938a8aa48af61df1835c2c0dab95d4ef6ca1a.tar.gz
gcc-c34938a8aa48af61df1835c2c0dab95d4ef6ca1a.tar.bz2
re PR middle-end/36506 (Broken #pragma omp sections reduction (+:x))
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/omp-low.c34
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--libgomp/testsuite/libgomp.c/reduction-5.c78
4 files changed, 121 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eb6c434e6..f2c5185 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e9223b2..85b8333 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -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;
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index fb70823c..ff9ed03 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -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
index 0000000..de87d9f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/reduction-5.c
@@ -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;
+}