Commit 6811ea79 by Richard Biener Committed by Richard Biener

re PR tree-optimization/77648 (Setting conversion to a integer to double to 0 3/4 through a loop)

2016-09-21  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/77648
	* tree-ssa-structalias.c (process_constraint): Handle all DEREF
	with complex RHS.
	(make_transitive_closure_constraints): Adjust comment.
	(make_any_offset_constraints): New function.
	(handle_rhs_call): Make sure to first expand a pointer to all
	subfields before transitively closing it.
	(handle_const_call): Likewise.  Properly expand returned
	pointers as well.
	(handle_pure_call): Likewise.

	* gcc.dg/torture/pr77648-1.c: New testcase.
	* gcc.dg/torture/pr77648-2.c: Likewise.

From-SVN: r240303
parent f955c4c4
2016-09-21 Richard Biener <rguenther@suse.de> 2016-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/77648
* tree-ssa-structalias.c (process_constraint): Handle all DEREF
with complex RHS.
(make_transitive_closure_constraints): Adjust comment.
(make_any_offset_constraints): New function.
(handle_rhs_call): Make sure to first expand a pointer to all
subfields before transitively closing it.
(handle_const_call): Likewise. Properly expand returned
pointers as well.
(handle_pure_call): Likewise.
2016-09-21 Richard Biener <rguenther@suse.de>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/77621 PR tree-optimization/77621
......
2016-09-21 Richard Biener <rguenther@suse.de> 2016-09-21 Richard Biener <rguenther@suse.de>
PR tree-optimization/77648
* gcc.dg/torture/pr77648-1.c: New testcase.
* gcc.dg/torture/pr77648-2.c: Likewise.
2016-09-21 Richard Biener <rguenther@suse.de>
Jakub Jelinek <jakub@redhat.com> Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/77621 PR tree-optimization/77621
......
/* { dg-do run } */
struct S { int *p; int *q; };
int **__attribute__((noinline,noclone,pure)) foo (struct S *s)
{
int tem;
__asm__ ("" : "=g" (tem) : "g" (s->p));
return &s->q;
}
int main()
{
struct S s;
int i = 1, j = 2;
int **x;
s.p = &i;
s.q = &j;
x = foo (&s);
**x = 7;
if (j != 7)
__builtin_abort ();
return 0;
}
/* { dg-do run } */
struct S { int *p; int *q; };
int **__attribute__((noinline,noclone,const)) foo (struct S *s)
{
return &s->q;
}
int main()
{
struct S s;
int i = 1, j = 2;
int **x;
s.p = &i;
s.q = &j;
x = foo (&s);
**x = 7;
if (j != 7)
__builtin_abort ();
return 0;
}
...@@ -3010,7 +3010,7 @@ process_constraint (constraint_t t) ...@@ -3010,7 +3010,7 @@ process_constraint (constraint_t t)
process_constraint (new_constraint (tmplhs, rhs)); process_constraint (new_constraint (tmplhs, rhs));
process_constraint (new_constraint (lhs, tmplhs)); process_constraint (new_constraint (lhs, tmplhs));
} }
else if (rhs.type == ADDRESSOF && lhs.type == DEREF) else if ((rhs.type != SCALAR || rhs.offset != 0) && lhs.type == DEREF)
{ {
/* Split into tmp = &rhs, *lhs = tmp */ /* Split into tmp = &rhs, *lhs = tmp */
struct constraint_expr tmplhs; struct constraint_expr tmplhs;
...@@ -3747,7 +3747,7 @@ make_transitive_closure_constraints (varinfo_t vi) ...@@ -3747,7 +3747,7 @@ make_transitive_closure_constraints (varinfo_t vi)
{ {
struct constraint_expr lhs, rhs; struct constraint_expr lhs, rhs;
/* VAR = *VAR; */ /* VAR = *(VAR + UNKNOWN); */
lhs.type = SCALAR; lhs.type = SCALAR;
lhs.var = vi->id; lhs.var = vi->id;
lhs.offset = 0; lhs.offset = 0;
...@@ -3757,6 +3757,23 @@ make_transitive_closure_constraints (varinfo_t vi) ...@@ -3757,6 +3757,23 @@ make_transitive_closure_constraints (varinfo_t vi)
process_constraint (new_constraint (lhs, rhs)); process_constraint (new_constraint (lhs, rhs));
} }
/* Add constraints to that the solution of VI has all subvariables added. */
static void
make_any_offset_constraints (varinfo_t vi)
{
struct constraint_expr lhs, rhs;
/* VAR = VAR + UNKNOWN; */
lhs.type = SCALAR;
lhs.var = vi->id;
lhs.offset = 0;
rhs.type = SCALAR;
rhs.var = vi->id;
rhs.offset = UNKNOWN_OFFSET;
process_constraint (new_constraint (lhs, rhs));
}
/* Temporary storage for fake var decls. */ /* Temporary storage for fake var decls. */
struct obstack fake_var_decl_obstack; struct obstack fake_var_decl_obstack;
...@@ -3902,15 +3919,12 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) ...@@ -3902,15 +3919,12 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
&& (flags & EAF_NOESCAPE)) && (flags & EAF_NOESCAPE))
{ {
varinfo_t uses = get_call_use_vi (stmt); varinfo_t uses = get_call_use_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT)) if (!(flags & EAF_DIRECT))
{ make_transitive_closure_constraints (tem);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); make_copy_constraint (uses, tem->id);
make_constraint_to (tem->id, arg);
make_transitive_closure_constraints (tem);
make_copy_constraint (uses, tem->id);
}
else
make_constraint_to (uses->id, arg);
returns_uses = true; returns_uses = true;
} }
else if (flags & EAF_NOESCAPE) else if (flags & EAF_NOESCAPE)
...@@ -3920,6 +3934,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) ...@@ -3920,6 +3934,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
varinfo_t clobbers = get_call_clobber_vi (stmt); varinfo_t clobbers = get_call_clobber_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
make_constraint_to (tem->id, arg); make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT)) if (!(flags & EAF_DIRECT))
make_transitive_closure_constraints (tem); make_transitive_closure_constraints (tem);
make_copy_constraint (uses, tem->id); make_copy_constraint (uses, tem->id);
...@@ -3945,7 +3960,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) ...@@ -3945,7 +3960,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
if (returns_uses) if (returns_uses)
{ {
rhsc.var = get_call_use_vi (stmt)->id; rhsc.var = get_call_use_vi (stmt)->id;
rhsc.offset = 0; rhsc.offset = UNKNOWN_OFFSET;
rhsc.type = SCALAR; rhsc.type = SCALAR;
results->safe_push (rhsc); results->safe_push (rhsc);
} }
...@@ -4054,6 +4069,7 @@ handle_const_call (gcall *stmt, vec<ce_s> *results) ...@@ -4054,6 +4069,7 @@ handle_const_call (gcall *stmt, vec<ce_s> *results)
if (gimple_call_chain (stmt)) if (gimple_call_chain (stmt))
{ {
varinfo_t uses = get_call_use_vi (stmt); varinfo_t uses = get_call_use_vi (stmt);
make_any_offset_constraints (uses);
make_transitive_closure_constraints (uses); make_transitive_closure_constraints (uses);
make_constraint_to (uses->id, gimple_call_chain (stmt)); make_constraint_to (uses->id, gimple_call_chain (stmt));
rhsc.var = uses->id; rhsc.var = uses->id;
...@@ -4062,16 +4078,24 @@ handle_const_call (gcall *stmt, vec<ce_s> *results) ...@@ -4062,16 +4078,24 @@ handle_const_call (gcall *stmt, vec<ce_s> *results)
results->safe_push (rhsc); results->safe_push (rhsc);
} }
/* May return arguments. */ /* May return offsetted arguments. */
varinfo_t tem = NULL;
if (gimple_call_num_args (stmt) != 0)
tem = new_var_info (NULL_TREE, "callarg", true);
for (k = 0; k < gimple_call_num_args (stmt); ++k) for (k = 0; k < gimple_call_num_args (stmt); ++k)
{ {
tree arg = gimple_call_arg (stmt, k); tree arg = gimple_call_arg (stmt, k);
auto_vec<ce_s> argc; auto_vec<ce_s> argc;
unsigned i;
struct constraint_expr *argp;
get_constraint_for_rhs (arg, &argc); get_constraint_for_rhs (arg, &argc);
FOR_EACH_VEC_ELT (argc, i, argp) make_constraints_to (tem->id, argc);
results->safe_push (*argp); }
if (tem)
{
ce_s ce;
ce.type = SCALAR;
ce.var = tem->id;
ce.offset = UNKNOWN_OFFSET;
results->safe_push (ce);
} }
/* May return addresses of globals. */ /* May return addresses of globals. */
...@@ -4098,6 +4122,7 @@ handle_pure_call (gcall *stmt, vec<ce_s> *results) ...@@ -4098,6 +4122,7 @@ handle_pure_call (gcall *stmt, vec<ce_s> *results)
if (!uses) if (!uses)
{ {
uses = get_call_use_vi (stmt); uses = get_call_use_vi (stmt);
make_any_offset_constraints (uses);
make_transitive_closure_constraints (uses); make_transitive_closure_constraints (uses);
} }
make_constraint_to (uses->id, arg); make_constraint_to (uses->id, arg);
...@@ -4109,6 +4134,7 @@ handle_pure_call (gcall *stmt, vec<ce_s> *results) ...@@ -4109,6 +4134,7 @@ handle_pure_call (gcall *stmt, vec<ce_s> *results)
if (!uses) if (!uses)
{ {
uses = get_call_use_vi (stmt); uses = get_call_use_vi (stmt);
make_any_offset_constraints (uses);
make_transitive_closure_constraints (uses); make_transitive_closure_constraints (uses);
} }
make_constraint_to (uses->id, gimple_call_chain (stmt)); make_constraint_to (uses->id, gimple_call_chain (stmt));
......
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