Commit 2044a4c3 by Jakub Jelinek Committed by Jakub Jelinek

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
parent 9d8b4d1c
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> 2014-04-22 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/arm.c (arm_hard_regno_mode_ok): Loosen * config/arm/arm.c (arm_hard_regno_mode_ok): Loosen
......
...@@ -11281,45 +11281,53 @@ static tree ...@@ -11281,45 +11281,53 @@ static tree
ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data) ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
{ {
struct walk_stmt_info *wi = (struct walk_stmt_info *) 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)) if (TYPE_P (*tp))
*walk_subtrees = 0; *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; tree repl = NULL_TREE;
gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt); if (cand)
if (wi->is_lhs) repl = unshare_expr (cand->new_decl);
else
{ {
stmt = gimple_build_assign (unshare_expr (cand->new_decl), repl); if (tp != orig_tp)
gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); {
SSA_NAME_DEF_STMT (repl) = info->stmt; *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 repl = build_fold_addr_expr (repl);
wi->val_only=true, but we may have `*var' which will get gimple stmt
replaced into `*var_array[iter]' and will likely be something = gimple_build_assign (make_ssa_name (TREE_TYPE (repl), NULL), repl);
not gimple. */ repl = gimple_assign_lhs (stmt);
stmt = gimple_build_assign (repl, unshare_expr (cand->new_decl)); gimple_stmt_iterator gsi = gsi_for_stmt (info->stmt);
gsi_insert_before (&gsi, stmt, GSI_SAME_STMT); gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
*orig_tp = repl;
} }
else if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
if (!useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (repl)))
{ {
tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl); tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*tp), repl);
*tp = vce; *tp = vce;
...@@ -11328,8 +11336,6 @@ ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data) ...@@ -11328,8 +11336,6 @@ ipa_simd_modify_stmt_ops (tree *tp, int *walk_subtrees, void *data)
*tp = repl; *tp = repl;
info->modified = true; info->modified = true;
wi->is_lhs = false;
wi->val_only = true;
return NULL_TREE; return NULL_TREE;
} }
...@@ -11348,7 +11354,7 @@ ipa_simd_modify_function_body (struct cgraph_node *node, ...@@ -11348,7 +11354,7 @@ ipa_simd_modify_function_body (struct cgraph_node *node,
tree retval_array, tree iter) tree retval_array, tree iter)
{ {
basic_block bb; basic_block bb;
unsigned int i, j; unsigned int i, j, l;
/* Re-use the adjustments array, but this time use it to replace /* Re-use the adjustments array, but this time use it to replace
every function argument use to an offset into the corresponding every function argument use to an offset into the corresponding
...@@ -11371,6 +11377,46 @@ ipa_simd_modify_function_body (struct cgraph_node *node, ...@@ -11371,6 +11377,46 @@ ipa_simd_modify_function_body (struct cgraph_node *node,
j += node->simdclone->simdlen / TYPE_VECTOR_SUBPARTS (vectype) - 1; 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; struct modify_stmt_info info;
info.adjustments = adjustments; info.adjustments = adjustments;
......
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> 2014-04-22 Ian Bolton <ian.bolton@arm.com>
* gcc.target/arm/anddi_notdi-1.c: New test. * gcc.target/arm/anddi_notdi-1.c: New test.
......
/* 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;
}
/* 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;
}
/* 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) ...@@ -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, loc = htab_find_slot_with_hash (DEFAULT_DEFS (fn), &in,
DECL_UID (var), NO_INSERT); DECL_UID (var), NO_INSERT);
if (*loc) if (loc)
{ {
SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false; SSA_NAME_IS_DEFAULT_DEF (*(tree *)loc) = false;
htab_clear_slot (DEFAULT_DEFS (fn), loc); htab_clear_slot (DEFAULT_DEFS (fn), loc);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment