diff options
author | Richard Biener <rguenther@suse.de> | 2019-05-16 08:03:49 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-05-16 08:03:49 +0000 |
commit | 1bf2a0b90f2457f6d9301535560eb5e05978261b (patch) | |
tree | bce84fa1f77945c69ed17cb17728304fec2ac700 /gcc/tree-ssa.c | |
parent | adfe6e4b2f8e7288710eac6bacd6bae8d6ea3c05 (diff) | |
download | gcc-1bf2a0b90f2457f6d9301535560eb5e05978261b.zip gcc-1bf2a0b90f2457f6d9301535560eb5e05978261b.tar.gz gcc-1bf2a0b90f2457f6d9301535560eb5e05978261b.tar.bz2 |
re PR target/90424 (memcpy into vector builtin not optimized)
2019-05-16 Richard Biener <rguenther@suse.de>
PR tree-optimization/90424
* tree-ssa.c (non_rewritable_lvalue_p): Handle inserts from
aligned subvectors.
(execute_update_addresses_taken): Likewise.
* tree-cfg.c (verify_gimple_assign_ternary): Likewise.
* g++.target/i386/pr90424-1.C: New testcase.
* g++.target/i386/pr90424-2.C: Likewise.
From-SVN: r271279
Diffstat (limited to 'gcc/tree-ssa.c')
-rw-r--r-- | gcc/tree-ssa.c | 49 |
1 files changed, 37 insertions, 12 deletions
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 489f6dc..8e3aec1 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1521,14 +1521,29 @@ non_rewritable_lvalue_p (tree lhs) if (DECL_P (decl) && VECTOR_TYPE_P (TREE_TYPE (decl)) && TYPE_MODE (TREE_TYPE (decl)) != BLKmode - && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), - TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (decl))), 0) && known_ge (mem_ref_offset (lhs), 0) && known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))), mem_ref_offset (lhs)) && multiple_of_p (sizetype, TREE_OPERAND (lhs, 1), TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) - return false; + { + poly_uint64 lhs_bits, nelts; + if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)), &lhs_bits) + && multiple_p (lhs_bits, + tree_to_uhwi + (TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl)))), + &nelts)) + { + if (known_eq (nelts, 1u)) + return false; + /* For sub-vector inserts the insert vector mode has to be + supported. */ + tree vtype = build_vector_type (TREE_TYPE (TREE_TYPE (decl)), + nelts); + if (TYPE_MODE (vtype) != BLKmode) + return false; + } + } } /* A vector-insert using a BIT_FIELD_REF is rewritable using @@ -1866,20 +1881,30 @@ execute_update_addresses_taken (void) && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)) && VECTOR_TYPE_P (TREE_TYPE (sym)) && TYPE_MODE (TREE_TYPE (sym)) != BLKmode - && operand_equal_p (TYPE_SIZE_UNIT (TREE_TYPE (lhs)), - TYPE_SIZE_UNIT - (TREE_TYPE (TREE_TYPE (sym))), 0) - && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1)) - && tree_int_cst_lt (TREE_OPERAND (lhs, 1), - TYPE_SIZE_UNIT (TREE_TYPE (sym))) - && (tree_to_uhwi (TREE_OPERAND (lhs, 1)) - % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0) + && known_ge (mem_ref_offset (lhs), 0) + && known_gt (wi::to_poly_offset + (TYPE_SIZE_UNIT (TREE_TYPE (sym))), + mem_ref_offset (lhs)) + && multiple_of_p (sizetype, + TREE_OPERAND (lhs, 1), + TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) { tree val = gimple_assign_rhs1 (stmt); if (! types_compatible_p (TREE_TYPE (val), TREE_TYPE (TREE_TYPE (sym)))) { - tree tem = make_ssa_name (TREE_TYPE (TREE_TYPE (sym))); + poly_uint64 lhs_bits, nelts; + tree temtype = TREE_TYPE (TREE_TYPE (sym)); + if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)), + &lhs_bits) + && multiple_p (lhs_bits, + tree_to_uhwi + (TYPE_SIZE (TREE_TYPE + (TREE_TYPE (sym)))), + &nelts) + && maybe_ne (nelts, 1u)) + temtype = build_vector_type (temtype, nelts); + tree tem = make_ssa_name (temtype); gimple *pun = gimple_build_assign (tem, build1 (VIEW_CONVERT_EXPR, |