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:
parent
ff802fa1f3
commit
ed6c4831a9
4 changed files with 110 additions and 23 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
28
gcc/testsuite/gcc.dg/torture/pr45623.c
Normal file
28
gcc/testsuite/gcc.dg/torture/pr45623.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue