diff --git a/gcc/ChangeLog b/gcc/ChangeLog index accfc234e32..a3821a88a80 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,13 @@ +2013-12-16 Jakub Jelinek + + PR libgomp/58756 + * omp-low.c (lower_rec_input_clauses) : For + reductions without placeholder if is_simd, but when not using + GOMP_SIMD* internal calls, also perform the reduction operation + on the outer var rather than simple assignment. + 2013-12-16 Yuri Rumyantsev + * config/i386/i386.c (slm_cost): Fix imul cost for HI. 2013-12-16 Jakub Jelinek diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 05fca4096fc..97092dd0894 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3565,20 +3565,21 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, { x = omp_reduction_init (c, TREE_TYPE (new_var)); gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE); + enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c); + + /* reduction(-:var) sums up the partial results, so it + acts identically to reduction(+:var). */ + if (code == MINUS_EXPR) + code = PLUS_EXPR; + if (is_simd && lower_rec_simd_input_clauses (new_var, ctx, max_vf, idx, lane, ivar, lvar)) { - enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c); tree ref = build_outer_var_ref (var, ctx); gimplify_assign (unshare_expr (ivar), x, &llist[0]); - /* reduction(-:var) sums up the partial results, so it - acts identically to reduction(+:var). */ - if (code == MINUS_EXPR) - code = PLUS_EXPR; - x = build2 (code, TREE_TYPE (ref), ref, ivar); ref = build_outer_var_ref (var, ctx); gimplify_assign (ref, x, &llist[1]); @@ -3587,8 +3588,13 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, { gimplify_assign (new_var, x, ilist); if (is_simd) - gimplify_assign (build_outer_var_ref (var, ctx), - new_var, dlist); + { + tree ref = build_outer_var_ref (var, ctx); + + x = build2 (code, TREE_TYPE (ref), ref, new_var); + ref = build_outer_var_ref (var, ctx); + gimplify_assign (ref, x, dlist); + } } } break; diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog index bdcc930d97b..566a4c12752 100644 --- a/libgomp/ChangeLog +++ b/libgomp/ChangeLog @@ -1,3 +1,8 @@ +2013-12-16 Jakub Jelinek + + PR libgomp/58756 + * testsuite/libgomp.c/pr58756.c: New test. + 2013-12-12 Jakub Jelinek PR libgomp/59467 diff --git a/libgomp/testsuite/libgomp.c/pr58756.c b/libgomp/testsuite/libgomp.c/pr58756.c new file mode 100644 index 00000000000..d35ea792e8d --- /dev/null +++ b/libgomp/testsuite/libgomp.c/pr58756.c @@ -0,0 +1,58 @@ +/* PR libgomp/58756 */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-msse2" { target sse2_runtime } } */ +/* { dg-additional-options "-mavx" { target avx_runtime } } */ + +extern void abort (void); +int d[32 * 32]; + +__attribute__((noinline, noclone)) int +foo (int a, int b) +{ + int j, c = 0; + #pragma omp parallel for reduction(+: c) + for (j = 0; j < a; j += 32) + { + int l; + #pragma omp simd reduction(+: c) safelen(1) + for (l = 0; l < b; ++l) + c += d[j + l]; + } + return c; +} + +__attribute__((noinline, noclone)) int +bar (int a) +{ + int j, c = 0; + #pragma omp parallel for simd reduction(+: c) safelen(1) + for (j = 0; j < a; ++j) + c += d[j]; + return c; +} + +__attribute__((noinline)) static int +baz (int a) +{ + int j, c = 0; + #pragma omp simd reduction(+: c) safelen(1) + for (j = 0; j < a; ++j) + c += d[j]; + return c; +} + +int +main () +{ + int i; + for (i = 0; i < 32 * 32; i++) + d[i] = (i & 31); + if (foo (32 * 32, 32) != (31 * 32 / 2) * 32) + abort (); + if (bar (32 * 32) != (31 * 32 / 2) * 32) + abort (); + if (baz (32 * 32) != (31 * 32 / 2) * 32) + abort (); + return 0; +}