From c34938a8aa48af61df1835c2c0dab95d4ef6ca1a Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 12 Jun 2008 13:03:50 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++ gcc/omp-low.c | 34 +++++++++- libgomp/ChangeLog | 5 ++ libgomp/testsuite/libgomp.c/reduction-5.c | 78 +++++++++++++++++++++++ 4 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 libgomp/testsuite/libgomp.c/reduction-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb6c434e6ff..f2c51854bcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-06-12 Jakub Jelinek + + PR middle-end/36506 + * omp-low.c (expand_omp_sections): Handle #pragma omp sections with + reductions. + 2008-06-12 Richard Guenther PR tree-optimization/36345 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; diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index fb70823cfcc..ff9ed0374c9 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2008-06-12 Jakub Jelinek + + PR middle-end/36506 + * testsuite/libgomp.c/reduction-5.c: New test. + 2008-06-11 Jakub Jelinek * 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 00000000000..de87d9f6dc8 --- /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; +} -- 2.30.2