summaryrefslogtreecommitdiff
path: root/gcc/omp-low.c
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 /gcc/omp-low.c
parentb377855627f22cdef5712621e89e68048a94a164 (diff)
downloadgcc-c34938a8aa48af61df1835c2c0dab95d4ef6ca1a.tar.gz
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
Diffstat (limited to 'gcc/omp-low.c')
-rw-r--r--gcc/omp-low.c34
1 files changed, 32 insertions, 2 deletions
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e9223b2afb2..85b83332ff8 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;