Commit cb89b4b0 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/45982 (PTA does not track integers)

2010-10-13  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/45982
	* tree-ssa-structalias.c (make_constraints_to): New function.
	(make_constraint_to): Implement in terms of make_constraints_to.
	(find_func_aliases): Properly make return values of pure/const
	functions escape if they assign to sth that is not a pointer.

	* gcc.dg/torture/pr45982.c: New testcase.
	* gcc.dg/tree-ssa/pr24287.c: Adjust.
	* gcc.dg/tree-ssa/pta-callused.c: Likewise.
	* gcc.dg/torture/pr39074-2.c: Likewise.

From-SVN: r165418
parent 72351fa3
2010-10-13 Richard Guenther <rguenther@suse.de> 2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45982
* tree-ssa-structalias.c (make_constraints_to): New function.
(make_constraint_to): Implement in terms of make_constraints_to.
(find_func_aliases): Properly make return values of pure/const
functions escape if they assign to sth that is not a pointer.
2010-10-13 Richard Guenther <rguenther@suse.de>
PR middle-end/45874 PR middle-end/45874
* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): * cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee):
Fixup the CFG when EH was fixed up. Fixup the CFG when EH was fixed up.
2010-10-13 Richard Guenther <rguenther@suse.de> 2010-10-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45982
* gcc.dg/torture/pr45982.c: New testcase.
* gcc.dg/tree-ssa/pr24287.c: Adjust.
* gcc.dg/tree-ssa/pta-callused.c: Likewise.
* gcc.dg/torture/pr39074-2.c: Likewise.
2010-10-13 Richard Guenther <rguenther@suse.de>
PR middle-end/45874 PR middle-end/45874
* g++.dg/torture/pr45874.C: New testcase. * g++.dg/torture/pr45874.C: New testcase.
......
...@@ -30,5 +30,5 @@ int main() ...@@ -30,5 +30,5 @@ int main()
return 0; return 0;
} }
/* { dg-final { scan-tree-dump "y.._., points-to vars: { i }" "alias" } } */ /* { dg-final { scan-tree-dump "y.._., points-to non-local, points-to escaped, points-to vars: { i }" "alias" } } */
/* { dg-final { cleanup-tree-dump "alias" } } */ /* { dg-final { cleanup-tree-dump "alias" } } */
/* { dg-do run } */
#include <stdint.h>
extern void abort (void);
uintptr_t __attribute__((pure,noinline,noclone))
foo (int *a)
{
return (uintptr_t) a;
}
void __attribute__((noinline,noclone))
bar (uintptr_t a)
{
int *p = (int *)a;
*p = 1;
}
int main()
{
int t = 0;
bar (foo (&t));
if (t != 1)
abort ();
return 0;
}
...@@ -9,11 +9,14 @@ void link_error(); ...@@ -9,11 +9,14 @@ void link_error();
int g(void) int g(void)
{ {
int t = 0, t1 = 2; int t = 0, t1 = 2;
/* ??? That's not true. The pointers escape to the integer return
value which we do not track in PTA. */
int t2 = h(&t, &t1); int t2 = h(&t, &t1);
if (t != 0) if (t != 0)
link_error (); link_error ();
if (t1 != 2) if (t1 != 2)
link_error (); link_error ();
/* ??? And it would finally escape here even if we did. */
g1(t2); g1(t2);
if (t != 0) if (t != 0)
link_error (); link_error ();
...@@ -21,5 +24,6 @@ int g(void) ...@@ -21,5 +24,6 @@ int g(void)
link_error (); link_error ();
return t2 == 2; return t2 == 2;
} }
/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */ /* We are allowed to optimize the first two link_error calls. */
/* { dg-final { scan-tree-dump-times "link_error" 2 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -5,7 +5,7 @@ struct Foo { ...@@ -5,7 +5,7 @@ struct Foo {
int *p, *q; int *p, *q;
}; };
int foo (int ***x) __attribute__((pure)); int *foo (int ***x) __attribute__((pure));
int bar (int b) int bar (int b)
{ {
...@@ -19,7 +19,7 @@ int bar (int b) ...@@ -19,7 +19,7 @@ int bar (int b)
q = &f.p; q = &f.p;
else else
q = &f.q; q = &f.q;
return foo (&q); return *foo (&q);
} }
/* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */ /* { dg-final { scan-tree-dump "CALLUSED = { f.* i q }" "alias" } } */
......
...@@ -3563,12 +3563,11 @@ do_structure_copy (tree lhsop, tree rhsop) ...@@ -3563,12 +3563,11 @@ do_structure_copy (tree lhsop, tree rhsop)
VEC_free (ce_s, heap, rhsc); VEC_free (ce_s, heap, rhsc);
} }
/* Create a constraint ID = OP. */ /* Create constraints ID = { rhsc }. */
static void static void
make_constraint_to (unsigned id, tree op) make_constraints_to (unsigned id, VEC(ce_s, heap) *rhsc)
{ {
VEC(ce_s, heap) *rhsc = NULL;
struct constraint_expr *c; struct constraint_expr *c;
struct constraint_expr includes; struct constraint_expr includes;
unsigned int j; unsigned int j;
...@@ -3577,9 +3576,18 @@ make_constraint_to (unsigned id, tree op) ...@@ -3577,9 +3576,18 @@ make_constraint_to (unsigned id, tree op)
includes.offset = 0; includes.offset = 0;
includes.type = SCALAR; includes.type = SCALAR;
get_constraint_for_rhs (op, &rhsc);
FOR_EACH_VEC_ELT (ce_s, rhsc, j, c) FOR_EACH_VEC_ELT (ce_s, rhsc, j, c)
process_constraint (new_constraint (includes, *c)); process_constraint (new_constraint (includes, *c));
}
/* Create a constraint ID = OP. */
static void
make_constraint_to (unsigned id, tree op)
{
VEC(ce_s, heap) *rhsc = NULL;
get_constraint_for_rhs (op, &rhsc);
make_constraints_to (id, rhsc);
VEC_free (ce_s, heap, rhsc); VEC_free (ce_s, heap, rhsc);
} }
...@@ -4334,8 +4342,7 @@ find_func_aliases (gimple origt) ...@@ -4334,8 +4342,7 @@ find_func_aliases (gimple origt)
of global memory but not of escaped memory. */ of global memory but not of escaped memory. */
if (flags & (ECF_CONST|ECF_NOVOPS)) if (flags & (ECF_CONST|ECF_NOVOPS))
{ {
if (gimple_call_lhs (t) if (gimple_call_lhs (t))
&& could_have_pointers (gimple_call_lhs (t)))
handle_const_call (t, &rhsc); handle_const_call (t, &rhsc);
} }
/* Pure functions can return addresses in and of memory /* Pure functions can return addresses in and of memory
...@@ -4345,9 +4352,17 @@ find_func_aliases (gimple origt) ...@@ -4345,9 +4352,17 @@ find_func_aliases (gimple origt)
handle_pure_call (t, &rhsc); handle_pure_call (t, &rhsc);
else else
handle_rhs_call (t, &rhsc); handle_rhs_call (t, &rhsc);
if (gimple_call_lhs (t) if (gimple_call_lhs (t))
&& could_have_pointers (gimple_call_lhs (t))) {
handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl); if (could_have_pointers (gimple_call_lhs (t)))
handle_lhs_call (t, gimple_call_lhs (t), flags, rhsc, fndecl);
/* Similar to conversions a result that is not a pointer
is an escape point for any pointer the function might
return. */
else if (flags & (ECF_CONST|ECF_PURE
|ECF_NOVOPS|ECF_LOOPING_CONST_OR_PURE))
make_constraints_to (escaped_id, rhsc);
}
VEC_free (ce_s, heap, rhsc); VEC_free (ce_s, heap, rhsc);
} }
else else
......
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