[PR 89209] Avoid segfault in a peculiar corner case in SRA

2019-02-18  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/89209
	* tree-sra.c (create_access_replacement): New optional parameter
	reg_tree.  Use it as a type if non-NULL and access type is not of
	a register type.
	(get_repl_default_def_ssa_name): New parameter REG_TYPE, pass it
	to create_access_replacement.
	(sra_modify_assign): Pass LHS type to get_repl_default_def_ssa_name.
	Check lacc is non-NULL before attempting to re-create it on the RHS.

	testsuite/
	* gcc.dg/tree-ssa/pr89209.c: New test.

From-SVN: r268980
This commit is contained in:
Martin Jambor 2019-02-18 09:59:04 +01:00 committed by Martin Jambor
parent db30281f0b
commit 469b4adb4f
4 changed files with 53 additions and 13 deletions

View file

@ -1,3 +1,14 @@
2019-02-18 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/89209
* tree-sra.c (create_access_replacement): New optional parameter
reg_tree. Use it as a type if non-NULL and access type is not of
a register type.
(get_repl_default_def_ssa_name): New parameter REG_TYPE, pass it
to create_access_replacement.
(sra_modify_assign): Pass LHS type to get_repl_default_def_ssa_name.
Check lacc is non-NULL before attempting to re-create it on the RHS.
2019-02-18 Martin Liska <mliska@suse.cz>
PR ipa/89306

View file

@ -1,3 +1,8 @@
2019-02-18 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/89209
* gcc.dg/tree-ssa/pr89209.c: New test.
2019-02-18 Martin Liska <mliska@suse.cz>
* gfortran.dg/simd-builtins-7.f90: New test.

View file

@ -0,0 +1,16 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
struct S {
short a, b;
};
struct T {
int c;
struct S s;
};
int f ()
{
struct T t;
t.c = t.s.a || t.s.b;
return t.c;
}

View file

@ -2195,13 +2195,20 @@ sort_and_splice_var_accesses (tree var)
/* Create a variable for the given ACCESS which determines the type, name and a
few other properties. Return the variable declaration and store it also to
ACCESS->replacement. */
ACCESS->replacement. REG_TREE is used when creating a declaration to base a
default-definition SSA name on on in order to facilitate an uninitialized
warning. It is used instead of the actual ACCESS type if that is not of a
gimple register type. */
static tree
create_access_replacement (struct access *access)
create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
{
tree repl;
tree type = access->type;
if (reg_type && !is_gimple_reg_type (type))
type = reg_type;
if (access->grp_to_be_debug_replaced)
{
repl = create_tmp_var_raw (access->type);
@ -2210,17 +2217,16 @@ create_access_replacement (struct access *access)
else
/* Drop any special alignment on the type if it's not on the main
variant. This avoids issues with weirdo ABIs like AAPCS. */
repl = create_tmp_var (build_qualified_type
(TYPE_MAIN_VARIANT (access->type),
TYPE_QUALS (access->type)), "SR");
if (TREE_CODE (access->type) == COMPLEX_TYPE
|| TREE_CODE (access->type) == VECTOR_TYPE)
repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
TYPE_QUALS (type)), "SR");
if (TREE_CODE (type) == COMPLEX_TYPE
|| TREE_CODE (type) == VECTOR_TYPE)
{
if (!access->grp_partial_lhs)
DECL_GIMPLE_REG_P (repl) = 1;
}
else if (access->grp_partial_lhs
&& is_gimple_reg_type (access->type))
&& is_gimple_reg_type (type))
TREE_ADDRESSABLE (repl) = 1;
DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
@ -3450,15 +3456,16 @@ sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi)
/* Create and return a new suitable default definition SSA_NAME for RACC which
is an access describing an uninitialized part of an aggregate that is being
loaded. */
loaded. REG_TREE is used instead of the actual RACC type if that is not of
a gimple register type. */
static tree
get_repl_default_def_ssa_name (struct access *racc)
get_repl_default_def_ssa_name (struct access *racc, tree reg_type)
{
gcc_checking_assert (!racc->grp_to_be_replaced
&& !racc->grp_to_be_debug_replaced);
if (!racc->replacement_decl)
racc->replacement_decl = create_access_replacement (racc);
racc->replacement_decl = create_access_replacement (racc, reg_type);
return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
}
@ -3530,7 +3537,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
&& TREE_CODE (lhs) == SSA_NAME
&& !access_has_replacements_p (racc))
{
rhs = get_repl_default_def_ssa_name (racc);
rhs = get_repl_default_def_ssa_name (racc, TREE_TYPE (lhs));
modify_this_stmt = true;
sra_stats.exprs++;
}
@ -3548,7 +3555,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
gimple_assign_set_lhs (stmt, lhs);
}
else if (AGGREGATE_TYPE_P (TREE_TYPE (rhs))
else if (lacc
&& AGGREGATE_TYPE_P (TREE_TYPE (rhs))
&& !contains_vce_or_bfcref_p (rhs))
rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);