diff options
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/omp-low.c | 59 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/gomp/pr59150.C | 25 |
4 files changed, 82 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b04f539..0d97d2e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2013-11-26 Jakub Jelinek <jakub@redhat.com> + PR middle-end/59150 + * omp-low.c (lower_rec_input_clause): For reduction with placeholder + of references to constant size types in simd loops, defer emitting + initializer for the new_var, emit it later on only if not using + SIMD arrays for it. + PR middle-end/59152 * omp-low.c (expand_omp_for_static_chunk): Don't set loop->latch for the inner loop if collapse_bb is non-NULL. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 7abe456..b980825 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3185,15 +3185,26 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, } else if (TREE_CONSTANT (x)) { - const char *name = NULL; - if (DECL_NAME (var)) - name = IDENTIFIER_POINTER (DECL_NAME (new_var)); - - x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)), - name); - gimple_add_tmp_var (x); - TREE_ADDRESSABLE (x) = 1; - x = build_fold_addr_expr_loc (clause_loc, x); + /* For reduction with placeholder in SIMD loop, + defer adding the initialization of the reference, + because if we decide to use SIMD array for it, + the initilization could cause expansion ICE. */ + if (c_kind == OMP_CLAUSE_REDUCTION + && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) + && is_simd) + x = NULL_TREE; + else + { + const char *name = NULL; + if (DECL_NAME (var)) + name = IDENTIFIER_POINTER (DECL_NAME (new_var)); + + x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)), + name); + gimple_add_tmp_var (x); + TREE_ADDRESSABLE (x) = 1; + x = build_fold_addr_expr_loc (clause_loc, x); + } } else { @@ -3201,8 +3212,11 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, x = build_call_expr_loc (clause_loc, atmp, 1, x); } - x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x); - gimplify_assign (new_var, x, ilist); + if (x) + { + x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x); + gimplify_assign (new_var, x, ilist); + } new_var = build_simple_mem_ref_loc (clause_loc, new_var); } @@ -3500,6 +3514,29 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist, } break; } + /* If this is a reference to constant size reduction var + with placeholder, we haven't emitted the initializer + for it because it is undesirable if SIMD arrays are used. + But if they aren't used, we need to emit the deferred + initialization now. */ + else if (is_reference (var) && is_simd) + { + tree z + = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard))); + if (TREE_CONSTANT (z)) + { + const char *name = NULL; + if (DECL_NAME (var)) + name = IDENTIFIER_POINTER (DECL_NAME (new_vard)); + + z = create_tmp_var_raw + (TREE_TYPE (TREE_TYPE (new_vard)), name); + gimple_add_tmp_var (z); + TREE_ADDRESSABLE (z) = 1; + z = build_fold_addr_expr_loc (clause_loc, z); + gimplify_assign (new_vard, z, ilist); + } + } x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, unshare_expr (x)); if (x) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 26b50d1..a23c397 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2013-11-26 Jakub Jelinek <jakub@redhat.com> + PR middle-end/59150 + * g++.dg/gomp/pr59150.C: New test. + PR middle-end/59152 * c-c++-common/gomp/pr59152.c: New test. diff --git a/gcc/testsuite/g++.dg/gomp/pr59150.C b/gcc/testsuite/g++.dg/gomp/pr59150.C new file mode 100644 index 0000000..103edb6 --- /dev/null +++ b/gcc/testsuite/g++.dg/gomp/pr59150.C @@ -0,0 +1,25 @@ +// PR middle-end/59150 +// { dg-do compile } +// { dg-options "-O -fopenmp-simd -fno-tree-ccp -fno-tree-copy-prop -fno-tree-dce" } + +#pragma omp declare reduction (foo: int: omp_out += omp_in) initializer (omp_priv = 0) + +int +foo () +{ + int i, v, &u = v; + #pragma omp simd reduction (foo:u) + for (i = 0; i < 1024; i++) + u = i; + return u; +} + +int +bar () +{ + int i, v, &u = v; + #pragma omp simd reduction (foo:u) safelen(1) + for (i = 0; i < 1024; i++) + u = i; + return u; +} |