[PATCH, PR 50444] Decrease MEM_REF TYPE_ALIGN in build_ref_for_offset
Richard Guenther
rguenther@suse.de
Thu Jan 12 14:23:00 GMT 2012
On Thu, 12 Jan 2012, Martin Jambor wrote:
> Hi,
>
> I tend to believe that this is the SRA part of a fix for PR 50444 (and
> possibly some strict alignment SRA-related bugs too. What it does is
> that it decreases the alignment of the built MEM_REF type if it seems
> necessary. That is in cases when the alignment of the type as it
> arrived in the parameter is larger than the alignment of the base we
> are building the MEM_REF on top of or the MEM_REF we are replacing or
> when it is larger than the biggest power of two that divides the
> offset we are adding, if it is non zero).
>
> This patch alone fixes the testcase on i686, on x86_64 the testcase
> stops segfaulting but the final comparison does not go well and the
> testcase returns non-zero exit code. However, I belive that is most
> probably an expansion problem, rather than SRA's. Perhaps it should
> be also noted that if I revert SRA's build_ref_for_model to what it
> was in revision 164280 and SRA creates only a MEM_REF rather than a
> COMPONENT_REF on top of a MEM_REF which it does now, the assignment
> expansion takes the "optab_handler (movmisalign_optab, mode)" route
> and the testcase is compiled well, with both the segfault gone and
> comparison yielding the correct result. I plan to have a look at what
> goes on in expansion with the current build_ref_for_model shortly but
> thought I'd post this for review and comments before that.
>
> A similar patch has passed bootstrap and testsuite on x86_64-linux,
> this exact one is undergoing the same as I'm writing this. Is it the
> good direction, should I commit the patch (to trunk and the 4.6
> branch) if it passes?
I don't think this is a suitable place to discover the alignment
for the access. In fact what we should do is use the same alignment
that was used for the access we replicate/decompose (or is the
'base' argument to build_ref_for_offset always the original access?)
Also ...
> Thanks,
>
> Martin
>
>
> 2012-01-12 Martin Jambor <mjambor@suse.cz>
>
> PR tree-optimization/50444
> * tree-sra.c (build_ref_for_offset): Decrease the alignment of the
> type of the created MEM_REF if necessary.
>
> Index: src/gcc/tree-sra.c
> ===================================================================
> --- src.orig/gcc/tree-sra.c
> +++ src/gcc/tree-sra.c
> @@ -1458,9 +1458,10 @@ build_ref_for_offset (location_t loc, tr
> tree exp_type, gimple_stmt_iterator *gsi,
> bool insert_after)
> {
> + HOST_WIDE_INT base_offset, final_offset;
> + unsigned int align;
> tree prev_base = base;
> tree off;
> - HOST_WIDE_INT base_offset;
>
> gcc_checking_assert (offset % BITS_PER_UNIT == 0);
>
> @@ -1488,24 +1489,34 @@ build_ref_for_offset (location_t loc, tr
> gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
> update_stmt (stmt);
>
> + final_offset = offset / BITS_PER_UNIT;
> off = build_int_cst (reference_alias_ptr_type (prev_base),
> - offset / BITS_PER_UNIT);
> + final_offset);
> base = tmp;
> + align = get_object_alignment (prev_base);
> }
> else if (TREE_CODE (base) == MEM_REF)
> {
> - off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)),
> - base_offset + offset / BITS_PER_UNIT);
> + final_offset = base_offset + offset / BITS_PER_UNIT;
> + off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)), final_offset);
> off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off);
> + align = get_object_or_type_alignment (base);
> base = unshare_expr (TREE_OPERAND (base, 0));
> }
> else
> {
> - off = build_int_cst (reference_alias_ptr_type (base),
> - base_offset + offset / BITS_PER_UNIT);
> + final_offset = base_offset + offset / BITS_PER_UNIT;
> + off = build_int_cst (reference_alias_ptr_type (base), final_offset);
> + align = get_object_alignment (base);
I think you always want to use get_object_alignment_1 to be able to
factor in offset and thus knowledge about explicit misalignment,
otherwise you'd pessimize quite some cases. Then the question
is whether to factor in TYPE_ALIGN of the original access
(see get_object_or_type_alignment).
Richard.
> base = build_fold_addr_expr (unshare_expr (base));
> }
>
> + if (final_offset != 0)
> + align = MIN (align,
> + (1u << ctz_hwi (absu_hwi (final_offset))) * BITS_PER_UNIT);
> + if (align < TYPE_ALIGN (exp_type))
> + exp_type = build_aligned_type (exp_type, align);
> +
> return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
> }
More information about the Gcc-patches
mailing list