diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-12-08 13:11:02 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2017-12-08 13:11:02 +0100 |
commit | d90ffcfb7d105d004cf04911a42935be03256b49 (patch) | |
tree | 532b5384e1818d533de7ff602a79ef179ad6acd1 /gcc/tree-sra.c | |
parent | 0123db8e39de9fdcb36e9a5ad26b3039474672bd (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.c | 54 |
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 |