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
This commit is contained in:
Richard Guenther 2010-09-16 11:06:25 +00:00 committed by Richard Biener
parent ff802fa1f3
commit ed6c4831a9
4 changed files with 110 additions and 23 deletions

View file

@ -1,3 +1,20 @@
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>
* tree-vectorizer.c: Fix documentation.

View file

@ -1,3 +1,8 @@
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>
* gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function

View file

@ -0,0 +1,28 @@
/* { 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;
}

View file

@ -532,8 +532,9 @@ struct constraint_expr
typedef struct constraint_expr ce_s;
DEF_VEC_O(ce_s);
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_rhs (tree, VEC(ce_s, heap) **);
static void do_deref (VEC (ce_s, heap) **);
/* Our set constraints are made up of two constraint expressions, one
@ -2994,7 +2995,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
does not change the points-to solution. */
if (!use_field_sensitive)
{
get_constraint_for (ptr, results);
get_constraint_for_rhs (ptr, results);
return;
}
@ -3014,7 +3015,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
rhsoffset = UNKNOWN_OFFSET;
}
get_constraint_for (ptr, results);
get_constraint_for_rhs (ptr, results);
if (rhsoffset == 0)
return;
@ -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.
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
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;
HOST_WIDE_INT bitsize = -1;
@ -3124,11 +3127,34 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
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);
/* Pretend to take the address of the base, we'll take care of
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);
result = VEC_last (ce_s, *results);
@ -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
address of it. */
@ -3268,7 +3292,7 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
struct constraint_expr *c;
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)
{
@ -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. */
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;
@ -3354,10 +3379,11 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
case ARRAY_REF:
case ARRAY_RANGE_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;
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;
/* We are missing handling for TARGET_MEM_REF here. */
default:;
@ -3382,7 +3408,7 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
{
struct constraint_expr *rhsp;
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)
VEC_safe_push (ce_s, heap, *results, rhsp);
VEC_truncate (ce_s, tmp, 0);
@ -3419,7 +3445,18 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
{
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)
unsigned j;
get_constraint_for (lhsop, &lhsc);
get_constraint_for (rhsop, &rhsc);
get_constraint_for_rhs (rhsop, &rhsc);
lhsp = VEC_index (ce_s, lhsc, 0);
rhsp = VEC_index (ce_s, rhsc, 0);
if (lhsp->type == DEREF
@ -3531,7 +3568,7 @@ make_constraint_to (unsigned id, tree op)
includes.offset = 0;
includes.type = SCALAR;
get_constraint_for (op, &rhsc);
get_constraint_for_rhs (op, &rhsc);
FOR_EACH_VEC_ELT (ce_s, rhsc, j, c)
process_constraint (new_constraint (includes, *c));
VEC_free (ce_s, heap, rhsc);
@ -3904,7 +3941,7 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
VEC(ce_s, heap) *argc = NULL;
unsigned i;
struct constraint_expr *argp;
get_constraint_for (arg, &argc);
get_constraint_for_rhs (arg, &argc);
FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
VEC_safe_push (ce_s, heap, *results, argp);
VEC_free(ce_s, heap, argc);
@ -4038,7 +4075,7 @@ find_func_aliases (gimple origt)
tree strippedrhs = PHI_ARG_DEF (t, i);
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)
{
@ -4322,7 +4359,7 @@ find_func_aliases (gimple origt)
if (!could_have_pointers (arg))
continue;
get_constraint_for (arg, &rhsc);
get_constraint_for_rhs (arg, &rhsc);
lhs = get_function_part_constraint (fi, fi_parm_base + j);
while (VEC_length (ce_s, rhsc) != 0)
{
@ -4417,7 +4454,7 @@ find_func_aliases (gimple origt)
&& !(POINTER_TYPE_P (gimple_expr_type (t))
&& !POINTER_TYPE_P (TREE_TYPE (rhsop))))
|| gimple_assign_single_p (t))
get_constraint_for (rhsop, &rhsc);
get_constraint_for_rhs (rhsop, &rhsc);
else
{
temp.type = ADDRESSOF;
@ -4468,7 +4505,7 @@ find_func_aliases (gimple origt)
unsigned i;
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)
process_constraint (new_constraint (lhs, *rhsp));
}
@ -4549,7 +4586,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr)
VEC(ce_s, heap) *ptrc = NULL;
struct constraint_expr *c, lhs;
unsigned i;
get_constraint_for (ptr, &ptrc);
get_constraint_for_rhs (ptr, &ptrc);
lhs = get_function_part_constraint (fi, fi_clobbers);
FOR_EACH_VEC_ELT (ce_s, ptrc, i, c)
process_constraint (new_constraint (lhs, *c));
@ -5430,7 +5467,7 @@ create_variable_info_for (tree decl, const char *name)
VEC (ce_s, heap) *rhsc = NULL;
struct constraint_expr lhs, *rhsp;
unsigned i;
get_constraint_for (DECL_INITIAL (decl), &rhsc);
get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc);
lhs.var = vi->id;
lhs.offset = 0;
lhs.type = SCALAR;