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
This commit is contained in:
parent
9d8b4d1ce9
commit
2044a4c3cc
7 changed files with 197 additions and 38 deletions
|
@ -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
|
||||
|
|
120
gcc/omp-low.c
120
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))
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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
|
||||
{
|
||||
/* 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));
|
||||
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
|
||||
if (TYPE_P (*tp))
|
||||
*walk_subtrees = 0;
|
||||
}
|
||||
|
||||
if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
|
||||
tree repl = NULL_TREE;
|
||||
if (cand)
|
||||
repl = unshare_expr (cand->new_decl);
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (tp != orig_tp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
19
gcc/testsuite/c-c++-common/gomp/pr60823-1.c
Normal file
19
gcc/testsuite/c-c++-common/gomp/pr60823-1.c
Normal file
|
@ -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;
|
||||
}
|
43
gcc/testsuite/c-c++-common/gomp/pr60823-2.c
Normal file
43
gcc/testsuite/c-c++-common/gomp/pr60823-2.c
Normal file
|
@ -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;
|
||||
}
|
32
gcc/testsuite/c-c++-common/gomp/pr60823-3.c
Normal file
32
gcc/testsuite/c-c++-common/gomp/pr60823-3.c
Normal file
|
@ -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
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue