Commit 469b4adb by Martin Jambor Committed by Martin Jambor

[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
parent db30281f
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> 2019-02-18 Martin Liska <mliska@suse.cz>
PR ipa/89306 PR ipa/89306
......
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> 2019-02-18 Martin Liska <mliska@suse.cz>
* gfortran.dg/simd-builtins-7.f90: New test. * gfortran.dg/simd-builtins-7.f90: New test.
......
/* { 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;
}
...@@ -2195,13 +2195,20 @@ sort_and_splice_var_accesses (tree var) ...@@ -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 /* 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 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 static tree
create_access_replacement (struct access *access) create_access_replacement (struct access *access, tree reg_type = NULL_TREE)
{ {
tree repl; tree repl;
tree type = access->type;
if (reg_type && !is_gimple_reg_type (type))
type = reg_type;
if (access->grp_to_be_debug_replaced) if (access->grp_to_be_debug_replaced)
{ {
repl = create_tmp_var_raw (access->type); repl = create_tmp_var_raw (access->type);
...@@ -2210,17 +2217,16 @@ create_access_replacement (struct access *access) ...@@ -2210,17 +2217,16 @@ create_access_replacement (struct access *access)
else else
/* Drop any special alignment on the type if it's not on the main /* Drop any special alignment on the type if it's not on the main
variant. This avoids issues with weirdo ABIs like AAPCS. */ variant. This avoids issues with weirdo ABIs like AAPCS. */
repl = create_tmp_var (build_qualified_type repl = create_tmp_var (build_qualified_type (TYPE_MAIN_VARIANT (type),
(TYPE_MAIN_VARIANT (access->type), TYPE_QUALS (type)), "SR");
TYPE_QUALS (access->type)), "SR"); if (TREE_CODE (type) == COMPLEX_TYPE
if (TREE_CODE (access->type) == COMPLEX_TYPE || TREE_CODE (type) == VECTOR_TYPE)
|| TREE_CODE (access->type) == VECTOR_TYPE)
{ {
if (!access->grp_partial_lhs) if (!access->grp_partial_lhs)
DECL_GIMPLE_REG_P (repl) = 1; DECL_GIMPLE_REG_P (repl) = 1;
} }
else if (access->grp_partial_lhs else if (access->grp_partial_lhs
&& is_gimple_reg_type (access->type)) && is_gimple_reg_type (type))
TREE_ADDRESSABLE (repl) = 1; TREE_ADDRESSABLE (repl) = 1;
DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base); DECL_SOURCE_LOCATION (repl) = DECL_SOURCE_LOCATION (access->base);
...@@ -3450,15 +3456,16 @@ sra_modify_constructor_assign (gimple *stmt, gimple_stmt_iterator *gsi) ...@@ -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 /* 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 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 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 gcc_checking_assert (!racc->grp_to_be_replaced
&& !racc->grp_to_be_debug_replaced); && !racc->grp_to_be_debug_replaced);
if (!racc->replacement_decl) 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); return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
} }
...@@ -3530,7 +3537,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) ...@@ -3530,7 +3537,7 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
&& TREE_CODE (lhs) == SSA_NAME && TREE_CODE (lhs) == SSA_NAME
&& !access_has_replacements_p (racc)) && !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; modify_this_stmt = true;
sra_stats.exprs++; sra_stats.exprs++;
} }
...@@ -3548,7 +3555,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi) ...@@ -3548,7 +3555,8 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false); lhs = build_ref_for_model (loc, lhs, 0, racc, gsi, false);
gimple_assign_set_lhs (stmt, lhs); 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)) && !contains_vce_or_bfcref_p (rhs))
rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false); rhs = build_ref_for_model (loc, rhs, 0, lacc, gsi, false);
......
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