diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-27 14:56:54 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-01-27 14:56:54 +0000 |
commit | 25b3bbad6624357c1ac6a31e0be6fca37182fb78 (patch) | |
tree | 32ec665bb53ff9c8bb80cf933b2e0e8513aab2ba /gcc/tree-sra.c | |
parent | a598af2a9120feca416b38688593070db46cd07e (diff) | |
download | gcc-25b3bbad6624357c1ac6a31e0be6fca37182fb78.tar.gz |
2012-01-27 Richard Guenther <rguenther@suse.de>
PR tree-optimization/50444
* tree-sra.c (build_ref_for_offset): Properly adjust the
MEM_REF type for unaligned accesses.
* gcc.dg/torture/pr50444.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@183630 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r-- | gcc/tree-sra.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index f4146b2acbc..fa67e94cca3 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1461,6 +1461,8 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, tree prev_base = base; tree off; HOST_WIDE_INT base_offset; + unsigned HOST_WIDE_INT misalign; + unsigned int align; gcc_checking_assert (offset % BITS_PER_UNIT == 0); @@ -1506,6 +1508,23 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, base = build_fold_addr_expr (unshare_expr (base)); } + /* If prev_base were always an originally performed access + we can extract more optimistic alignment information + by looking at the access mode. That would constrain the + alignment of base + base_offset which we would need to + adjust according to offset. + ??? But it is not at all clear that prev_base is an access + that was in the IL that way, so be conservative for now. */ + align = get_pointer_alignment_1 (base, &misalign); + misalign += (double_int_sext (tree_to_double_int (off), + TYPE_PRECISION (TREE_TYPE (off))).low + * BITS_PER_UNIT); + misalign = misalign & (align - 1); + if (misalign != 0) + align = (misalign & -misalign); + 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); } |