aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-sra.c
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2012-12-07 13:50:43 +0100
committerMartin Jambor <jamborm@gcc.gnu.org>2012-12-07 13:50:43 +0100
commit4bd7b70b8954bb935a3b88ffa70f384552cc6fb3 (patch)
treed07f6d3b5a64e67856103436b1ad8de49a207b82 /gcc/tree-sra.c
parenta09b3c50dd4ab7df41376abae0fe5f07cc172e07 (diff)
downloadgcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.zip
gcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.tar.gz
gcc-4bd7b70b8954bb935a3b88ffa70f384552cc6fb3.tar.bz2
re PR tree-optimization/55590 (SRA still produces unnecessarily unaligned memory accesses)
2012-12-07 Martin Jambor <mjambor@suse.cz> PR tree-optimization/55590 * tree-sra.c (build_ref_for_offset): Use get_object_alignment_1 to get base alignment. * testsuite/gcc.target/i386/pr55590-1.c: New test. * testsuite/gcc.target/i386/pr55590-2.c: Likewise. From-SVN: r194300
Diffstat (limited to 'gcc/tree-sra.c')
-rw-r--r--gcc/tree-sra.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 4580ad2..21d8a51 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1423,7 +1423,10 @@ make_fancy_name (tree expr)
EXP_TYPE at the given OFFSET. If BASE is something for which
get_addr_base_and_unit_offset returns NULL, gsi must be non-NULL and is used
to insert new statements either before or below the current one as specified
- by INSERT_AFTER. This function is not capable of handling bitfields. */
+ by INSERT_AFTER. This function is not capable of handling bitfields.
+
+ BASE must be either a declaration or a memory reference that has correct
+ alignment ifformation embeded in it (e.g. a pre-existing one in SRA). */
tree
build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
@@ -1437,7 +1440,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
unsigned int align;
gcc_checking_assert (offset % BITS_PER_UNIT == 0);
-
+ get_object_alignment_1 (base, &align, &misalign);
base = get_addr_base_and_unit_offset (base, &base_offset);
/* get_addr_base_and_unit_offset returns NULL for references with a variable
@@ -1476,22 +1479,7 @@ 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. */
- if (!get_pointer_alignment_1 (base, &align, &misalign))
- {
- gcc_assert (misalign == 0);
- if (TREE_CODE (prev_base) == MEM_REF
- || TREE_CODE (prev_base) == TARGET_MEM_REF)
- align = TYPE_ALIGN (TREE_TYPE (prev_base));
- }
- misalign += (tree_to_double_int (off)
- .sext (TYPE_PRECISION (TREE_TYPE (off))).low
- * BITS_PER_UNIT);
- misalign = misalign & (align - 1);
+ misalign = (misalign + offset) & (align - 1);
if (misalign != 0)
align = (misalign & -misalign);
if (align < TYPE_ALIGN (exp_type))