re PR middle-end/42025 (ICE verify_stmts failed (non-trivial conversion at assignment))
2009-11-21 Martin Jambor <mjambor@suse.cz> PR middle-end/42025 * tree-sra.c (access_precludes_ipa_sra_p): New function. (splice_param_accesses): Check all accesses by calling access_precludes_ipa_sra_p. (sra_ipa_modify_expr): Rename argument erite to dont_convert and do not convert types if it is true. (sra_ipa_modify_assign): Convert types in case of mismatch. * testsuite/gcc.c-torture/compile/pr42025-1.c: New test. * testsuite/gcc.c-torture/compile/pr42025-2.c: New test. From-SVN: r154413
This commit is contained in:
parent
bcd9e00d09
commit
c6a2c25d12
5 changed files with 140 additions and 18 deletions
|
@ -1,3 +1,13 @@
|
|||
2009-11-21 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR middle-end/42025
|
||||
* tree-sra.c (access_precludes_ipa_sra_p): New function.
|
||||
(splice_param_accesses): Check all accesses by calling
|
||||
access_precludes_ipa_sra_p.
|
||||
(sra_ipa_modify_expr): Rename argument erite to dont_convert and do
|
||||
not convert types if it is true.
|
||||
(sra_ipa_modify_assign): Convert types in case of mismatch.
|
||||
|
||||
2009-11-21 Kaushik Phatak <kaushik.phatak@kpitcummins.com>
|
||||
|
||||
* config/sh/sh.md (cmpeqsi_t-1): Use logical_operand predicate
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2009-11-21 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
PR middle-end/42025
|
||||
* gcc.c-torture/compile/pr42025-1.c: New test.
|
||||
* gcc.c-torture/compile/pr42025-2.c: New test.
|
||||
|
||||
2009-11-21 Adam Nemet <adambnemet@gmail.com>
|
||||
|
||||
* gcc.target/mips/mult-1.c: Forbid octeon.
|
||||
|
|
24
gcc/testsuite/gcc.c-torture/compile/pr42025-1.c
Normal file
24
gcc/testsuite/gcc.c-torture/compile/pr42025-1.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
typedef void* Ptr;
|
||||
|
||||
struct A
|
||||
{
|
||||
int i;
|
||||
union
|
||||
{
|
||||
Ptr p;
|
||||
char *q;
|
||||
} u;
|
||||
};
|
||||
|
||||
static void foo(struct A *p, char *q)
|
||||
{
|
||||
if (p->i)
|
||||
p->u.p = 0;
|
||||
else
|
||||
p->u.q = q;
|
||||
}
|
||||
|
||||
void bar(struct A *p, char *q)
|
||||
{
|
||||
foo(p, q);
|
||||
}
|
32
gcc/testsuite/gcc.c-torture/compile/pr42025-2.c
Normal file
32
gcc/testsuite/gcc.c-torture/compile/pr42025-2.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
typedef struct
|
||||
{
|
||||
void *p;
|
||||
} Ptr;
|
||||
|
||||
struct A
|
||||
{
|
||||
int i;
|
||||
union
|
||||
{
|
||||
Ptr p;
|
||||
char *q;
|
||||
} u;
|
||||
};
|
||||
|
||||
extern Ptr get_stuff (void);
|
||||
extern void use_stuff (char *);
|
||||
|
||||
static void foo(struct A p, char *q)
|
||||
{
|
||||
if (p.i)
|
||||
p.u.p = get_stuff ();
|
||||
else
|
||||
p.u.q = q;
|
||||
|
||||
use_stuff (p.u.q);
|
||||
}
|
||||
|
||||
void bar(struct A *p, char *q)
|
||||
{
|
||||
foo(*p, q);
|
||||
}
|
|
@ -3042,6 +3042,27 @@ unmodified_by_ref_scalar_representative (tree parm)
|
|||
return repr;
|
||||
}
|
||||
|
||||
/* Return true iff this access precludes IPA-SRA of the parameter it is
|
||||
associated with. */
|
||||
|
||||
static bool
|
||||
access_precludes_ipa_sra_p (struct access *access)
|
||||
{
|
||||
/* Avoid issues such as the second simple testcase in PR 42025. The problem
|
||||
is incompatible assign in a call statement (and possibly even in asm
|
||||
statements). This can be relaxed by using a new temporary but only for
|
||||
non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
|
||||
intraprocedural SRA we deal with this by keeping the old aggregate around,
|
||||
something we cannot do in IPA-SRA.) */
|
||||
if (access->write
|
||||
&& (is_gimple_call (access->stmt)
|
||||
|| gimple_code (access->stmt) == GIMPLE_ASM))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Sort collected accesses for parameter PARM, identify representatives for
|
||||
each accessed region and link them together. Return NULL if there are
|
||||
different but overlapping accesses, return the special ptr value meaning
|
||||
|
@ -3073,6 +3094,8 @@ splice_param_accesses (tree parm, bool *ro_grp)
|
|||
bool modification;
|
||||
access = VEC_index (access_p, access_vec, i);
|
||||
modification = access->write;
|
||||
if (access_precludes_ipa_sra_p (access))
|
||||
return NULL;
|
||||
|
||||
/* Access is about to become group representative unless we find some
|
||||
nasty overlap which would preclude us from breaking this parameter
|
||||
|
@ -3093,6 +3116,9 @@ splice_param_accesses (tree parm, bool *ro_grp)
|
|||
else if (ac2->size != access->size)
|
||||
return NULL;
|
||||
|
||||
if (access_precludes_ipa_sra_p (ac2))
|
||||
return NULL;
|
||||
|
||||
modification |= ac2->write;
|
||||
ac2->group_representative = access;
|
||||
ac2->next_sibling = access->next_sibling;
|
||||
|
@ -3523,13 +3549,19 @@ replace_removed_params_ssa_names (gimple stmt, void *data)
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Callback for scan_function. If the expression *EXPR should be replaced by a
|
||||
reduction of a parameter, do so. DATA is a pointer to a vector of
|
||||
adjustments. */
|
||||
/* Callback for scan_function and helper to sra_ipa_modify_assign. If the
|
||||
expression *EXPR should be replaced by a reduction of a parameter, do so.
|
||||
DATA is a pointer to a vector of adjustments. DONT_CONVERT specifies
|
||||
whether the function should care about type incompatibility the current and
|
||||
new expressions. If it is true, the function will leave incompatibility
|
||||
issues to the caller.
|
||||
|
||||
When called directly by scan_function, DONT_CONVERT is true when the EXPR is
|
||||
a write (LHS) expression. */
|
||||
|
||||
static bool
|
||||
sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
|
||||
bool write ATTRIBUTE_UNUSED, void *data)
|
||||
bool dont_convert, void *data)
|
||||
{
|
||||
ipa_parm_adjustment_vec adjustments;
|
||||
int i, len;
|
||||
|
@ -3543,10 +3575,10 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
|
|||
if (TREE_CODE (*expr) == BIT_FIELD_REF
|
||||
|| TREE_CODE (*expr) == IMAGPART_EXPR
|
||||
|| TREE_CODE (*expr) == REALPART_EXPR)
|
||||
expr = &TREE_OPERAND (*expr, 0);
|
||||
while (TREE_CODE (*expr) == NOP_EXPR
|
||||
|| TREE_CODE (*expr) == VIEW_CONVERT_EXPR)
|
||||
expr = &TREE_OPERAND (*expr, 0);
|
||||
{
|
||||
expr = &TREE_OPERAND (*expr, 0);
|
||||
dont_convert = false;
|
||||
}
|
||||
|
||||
base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
|
||||
if (!base || size == -1 || max_size == -1)
|
||||
|
@ -3594,13 +3626,14 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
|
|||
fprintf (dump_file, "\n");
|
||||
}
|
||||
|
||||
if (!useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
|
||||
if (!dont_convert
|
||||
&& !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
|
||||
{
|
||||
tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
|
||||
*expr = vce;
|
||||
}
|
||||
else
|
||||
*expr = src;
|
||||
else
|
||||
*expr = src;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3608,20 +3641,37 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
|
|||
essentially the same function like sra_ipa_modify_expr. */
|
||||
|
||||
static enum scan_assign_result
|
||||
sra_ipa_modify_assign (gimple *stmt_ptr,
|
||||
gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, void *data)
|
||||
sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
|
||||
{
|
||||
gimple stmt = *stmt_ptr;
|
||||
bool any = false;
|
||||
tree *lhs_p, *rhs_p;
|
||||
bool any;
|
||||
|
||||
if (!gimple_assign_single_p (stmt))
|
||||
return SRA_SA_NONE;
|
||||
|
||||
any |= sra_ipa_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false,
|
||||
data);
|
||||
any |= sra_ipa_modify_expr (gimple_assign_lhs_ptr (stmt), gsi, true, data);
|
||||
rhs_p = gimple_assign_rhs1_ptr (stmt);
|
||||
lhs_p = gimple_assign_lhs_ptr (stmt);
|
||||
|
||||
return any ? SRA_SA_PROCESSED : SRA_SA_NONE;
|
||||
any = sra_ipa_modify_expr (rhs_p, gsi, true, data);
|
||||
any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
|
||||
if (any)
|
||||
{
|
||||
if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
|
||||
{
|
||||
location_t loc = gimple_location (stmt);
|
||||
tree vce = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
|
||||
TREE_TYPE (*lhs_p), *rhs_p);
|
||||
tree tmp = force_gimple_operand_gsi (gsi, vce, true, NULL_TREE,
|
||||
true, GSI_SAME_STMT);
|
||||
|
||||
gimple_assign_set_rhs_from_tree (gsi, tmp);
|
||||
}
|
||||
|
||||
return SRA_SA_PROCESSED;
|
||||
}
|
||||
|
||||
return SRA_SA_NONE;
|
||||
}
|
||||
|
||||
/* Call gimple_debug_bind_reset_value on all debug statements describing
|
||||
|
|
Loading…
Add table
Reference in a new issue