aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@gcc.gnu.org>2011-12-12 18:22:13 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2011-12-12 18:22:13 +0000
commit0b27284847b2547bcd4e8fce52ad0e906563af4b (patch)
tree1701bcdbcbbe05ab413e97138bebf0988508e893 /gcc
parentf7c8a2da7791fefb361db7f4e1a25cecb0a2b7e8 (diff)
downloadgcc-0b27284847b2547bcd4e8fce52ad0e906563af4b.zip
gcc-0b27284847b2547bcd4e8fce52ad0e906563af4b.tar.gz
gcc-0b27284847b2547bcd4e8fce52ad0e906563af4b.tar.bz2
re PR tree-optimization/50569 (unaligned memory accesses generated for memcpy)
PR tree-optimization/50569 * tree-sra.c (build_ref_for_model): Replicate a chain of COMPONENT_REFs in the expression of MODEL instead of just the last one. From-SVN: r182252
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20111212-1.c34
-rw-r--r--gcc/tree-sra.c66
4 files changed, 94 insertions, 19 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d429ea5..0d1dea3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,7 +1,12 @@
+2011-12-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR tree-optimization/50569
+ * tree-sra.c (build_ref_for_model): Replicate a chain of COMPONENT_REFs
+ in the expression of MODEL instead of just the last one.
+
2011-12-12 Dmitry Vyukov <dvyukov@google.com>
- * cgraphunit.c (init_lowered_empty_function):
- Fix flags for new edges.
+ * cgraphunit.c (init_lowered_empty_function): Fix flags for new edges.
2011-12-12 Jakub Jelinek <jakub@redhat.com>
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c74c878..dbe8ac6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2011-12-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20111212-1.c: New test.
+
2011-12-12 Jakub Jelinek <jakub@redhat.com>
PR testsuite/51511
diff --git a/gcc/testsuite/gcc.c-torture/execute/20111212-1.c b/gcc/testsuite/gcc.c-torture/execute/20111212-1.c
new file mode 100644
index 0000000..c46e6e9
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20111212-1.c
@@ -0,0 +1,34 @@
+/* PR tree-optimization/50569 */
+/* Reported by Paul Koning <pkoning@gcc.gnu.org> */
+/* Reduced testcase by Mikael Pettersson <mikpe@it.uu.se> */
+
+struct event {
+ struct {
+ unsigned int sec;
+ } sent __attribute__((packed));
+};
+
+void __attribute__((noinline,noclone)) frob_entry(char *buf)
+{
+ struct event event;
+
+ __builtin_memcpy(&event, buf, sizeof(event));
+ if (event.sent.sec < 64) {
+ event.sent.sec = -1U;
+ __builtin_memcpy(buf, &event, sizeof(event));
+ }
+}
+
+int main(void)
+{
+ union {
+ char buf[1 + sizeof(struct event)];
+ int align;
+ } u;
+
+ __builtin_memset(&u, 0, sizeof u);
+
+ frob_entry(&u.buf[1]);
+
+ return 0;
+}
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 346519a..b921c76 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1492,33 +1492,65 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
}
+DEF_VEC_ALLOC_P_STACK (tree);
+#define VEC_tree_stack_alloc(alloc) VEC_stack_alloc (tree, alloc)
+
/* Construct a memory reference to a part of an aggregate BASE at the given
- OFFSET and of the same type as MODEL. In case this is a reference to a
- component, the function will replicate the last COMPONENT_REF of model's
- expr to access it. GSI and INSERT_AFTER have the same meaning as in
- build_ref_for_offset. */
+ OFFSET and of the type of MODEL. In case this is a chain of references
+ to component, the function will replicate the chain of COMPONENT_REFs of
+ the expression of MODEL to access it. GSI and INSERT_AFTER have the same
+ meaning as in build_ref_for_offset. */
static tree
build_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset,
struct access *model, gimple_stmt_iterator *gsi,
bool insert_after)
{
+ tree type = model->type, t;
+ VEC(tree,stack) *cr_stack = NULL;
+
if (TREE_CODE (model->expr) == COMPONENT_REF)
{
- tree t, exp_type, fld = TREE_OPERAND (model->expr, 1);
- tree cr_offset = component_ref_field_offset (model->expr);
-
- gcc_assert (cr_offset && host_integerp (cr_offset, 1));
- offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT;
- offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (fld));
- exp_type = TREE_TYPE (TREE_OPERAND (model->expr, 0));
- t = build_ref_for_offset (loc, base, offset, exp_type, gsi, insert_after);
- return fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (fld), t, fld,
- TREE_OPERAND (model->expr, 2));
+ tree expr = model->expr;
+
+ /* Create a stack of the COMPONENT_REFs so later we can walk them in
+ order from inner to outer. */
+ cr_stack = VEC_alloc (tree, stack, 6);
+
+ do {
+ tree field = TREE_OPERAND (expr, 1);
+ tree cr_offset = component_ref_field_offset (expr);
+ gcc_assert (cr_offset && host_integerp (cr_offset, 1));
+
+ offset -= TREE_INT_CST_LOW (cr_offset) * BITS_PER_UNIT;
+ offset -= TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field));
+
+ VEC_safe_push (tree, stack, cr_stack, expr);
+
+ expr = TREE_OPERAND (expr, 0);
+ type = TREE_TYPE (expr);
+ } while (TREE_CODE (expr) == COMPONENT_REF);
}
- else
- return build_ref_for_offset (loc, base, offset, model->type,
- gsi, insert_after);
+
+ t = build_ref_for_offset (loc, base, offset, type, gsi, insert_after);
+
+ if (TREE_CODE (model->expr) == COMPONENT_REF)
+ {
+ unsigned i;
+ tree expr;
+
+ /* Now replicate the chain of COMPONENT_REFs from inner to outer. */
+ FOR_EACH_VEC_ELT_REVERSE (tree, cr_stack, i, expr)
+ {
+ tree field = TREE_OPERAND (expr, 1);
+ t = fold_build3_loc (loc, COMPONENT_REF, TREE_TYPE (field), t, field,
+ TREE_OPERAND (expr, 2));
+ }
+
+ VEC_free (tree, stack, cr_stack);
+ }
+
+ return t;
}
/* Construct a memory reference consisting of component_refs and array_refs to