diff options
author | Richard Guenther <rguenther@suse.de> | 2012-01-27 14:56:54 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-01-27 14:56:54 +0000 |
commit | aff8659424a98c714d2de2eeac0e80f7751a87a1 (patch) | |
tree | 32ec665bb53ff9c8bb80cf933b2e0e8513aab2ba /gcc/tree-sra.c | |
parent | 223453574e2860830258588ce0104d8971c43ee3 (diff) | |
download | gcc-aff8659424a98c714d2de2eeac0e80f7751a87a1.zip gcc-aff8659424a98c714d2de2eeac0e80f7751a87a1.tar.gz gcc-aff8659424a98c714d2de2eeac0e80f7751a87a1.tar.bz2 |
re PR tree-optimization/50444 (-ftree-sra ignores alignment)
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.
From-SVN: r183630
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 f4146b2..fa67e94 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); } |