https://gcc.gnu.org/g:95d32d92af71456535a1d7ebc566d7c68f5d6eb4
commit 95d32d92af71456535a1d7ebc566d7c68f5d6eb4 Author: Michael Matz <[email protected]> Date: Thu Mar 1 00:34:42 2018 +0100 update-stmt: move mark_addressable() later when an address is constructed but then only used within a MEM_EXPR, the argument doesn't need TREE_ADDRESSABLE set; doing so is premature and causes missed optimizations (in the testsuite it seems only gcc.target/i386/pr68961.c and gcc.dg/ipa/ipa-sra-1.c). So move the marking further down in the vectorizer where it's unavoidable. Diff: --- gcc/tree-sra.c | 4 ++-- gcc/tree-vect-data-refs.c | 6 +++--- gcc/tree-vect-stmts.c | 20 +++++++++++++++++++- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 52481c9e6915..55103c973f1f 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1760,7 +1760,7 @@ build_ref_for_offset (location_t loc, tree base, poly_int64 offset, { off = build_int_cst (reference_alias_ptr_type (prev_base), base_offset + byte_offset); - base = build_addr (unshare_expr (base)); + base = build_fold_addr_expr (unshare_expr (base)); } unsigned int align_bound = known_alignment (misalign + offset); @@ -1841,7 +1841,7 @@ build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, { off = build_int_cst (reference_alias_ptr_type (base), base_offset + offset / BITS_PER_UNIT); - base = build_addr (unshare_expr (base)); + base = build_fold_addr_expr (unshare_expr (base)); } return fold_build2_loc (loc, MEM_REF, model->type, base, off); diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 875da995f39a..527b93025301 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -4607,13 +4607,11 @@ vect_create_addr_base_for_vector_ref (gimple *stmt, /* base + base_offset */ if (loop_vinfo) { - if (TREE_CODE (data_ref_base) == ADDR_EXPR) - mark_addressable (TREE_OPERAND (data_ref_base, 0)); addr_base = fold_build_pointer_plus (data_ref_base, base_offset); } else { - addr_base = build_addr (unshare_expr (DR_REF (dr))); + addr_base = build_fold_addr_expr (unshare_expr (DR_REF (dr))); } vect_ptr_type = build_pointer_type (STMT_VINFO_VECTYPE (stmt_info)); @@ -4990,6 +4988,8 @@ bump_vector_ptr (tree dataref_ptr, gimple *ptr_incr, gimple_stmt_iterator *gsi, new_dataref_ptr = copy_ssa_name (dataref_ptr); else new_dataref_ptr = make_ssa_name (TREE_TYPE (dataref_ptr)); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); incr_stmt = gimple_build_assign (new_dataref_ptr, POINTER_PLUS_EXPR, dataref_ptr, update); vect_finish_stmt_generation (stmt, incr_stmt, gsi); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 49716c09af2c..671d9b594a5e 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -6943,6 +6943,8 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, VEC_ARRAY). */ unsigned int align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype)); tree alias_ptr = build_int_cst (ref_type, align); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); call = gimple_build_call_internal (IFN_MASK_STORE_LANES, 4, dataref_ptr, alias_ptr, final_mask, vec_array); @@ -6993,6 +6995,8 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, { tree scale = size_int (gs_info.scale); gcall *call; + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); if (loop_masks) call = gimple_build_call_internal (IFN_MASK_SCATTER_STORE, 5, dataref_ptr, vec_offset, @@ -7057,6 +7061,8 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, { align = least_bit_hwi (misalign | align); tree ptr = build_int_cst (ref_type, align); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); gcall *call = gimple_build_call_internal (IFN_MASK_STORE, 4, dataref_ptr, ptr, @@ -8088,6 +8094,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, VEC_MASK). */ unsigned int align = TYPE_ALIGN_UNIT (TREE_TYPE (vectype)); tree alias_ptr = build_int_cst (ref_type, align); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); call = gimple_build_call_internal (IFN_MASK_LOAD_LANES, 3, dataref_ptr, alias_ptr, final_mask); @@ -8148,6 +8156,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, { tree scale = size_int (gs_info.scale); gcall *call; + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); if (loop_masks) call = gimple_build_call_internal (IFN_MASK_GATHER_LOAD, 4, dataref_ptr, @@ -8184,6 +8194,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, { align = least_bit_hwi (misalign | align); tree ptr = build_int_cst (ref_type, align); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); gcall *call = gimple_build_call_internal (IFN_MASK_LOAD, 3, dataref_ptr, ptr, @@ -8218,6 +8230,8 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, tree vs = size_int (TYPE_VECTOR_SUBPARTS (vectype)); + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); if (compute_in_loop) msq = vect_setup_realignment (first_stmt, gsi, &realignment_token, @@ -8270,7 +8284,11 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt, if (TREE_CODE (dataref_ptr) == SSA_NAME) new_temp = copy_ssa_name (dataref_ptr); else - new_temp = make_ssa_name (TREE_TYPE (dataref_ptr)); + { + if (TREE_CODE (dataref_ptr) == ADDR_EXPR) + mark_addressable (TREE_OPERAND (dataref_ptr, 0)); + new_temp = make_ssa_name (TREE_TYPE (dataref_ptr)); + } unsigned int align = DR_TARGET_ALIGNMENT (first_dr); new_stmt = gimple_build_assign (new_temp, BIT_AND_EXPR, dataref_ptr,
