Commit ed6c4831 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/45623 (GCC 4.5.[01] breaks our ffi on Linux64. ABI break?)

2010-09-16  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/45623
	* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
	(get_constraint_for_component_ref): If computing a constraint
	for the rhs handle type punning through unions.
	(get_constraint_for_address_of): Adjust.
	(get_constraint_for_1): Likewise.
	(get_constraint_for): Likewise.
	(get_constraint_for_rhs): New function.
	(do_structure_copy): Adjust.
	(make_constraint_to): Likewise.
	(handle_const_call): Likewise.
	(find_func_aliases): Likewise.
	(process_ipa_clobber): Likewise.
	(create_variable_info_for): Likewise.

	* gcc.dg/torture/pr45623.c: New testcase.

From-SVN: r164333
parent ff802fa1
2010-09-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45623
* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
(get_constraint_for_component_ref): If computing a constraint
for the rhs handle type punning through unions.
(get_constraint_for_address_of): Adjust.
(get_constraint_for_1): Likewise.
(get_constraint_for): Likewise.
(get_constraint_for_rhs): New function.
(do_structure_copy): Adjust.
(make_constraint_to): Likewise.
(handle_const_call): Likewise.
(find_func_aliases): Likewise.
(process_ipa_clobber): Likewise.
(create_variable_info_for): Likewise.
2010-09-16 Ira Rosen <irar@il.ibm.com> 2010-09-16 Ira Rosen <irar@il.ibm.com>
* tree-vectorizer.c: Fix documentation. * tree-vectorizer.c: Fix documentation.
......
2010-09-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/45623
* gcc.dg/torture/pr45623.c: New testcase.
2010-09-16 Ira Rosen <irar@il.ibm.com> 2010-09-16 Ira Rosen <irar@il.ibm.com>
* gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function * gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function
......
/* { dg-do run } */
#include <stdint.h>
extern void abort (void);
char *s1 = "foo";
char *s2 = "bar";
char **ss1 = &s1;
typedef union jsval_layout
{
uint64_t asBits;
char **ptr;
} jsval_layout;
int main()
{
jsval_layout l, m;
l.ptr = ss1;
m.asBits = l.asBits;
char ** data = m.ptr;
*data = s2;
if (s1 != s2)
abort ();
return 0;
}
...@@ -532,8 +532,9 @@ struct constraint_expr ...@@ -532,8 +532,9 @@ struct constraint_expr
typedef struct constraint_expr ce_s; typedef struct constraint_expr ce_s;
DEF_VEC_O(ce_s); DEF_VEC_O(ce_s);
DEF_VEC_ALLOC_O(ce_s, heap); DEF_VEC_ALLOC_O(ce_s, heap);
static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool); static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool, bool);
static void get_constraint_for (tree, VEC(ce_s, heap) **); static void get_constraint_for (tree, VEC(ce_s, heap) **);
static void get_constraint_for_rhs (tree, VEC(ce_s, heap) **);
static void do_deref (VEC (ce_s, heap) **); static void do_deref (VEC (ce_s, heap) **);
/* Our set constraints are made up of two constraint expressions, one /* Our set constraints are made up of two constraint expressions, one
...@@ -2994,7 +2995,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, ...@@ -2994,7 +2995,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
does not change the points-to solution. */ does not change the points-to solution. */
if (!use_field_sensitive) if (!use_field_sensitive)
{ {
get_constraint_for (ptr, results); get_constraint_for_rhs (ptr, results);
return; return;
} }
...@@ -3014,7 +3015,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, ...@@ -3014,7 +3015,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
rhsoffset = UNKNOWN_OFFSET; rhsoffset = UNKNOWN_OFFSET;
} }
get_constraint_for (ptr, results); get_constraint_for_rhs (ptr, results);
if (rhsoffset == 0) if (rhsoffset == 0)
return; return;
...@@ -3092,11 +3093,13 @@ get_constraint_for_ptr_offset (tree ptr, tree offset, ...@@ -3092,11 +3093,13 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
/* Given a COMPONENT_REF T, return the constraint_expr vector for it. /* Given a COMPONENT_REF T, return the constraint_expr vector for it.
If address_p is true the result will be taken its address of. */ If address_p is true the result will be taken its address of.
If lhs_p is true then the constraint expression is assumed to be used
as the lhs. */
static void static void
get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
bool address_p) bool address_p, bool lhs_p)
{ {
tree orig_t = t; tree orig_t = t;
HOST_WIDE_INT bitsize = -1; HOST_WIDE_INT bitsize = -1;
...@@ -3124,11 +3127,34 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results, ...@@ -3124,11 +3127,34 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
return; return;
} }
/* Handle type-punning through unions. If we are extracting a pointer
from a union via a possibly type-punning access that pointer
points to anything, similar to a conversion of an integer to
a pointer. */
if (!lhs_p)
{
tree u;
for (u = t;
TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
u = TREE_OPERAND (u, 0))
if (TREE_CODE (u) == COMPONENT_REF
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
{
struct constraint_expr temp;
temp.offset = 0;
temp.var = anything_id;
temp.type = ADDRESSOF;
VEC_safe_push (ce_s, heap, *results, &temp);
return;
}
}
t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize); t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
/* Pretend to take the address of the base, we'll take care of /* Pretend to take the address of the base, we'll take care of
adding the required subset of sub-fields below. */ adding the required subset of sub-fields below. */
get_constraint_for_1 (t, results, true); get_constraint_for_1 (t, results, true, lhs_p);
gcc_assert (VEC_length (ce_s, *results) == 1); gcc_assert (VEC_length (ce_s, *results) == 1);
result = VEC_last (ce_s, *results); result = VEC_last (ce_s, *results);
...@@ -3257,8 +3283,6 @@ do_deref (VEC (ce_s, heap) **constraints) ...@@ -3257,8 +3283,6 @@ do_deref (VEC (ce_s, heap) **constraints)
} }
} }
static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
/* Given a tree T, return the constraint expression for taking the /* Given a tree T, return the constraint expression for taking the
address of it. */ address of it. */
...@@ -3268,7 +3292,7 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results) ...@@ -3268,7 +3292,7 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
struct constraint_expr *c; struct constraint_expr *c;
unsigned int i; unsigned int i;
get_constraint_for_1 (t, results, true); get_constraint_for_1 (t, results, true, true);
FOR_EACH_VEC_ELT (ce_s, *results, i, c) FOR_EACH_VEC_ELT (ce_s, *results, i, c)
{ {
...@@ -3282,7 +3306,8 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results) ...@@ -3282,7 +3306,8 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
/* Given a tree T, return the constraint expression for it. */ /* Given a tree T, return the constraint expression for it. */
static void static void
get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,
bool lhs_p)
{ {
struct constraint_expr temp; struct constraint_expr temp;
...@@ -3354,10 +3379,11 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) ...@@ -3354,10 +3379,11 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
case ARRAY_REF: case ARRAY_REF:
case ARRAY_RANGE_REF: case ARRAY_RANGE_REF:
case COMPONENT_REF: case COMPONENT_REF:
get_constraint_for_component_ref (t, results, address_p); get_constraint_for_component_ref (t, results, address_p, lhs_p);
return; return;
case VIEW_CONVERT_EXPR: case VIEW_CONVERT_EXPR:
get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p); get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
lhs_p);
return; return;
/* We are missing handling for TARGET_MEM_REF here. */ /* We are missing handling for TARGET_MEM_REF here. */
default:; default:;
...@@ -3382,7 +3408,7 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p) ...@@ -3382,7 +3408,7 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
{ {
struct constraint_expr *rhsp; struct constraint_expr *rhsp;
unsigned j; unsigned j;
get_constraint_for_1 (val, &tmp, address_p); get_constraint_for_1 (val, &tmp, address_p, lhs_p);
FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp) FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
VEC_safe_push (ce_s, heap, *results, rhsp); VEC_safe_push (ce_s, heap, *results, rhsp);
VEC_truncate (ce_s, tmp, 0); VEC_truncate (ce_s, tmp, 0);
...@@ -3419,7 +3445,18 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results) ...@@ -3419,7 +3445,18 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
{ {
gcc_assert (VEC_length (ce_s, *results) == 0); gcc_assert (VEC_length (ce_s, *results) == 0);
get_constraint_for_1 (t, results, false); get_constraint_for_1 (t, results, false, true);
}
/* Given a gimple tree T, return the constraint expression vector for it
to be used as the rhs of a constraint. */
static void
get_constraint_for_rhs (tree t, VEC (ce_s, heap) **results)
{
gcc_assert (VEC_length (ce_s, *results) == 0);
get_constraint_for_1 (t, results, false, false);
} }
...@@ -3461,7 +3498,7 @@ do_structure_copy (tree lhsop, tree rhsop) ...@@ -3461,7 +3498,7 @@ do_structure_copy (tree lhsop, tree rhsop)
unsigned j; unsigned j;
get_constraint_for (lhsop, &lhsc); get_constraint_for (lhsop, &lhsc);
get_constraint_for (rhsop, &rhsc); get_constraint_for_rhs (rhsop, &rhsc);
lhsp = VEC_index (ce_s, lhsc, 0); lhsp = VEC_index (ce_s, lhsc, 0);
rhsp = VEC_index (ce_s, rhsc, 0); rhsp = VEC_index (ce_s, rhsc, 0);
if (lhsp->type == DEREF if (lhsp->type == DEREF
...@@ -3531,7 +3568,7 @@ make_constraint_to (unsigned id, tree op) ...@@ -3531,7 +3568,7 @@ make_constraint_to (unsigned id, tree op)
includes.offset = 0; includes.offset = 0;
includes.type = SCALAR; includes.type = SCALAR;
get_constraint_for (op, &rhsc); 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));
VEC_free (ce_s, heap, rhsc); VEC_free (ce_s, heap, rhsc);
...@@ -3904,7 +3941,7 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results) ...@@ -3904,7 +3941,7 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
VEC(ce_s, heap) *argc = NULL; VEC(ce_s, heap) *argc = NULL;
unsigned i; unsigned i;
struct constraint_expr *argp; struct constraint_expr *argp;
get_constraint_for (arg, &argc); get_constraint_for_rhs (arg, &argc);
FOR_EACH_VEC_ELT (ce_s, argc, i, argp) FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
VEC_safe_push (ce_s, heap, *results, argp); VEC_safe_push (ce_s, heap, *results, argp);
VEC_free(ce_s, heap, argc); VEC_free(ce_s, heap, argc);
...@@ -4038,7 +4075,7 @@ find_func_aliases (gimple origt) ...@@ -4038,7 +4075,7 @@ find_func_aliases (gimple origt)
tree strippedrhs = PHI_ARG_DEF (t, i); tree strippedrhs = PHI_ARG_DEF (t, i);
STRIP_NOPS (strippedrhs); STRIP_NOPS (strippedrhs);
get_constraint_for (gimple_phi_arg_def (t, i), &rhsc); get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
FOR_EACH_VEC_ELT (ce_s, lhsc, j, c) FOR_EACH_VEC_ELT (ce_s, lhsc, j, c)
{ {
...@@ -4322,7 +4359,7 @@ find_func_aliases (gimple origt) ...@@ -4322,7 +4359,7 @@ find_func_aliases (gimple origt)
if (!could_have_pointers (arg)) if (!could_have_pointers (arg))
continue; continue;
get_constraint_for (arg, &rhsc); get_constraint_for_rhs (arg, &rhsc);
lhs = get_function_part_constraint (fi, fi_parm_base + j); lhs = get_function_part_constraint (fi, fi_parm_base + j);
while (VEC_length (ce_s, rhsc) != 0) while (VEC_length (ce_s, rhsc) != 0)
{ {
...@@ -4417,7 +4454,7 @@ find_func_aliases (gimple origt) ...@@ -4417,7 +4454,7 @@ find_func_aliases (gimple origt)
&& !(POINTER_TYPE_P (gimple_expr_type (t)) && !(POINTER_TYPE_P (gimple_expr_type (t))
&& !POINTER_TYPE_P (TREE_TYPE (rhsop)))) && !POINTER_TYPE_P (TREE_TYPE (rhsop))))
|| gimple_assign_single_p (t)) || gimple_assign_single_p (t))
get_constraint_for (rhsop, &rhsc); get_constraint_for_rhs (rhsop, &rhsc);
else else
{ {
temp.type = ADDRESSOF; temp.type = ADDRESSOF;
...@@ -4468,7 +4505,7 @@ find_func_aliases (gimple origt) ...@@ -4468,7 +4505,7 @@ find_func_aliases (gimple origt)
unsigned i; unsigned i;
lhs = get_function_part_constraint (fi, fi_result); lhs = get_function_part_constraint (fi, fi_result);
get_constraint_for (gimple_return_retval (t), &rhsc); get_constraint_for_rhs (gimple_return_retval (t), &rhsc);
FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp) FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
process_constraint (new_constraint (lhs, *rhsp)); process_constraint (new_constraint (lhs, *rhsp));
} }
...@@ -4549,7 +4586,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr) ...@@ -4549,7 +4586,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr)
VEC(ce_s, heap) *ptrc = NULL; VEC(ce_s, heap) *ptrc = NULL;
struct constraint_expr *c, lhs; struct constraint_expr *c, lhs;
unsigned i; unsigned i;
get_constraint_for (ptr, &ptrc); get_constraint_for_rhs (ptr, &ptrc);
lhs = get_function_part_constraint (fi, fi_clobbers); lhs = get_function_part_constraint (fi, fi_clobbers);
FOR_EACH_VEC_ELT (ce_s, ptrc, i, c) FOR_EACH_VEC_ELT (ce_s, ptrc, i, c)
process_constraint (new_constraint (lhs, *c)); process_constraint (new_constraint (lhs, *c));
...@@ -5430,7 +5467,7 @@ create_variable_info_for (tree decl, const char *name) ...@@ -5430,7 +5467,7 @@ create_variable_info_for (tree decl, const char *name)
VEC (ce_s, heap) *rhsc = NULL; VEC (ce_s, heap) *rhsc = NULL;
struct constraint_expr lhs, *rhsp; struct constraint_expr lhs, *rhsp;
unsigned i; unsigned i;
get_constraint_for (DECL_INITIAL (decl), &rhsc); get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc);
lhs.var = vi->id; lhs.var = vi->id;
lhs.offset = 0; lhs.offset = 0;
lhs.type = SCALAR; lhs.type = SCALAR;
......
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