diff options
author | Richard Biener <rguenther@suse.de> | 2019-12-03 11:59:13 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-12-03 11:59:13 +0000 |
commit | 5105b576dfdcae0c6cc30a89a68b4ef3cbf56a1c (patch) | |
tree | 5c84bcbb4ae4e3a1b2b326b0cbf5f37160d5b143 /gcc/gimple-fold.c | |
parent | 8f316505da1348cca2eb7aeac7919710c255d396 (diff) | |
download | gcc-5105b576dfdcae0c6cc30a89a68b4ef3cbf56a1c.zip gcc-5105b576dfdcae0c6cc30a89a68b4ef3cbf56a1c.tar.gz gcc-5105b576dfdcae0c6cc30a89a68b4ef3cbf56a1c.tar.bz2 |
re PR tree-optimization/92645 (Hand written vector code is 450 times slower when compiled with GCC compared to Clang)
2019-12-03 Richard Biener <rguenther@suse.de>
PR tree-optimization/92645
* gimple-fold.c (gimple_fold_builtin_memory_op): Fold memcpy
from or to a properly aligned register variable.
* gcc.target/i386/pr92645-5.c: New testcase.
From-SVN: r278934
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r-- | gcc/gimple-fold.c | 41 |
1 files changed, 19 insertions, 22 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 849bee2..24a478a 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -986,36 +986,33 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi, src_align = get_pointer_alignment (src); dest_align = get_pointer_alignment (dest); - if (dest_align < TYPE_ALIGN (desttype) - || src_align < TYPE_ALIGN (srctype)) - return false; + /* Choose between src and destination type for the access based + on alignment, whether the access constitutes a register access + and whether it may actually expose a declaration for SSA rewrite + or SRA decomposition. */ destvar = NULL_TREE; + srcvar = NULL_TREE; if (TREE_CODE (dest) == ADDR_EXPR && var_decl_component_p (TREE_OPERAND (dest, 0)) - && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len)) + && tree_int_cst_equal (TYPE_SIZE_UNIT (desttype), len) + && dest_align >= TYPE_ALIGN (desttype) + && (is_gimple_reg_type (desttype) + || src_align >= TYPE_ALIGN (desttype))) destvar = fold_build2 (MEM_REF, desttype, dest, off0); - - srcvar = NULL_TREE; - if (TREE_CODE (src) == ADDR_EXPR - && var_decl_component_p (TREE_OPERAND (src, 0)) - && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len)) - { - if (!destvar - || src_align >= TYPE_ALIGN (desttype)) - srcvar = fold_build2 (MEM_REF, destvar ? desttype : srctype, - src, off0); - else if (!STRICT_ALIGNMENT) - { - srctype = build_aligned_type (TYPE_MAIN_VARIANT (desttype), - src_align); - srcvar = fold_build2 (MEM_REF, srctype, src, off0); - } - } - + else if (TREE_CODE (src) == ADDR_EXPR + && var_decl_component_p (TREE_OPERAND (src, 0)) + && tree_int_cst_equal (TYPE_SIZE_UNIT (srctype), len) + && src_align >= TYPE_ALIGN (srctype) + && (is_gimple_reg_type (srctype) + || dest_align >= TYPE_ALIGN (srctype))) + srcvar = fold_build2 (MEM_REF, srctype, src, off0); if (srcvar == NULL_TREE && destvar == NULL_TREE) return false; + /* Now that we chose an access type express the other side in + terms of it if the target allows that with respect to alignment + constraints. */ if (srcvar == NULL_TREE) { if (src_align >= TYPE_ALIGN (desttype)) |