diff options
author | Jakub Jelinek <jakub@redhat.com> | 2014-04-22 12:21:32 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2014-04-22 12:21:32 +0200 |
commit | 2044a4c3cc2db3697e62eea701c489378ad54947 (patch) | |
tree | 6bdbf55401c310f7e635b4e6df5d894fff74da1c | |
parent | 9d8b4d1ce91511ae92cd746c10a05e16215f1940 (diff) | |
download | gcc-2044a4c3cc2db3697e62eea701c489378ad54947.zip gcc-2044a4c3cc2db3697e62eea701c489378ad54947.tar.gz gcc-2044a4c3cc2db3697e62eea701c489378ad54947.tar.bz2 |
re PR tree-optimization/60823 (ICE in gimple_expand_cfg, at cfgexpand.c:5644)
PR tree-optimization/60823
* omp-low.c (ipa_simd_modify_function_body): Go through
all SSA_NAMEs and for those refering to vector arguments
which are going to be replaced adjust SSA_NAME_VAR and,
if it is a default definition, change it into a non-default
definition assigned at the beginning of function from new_decl.
(ipa_simd_modify_stmt_ops): Rewritten.
* tree-dfa.c (set_ssa_default_def): When removing default def,
check for NULL loc instead of NULL *loc.
* c-c++-common/gomp/pr60823-1.c: New test.
* c-c++-common/gomp/pr60823-2.c: New test.
* c-c++-common/gomp/pr60823-3.c: New test.
From-SVN: r209616
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/omp-low.c | 110 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pr60823-1.c | 19 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pr60823-2.c | 43 | ||||
-rw-r--r-- | gcc/testsuite/c-c++-common/gomp/pr60823-3.c | 32 | ||||
-rw-r--r-- | gcc/tree-dfa.c | 2 |
7 files changed, 192 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 80ffa58..e882ff8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2014-04-22 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/60823 + * omp-low.c (ipa_simd_modify_function_body): Go through + all SSA_NAMEs and for those refering to vector arguments + which are going to be replaced adjust SSA_NAME_VAR and, + if it is a default definition, change it into a non-default + definition assigned at the beginning of function from new_decl. + (ipa_simd_modify_stmt_ops): Rewritten. + * tree-dfa.c (set_ssa_default_def): When removing default def, + check for NULL loc instead of NULL *loc. + 2014-04-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> * config/arm/arm.c (arm_hard_regno_mode_ok): Loosen diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 0a46fb7..d0489e1 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -11281,45 +11281,53 @@ static tree ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data) { struct walk_stmt_info *wi = (struct walk_stmt_info *) data; - if (!SSA_VAR_P (*tp)) + struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info; + tree *orig_tp = tp; + if (TREE_CODE (*tp) == ADDR_EXPR) + tp = &TREE_OPERAND (*tp, 0); + struct ipa_parm_adjustment *cand = NULL; + if (TREE_CODE (*tp) == PARM_DECL) + cand = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true); + else { - /* Make sure we treat subtrees as a RHS. This makes sure that - when examining the `*foo' in *foo=x, the `foo' get treated as - a use properly. */ - wi->is_lhs = false; - wi->val_only = true; if (TYPE_P (*tp)) *walk_subtrees = 0; - return NULL_TREE; } - struct modify_stmt_info *info = (struct modify_stmt_info *) wi->info; - struct ipa_parm_adjustment *cand - = ipa_get_adjustment_candidate (&tp, NULL, info->adjustments, true); - if (!cand) - return NULL_TREE; - - tree t = *tp; - tree repl = make_ssa_name (TREE_TYPE (t), NULL); - gimple stmt; - gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt); - if (wi->is_lhs) + tree repl = NULL_TREE; + if (cand) + repl = unshare_expr (cand->new_decl); + else { - stmt = gimple_build_assign (unshare_expr (cand->new_decl), repl); - gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); - SSA_NAME_DEF_STMT (repl) = info->stmt; + if (tp != orig_tp) + { + *walk_subtrees = 0; + bool modified = info->modified; + info->modified = false; + walk_tree (tp, ipa_simd_modify_stmt_ops, wi, wi->pset); + if (!info->modified) + { + info->modified = modified; + return NULL_TREE; + } + info->modified = modified; + repl = *tp; + } + else + return NULL_TREE; } - else + + if (tp != orig_tp) { - /* You'd think we could skip the extra SSA variable when - wi->val_only=true, but we may have `*var' which will get - replaced into `*var_array[iter]' and will likely be something - not gimple. */ - stmt = gimple_build_assign (repl, unshare_expr (cand->new_decl)); + repl = build_fold_addr_expr (repl); + gimple stmt + = gimple_build_assign (make_ssa_name (TREE_TYPE (repl), NULL), repl); + repl = gimple_assign_lhs (stmt); + gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt); gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + *orig_tp = repl; } - - if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl))) + else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl))) { tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl); *tp = vce; @@ -11328,8 +11336,6 @@ ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data) *tp = repl; info->modified = true; - wi->is_lhs = false; - wi->val_only = true; return NULL_TREE; } @@ -11348,7 +11354,7 @@ ipa_simd_modify_function_body (struct cgraph_node *node, tree retval_array, tree iter) { basic_block bb; - unsigned int i, j; + unsigned int i, j, l; /* Re-use the adjustments array, but this time use it to replace every function argument use to an offset into the corresponding @@ -11371,6 +11377,46 @@ ipa_simd_modify_function_body (struct cgraph_node *node, j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1; } + l = adjustments.length (); + for (i = 1; i < num_ssa_names; i++) + { + tree name = ssa_name (i); + if (name + && SSA_NAME_VAR (name) + && TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL) + { + for (j = 0; j < l; j++) + if (SSA_NAME_VAR (name) == adjustments[j].base + && adjustments[j].new_decl) + { + tree base_var; + if (adjustments[j].new_ssa_base == NULL_TREE) + { + base_var + = copy_var_decl (adjustments[j].base, + DECL_NAME (adjustments[j].base), + TREE_TYPE (adjustments[j].base)); + adjustments[j].new_ssa_base = base_var; + } + else + base_var = adjustments[j].new_ssa_base; + if (SSA_NAME_IS_DEFAULT_DEF (name)) + { + bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + gimple_stmt_iterator gsi = gsi_after_labels (bb); + tree new_decl = unshare_expr (adjustments[j].new_decl); + set_ssa_default_def (cfun, adjustments[j].base, NULL_TREE); + SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var); + SSA_NAME_IS_DEFAULT_DEF (name) = 0; + gimple stmt = gimple_build_assign (name, new_decl); + gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); + } + else + SET_SSA_NAME_VAR_OR_IDENTIFIER (name, base_var); + } + } + } + struct modify_stmt_info info; info.adjustments = adjustments; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 20978b1..bee26e3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2014-04-22 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/60823 + * c-c++-common/gomp/pr60823-1.c: New test. + * c-c++-common/gomp/pr60823-2.c: New test. + * c-c++-common/gomp/pr60823-3.c: New test. + 2014-04-22 Ian Bolton <ian.bolton@arm.com> * gcc.target/arm/anddi_notdi-1.c: New test. diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-1.c b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c new file mode 100644 index 0000000..5f98572 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr60823-1.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/60823 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fopenmp-simd" } */ + +#pragma omp declare simd simdlen(4) notinbranch +int +foo (const double c1, const double c2) +{ + double z1 = c1, z2 = c2; + int res = 100, i; + + for (i = 0; i < 100; i++) + { + res = (z1 * z1 + z2 * z2 > 4.0) ? (i < res ? i : res) : res; + z1 = c1 + z1 * z1 - z2 * z2; + z2 = c2 + 2.0 * z1 * z2; + } + return res; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-2.c b/gcc/testsuite/c-c++-common/gomp/pr60823-2.c new file mode 100644 index 0000000..e0bf570 --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr60823-2.c @@ -0,0 +1,43 @@ +/* PR tree-optimization/60823 */ +/* { dg-do run } */ +/* { dg-options "-O2 -fopenmp-simd" } */ + +#pragma omp declare simd simdlen(4) notinbranch +__attribute__((noinline)) int +foo (double c1, double c2) +{ + double z1 = c1, z2 = c2; + int res = 100, i; + + for (i = 0; i < 5; i++) + { + res = (z1 * z1 + z2 * z2 > 4.0) ? (i < res ? i : res) : res; + z1 = c1 + z1 * z1 - z2 * z2; + z2 = c2 + 2.0 * z1 * z2; + c1 += 0.5; + c2 += 0.5; + } + return res; +} + +__attribute__((noinline, noclone)) void +bar (double *x, double *y) +{ + asm volatile ("" : : "rm" (x), "rm" (y) : "memory"); +} + +int +main () +{ + int i; + double c[4] = { 0.0, 1.0, 0.0, 1.0 }; + double d[4] = { 0.0, 1.0, 2.0, 0.0 }; + int e[4]; + bar (c, d); +#pragma omp simd safelen(4) + for (i = 0; i < 4; i++) + e[i] = foo (c[i], d[i]); + if (e[0] != 3 || e[1] != 1 || e[2] != 1 || e[3] != 2) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-3.c b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c new file mode 100644 index 0000000..93e9fbe --- /dev/null +++ b/gcc/testsuite/c-c++-common/gomp/pr60823-3.c @@ -0,0 +1,32 @@ +/* PR tree-optimization/60823 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fopenmp-simd -fno-strict-aliasing" } */ + +void bar (char *, double *); + +#if __SIZEOF_DOUBLE__ >= 4 + +struct S { char c[sizeof (double)]; }; +void baz (struct S, struct S); +union U { struct S s; double d; }; + +#pragma omp declare simd simdlen(4) notinbranch +__attribute__((noinline)) int +foo (double c1, double c2) +{ + double *a = &c1; + char *b = (char *) &c1 + 2; + + b[-2]++; + b[1]--; + *a++; + c2++; + bar ((char *) &c2 + 1, &c2); + c2 *= 3.0; + bar (b, a); + baz (((union U) { .d = c1 }).s, ((union U) { .d = c2 }).s); + baz (*(struct S *)&c1, *(struct S *)&c2); + return c1 + c2 + ((struct S *)&c1)->c[1]; +} + +#endif diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index fcf8d80..a1f2758 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -343,7 +343,7 @@ set_ssa_default_def (struct function *fn, tree var, tree def) { loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in, DECL_UID (var), NO_INSERT); - if (*loc) + if (loc) { SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false; htab_clear_slot (DEFAULT_DEFS (fn), loc); |