summaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2017-12-08 13:11:02 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2017-12-08 13:11:02 +0100
commitd90ffcfb7d105d004cf04911a42935be03256b49 (patch)
tree532b5384e1818d533de7ff602a79ef179ad6acd1 /gcc/tree-sra.c
parent0123db8e39de9fdcb36e9a5ad26b3039474672bd (diff)
Prevent SRA from removing type changing assignment
2017-12-08 Martin Jambor <mjambor@suse.cz> PR tree-optimization/83141 * tree-sra.c (contains_vce_or_bfcref_p): Move up in the file, also test for MEM_REFs implicitely changing types with padding. Remove inline keyword. (build_accesses_from_assign): Added contains_vce_or_bfcref_p checks. testsuite/ * gcc.dg/tree-ssa/pr83141.c: New test. * gcc.dg/guality/pr54970.c: XFAIL tests querying a[0]. From-SVN: r255510
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 866cff0edb0..54f1c8d54d5 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1141,6 +1141,33 @@ contains_view_convert_expr_p (const_tree ref)
return false;
}
+/* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs
+ type conversion or a COMPONENT_REF with a bit-field field declaration. */
+
+static bool
+contains_vce_or_bfcref_p (const_tree ref)
+{
+ while (handled_component_p (ref))
+ {
+ if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
+ || (TREE_CODE (ref) == COMPONENT_REF
+ && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
+ return true;
+ ref = TREE_OPERAND (ref, 0);
+ }
+
+ if (TREE_CODE (ref) != MEM_REF
+ || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
+ return false;
+
+ tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
+ if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
+ != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
+ return true;
+
+ return false;
+}
+
/* Search the given tree for a declaration by skipping handled components and
exclude it from the candidates. */
@@ -1339,7 +1366,14 @@ build_accesses_from_assign (gimple *stmt)
racc->grp_assignment_read = 1;
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt)
&& !is_gimple_reg_type (racc->type))
- bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base));
+ {
+ if (contains_vce_or_bfcref_p (rhs))
+ bitmap_set_bit (cannot_scalarize_away_bitmap,
+ DECL_UID (racc->base));
+ else
+ bitmap_set_bit (should_scalarize_away_bitmap,
+ DECL_UID (racc->base));
+ }
if (storage_order_barrier_p (lhs))
racc->grp_unscalarizable_region = 1;
}
@@ -3416,24 +3450,6 @@ get_repl_default_def_ssa_name (struct access *racc)
return get_or_create_ssa_default_def (cfun, racc->replacement_decl);
}
-/* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a
- bit-field field declaration somewhere in it. */
-
-static inline bool
-contains_vce_or_bfcref_p (const_tree ref)
-{
- while (handled_component_p (ref))
- {
- if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
- || (TREE_CODE (ref) == COMPONENT_REF
- && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
- return true;
- ref = TREE_OPERAND (ref, 0);
- }
-
- return false;
-}
-
/* Examine both sides of the assignment statement pointed to by STMT, replace
them with a scalare replacement if there is one and generate copying of
replacements if scalarized aggregates have been used in the assignment. GSI