From: Jakub Jelinek Date: Wed, 9 Dec 2015 13:42:06 +0000 (+0100) Subject: re PR tree-optimization/68786 (Aligned masked store is generated for unaligned pointer) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=08554c26c4541be7d6ec0fec4d8810e97f56caab;p=gcc.git re PR tree-optimization/68786 (Aligned masked store is generated for unaligned pointer) PR tree-optimization/68786 * tree-if-conv.c: Include builtins.h. (predicate_mem_writes): Put result of get_object_alignment (ref) into second argument's value. * tree-vect-stmts.c (vectorizable_mask_load_store): Put minimum pointer alignment into second argument's value. * tree-data-ref.c (get_references_in_stmt): Use value of second argument for build_aligned_type, and only the type to build a zero second argument for MEM_REF. * internal-fn.c (expand_mask_load_optab_fn, expand_mask_store_optab_fn): Likewise. From-SVN: r231454 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 3da8d1b6add..8526be6e85b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-12-09 Jakub Jelinek + + PR tree-optimization/68786 + * tree-if-conv.c: Include builtins.h. + (predicate_mem_writes): Put result of get_object_alignment (ref) + into second argument's value. + * tree-vect-stmts.c (vectorizable_mask_load_store): Put minimum + pointer alignment into second argument's value. + * tree-data-ref.c (get_references_in_stmt): Use value of second + argument for build_aligned_type, and only the type to build + a zero second argument for MEM_REF. + * internal-fn.c (expand_mask_load_optab_fn, + expand_mask_store_optab_fn): Likewise. + 2015-12-09 Richard Biener PR tree-optimization/68583 diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c index 2be2d8806f1..3ceaffe67ea 100644 --- a/gcc/internal-fn.c +++ b/gcc/internal-fn.c @@ -1911,16 +1911,20 @@ static void expand_mask_load_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { struct expand_operand ops[3]; - tree type, lhs, rhs, maskt; + tree type, lhs, rhs, maskt, ptr; rtx mem, target, mask; + unsigned align; maskt = gimple_call_arg (stmt, 2); lhs = gimple_call_lhs (stmt); if (lhs == NULL_TREE) return; type = TREE_TYPE (lhs); - rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), - gimple_call_arg (stmt, 1)); + ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0); + align = tree_to_shwi (gimple_call_arg (stmt, 1)); + if (TYPE_ALIGN (type) != align) + type = build_aligned_type (type, align); + rhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr); mem = expand_expr (rhs, NULL_RTX, VOIDmode, EXPAND_WRITE); gcc_assert (MEM_P (mem)); @@ -1940,14 +1944,18 @@ static void expand_mask_store_optab_fn (internal_fn, gcall *stmt, convert_optab optab) { struct expand_operand ops[3]; - tree type, lhs, rhs, maskt; + tree type, lhs, rhs, maskt, ptr; rtx mem, reg, mask; + unsigned align; maskt = gimple_call_arg (stmt, 2); rhs = gimple_call_arg (stmt, 3); type = TREE_TYPE (rhs); - lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), - gimple_call_arg (stmt, 1)); + ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0); + align = tree_to_shwi (gimple_call_arg (stmt, 1)); + if (TYPE_ALIGN (type) != align) + type = build_aligned_type (type, align); + lhs = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), ptr); mem = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); gcc_assert (MEM_P (mem)); diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c index 74f7614ff93..ec800556b1b 100644 --- a/gcc/tree-data-ref.c +++ b/gcc/tree-data-ref.c @@ -3872,6 +3872,8 @@ get_references_in_stmt (gimple *stmt, vec *references) else if (stmt_code == GIMPLE_CALL) { unsigned i, n; + tree ptr, type; + unsigned int align; ref.is_read = false; if (gimple_call_internal_p (stmt)) @@ -3882,12 +3884,16 @@ get_references_in_stmt (gimple *stmt, vec *references) break; ref.is_read = true; case IFN_MASK_STORE: - ref.ref = fold_build2 (MEM_REF, - ref.is_read - ? TREE_TYPE (gimple_call_lhs (stmt)) - : TREE_TYPE (gimple_call_arg (stmt, 3)), - gimple_call_arg (stmt, 0), - gimple_call_arg (stmt, 1)); + ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), 0); + align = tree_to_shwi (gimple_call_arg (stmt, 1)); + if (ref.is_read) + type = TREE_TYPE (gimple_call_lhs (stmt)); + else + type = TREE_TYPE (gimple_call_arg (stmt, 3)); + if (TYPE_ALIGN (type) != align) + type = build_aligned_type (type, align); + ref.ref = fold_build2 (MEM_REF, type, gimple_call_arg (stmt, 0), + ptr); references->safe_push (ref); return false; default: diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 637fa226935..55b590b253d 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -111,6 +111,7 @@ along with GCC; see the file COPYING3. If not see #include "dbgcnt.h" #include "tree-hash-traits.h" #include "varasm.h" +#include "builtins.h" /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; @@ -2056,7 +2057,8 @@ predicate_mem_writes (loop_p loop) vect_sizes.safe_push (bitsize); vect_masks.safe_push (mask); } - ptr = build_int_cst (reference_alias_ptr_type (ref), 0); + ptr = build_int_cst (reference_alias_ptr_type (ref), + get_object_alignment (ref)); /* Copy points-to info if possible. */ if (TREE_CODE (addr) == SSA_NAME && !SSA_NAME_PTR_INFO (addr)) copy_ref_info (build2 (MEM_REF, TREE_TYPE (ref), addr, ptr), diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 1a65c03753d..56aa2c8cce5 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -2058,10 +2058,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, misalign = DR_MISALIGNMENT (dr); set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, misalign); + tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), + misalign ? misalign & -misalign : align); new_stmt = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr, - gimple_call_arg (stmt, 1), - vec_mask, vec_rhs); + ptr, vec_mask, vec_rhs); vect_finish_stmt_generation (stmt, new_stmt, gsi); if (i == 0) STMT_VINFO_VEC_STMT (stmt_info) = *vec_stmt = new_stmt; @@ -2107,10 +2108,11 @@ vectorizable_mask_load_store (gimple *stmt, gimple_stmt_iterator *gsi, misalign = DR_MISALIGNMENT (dr); set_ptr_info_alignment (get_ptr_info (dataref_ptr), align, misalign); + tree ptr = build_int_cst (TREE_TYPE (gimple_call_arg (stmt, 1)), + misalign ? misalign & -misalign : align); new_stmt = gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr, - gimple_call_arg (stmt, 1), - vec_mask); + ptr, vec_mask); gimple_call_set_lhs (new_stmt, make_ssa_name (vec_dest)); vect_finish_stmt_generation (stmt, new_stmt, gsi); if (i == 0)