From 43332529edd116f18441629f484c36a645ccb763 Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Tue, 13 Mar 2012 15:29:42 +0100 Subject: [PATCH] expr.c (expand_assignment): Handle misaligned scalar writes to memory through top-level MEM_REFs by calling... 2012-03-13 Martin Jambor * expr.c (expand_assignment): Handle misaligned scalar writes to memory through top-level MEM_REFs by calling store_bit_field. * testsuite/gcc.dg/misaligned-expand-2.c: New test. From-SVN: r185336 --- gcc/ChangeLog | 5 +++ gcc/expr.c | 22 ++++++++---- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/misaligned-expand-2.c | 42 ++++++++++++++++++++++ 4 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/misaligned-expand-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5c679cf479..19bd4ed062c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2012-03-13 Martin Jambor + + * expr.c (expand_assignment): Handle misaligned scalar writes to + memory through top-level MEM_REFs by calling store_bit_field. + 2012-03-13 Richard Guenther PR middle-end/52134 diff --git a/gcc/expr.c b/gcc/expr.c index e6fc100f9f8..59b76a4b5f5 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4593,10 +4593,12 @@ expand_assignment (tree to, tree from, bool nontemporal) if ((TREE_CODE (to) == MEM_REF || TREE_CODE (to) == TARGET_MEM_REF) && mode != BLKmode + && !mem_ref_refers_to_non_mem_p (to) && ((align = get_object_or_type_alignment (to)) < GET_MODE_ALIGNMENT (mode)) - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) + && (((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + || SLOW_UNALIGNED_ACCESS (mode, align))) { addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (to, 0)))); @@ -4639,11 +4641,17 @@ expand_assignment (tree to, tree from, bool nontemporal) if (TREE_THIS_VOLATILE (to)) MEM_VOLATILE_P (mem) = 1; - create_fixed_operand (&ops[0], mem); - create_input_operand (&ops[1], reg, mode); - /* The movmisalign pattern cannot fail, else the assignment would - silently be omitted. */ - expand_insn (icode, 2, ops); + if (icode != CODE_FOR_nothing) + { + create_fixed_operand (&ops[0], mem); + create_input_operand (&ops[1], reg, mode); + /* The movmisalign pattern cannot fail, else the assignment + would silently be omitted. */ + expand_insn (icode, 2, ops); + } + else + store_bit_field (mem, GET_MODE_BITSIZE (mode), + 0, 0, 0, mode, reg); return; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1e6c43facdc..96b775ea746 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-03-13 Martin Jambor + + * gcc.dg/misaligned-expand-2.c: New test. + 2012-03-13 Richard Guenther PR middle-end/52134 diff --git a/gcc/testsuite/gcc.dg/misaligned-expand-2.c b/gcc/testsuite/gcc.dg/misaligned-expand-2.c new file mode 100644 index 00000000000..f3ae97f69e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/misaligned-expand-2.c @@ -0,0 +1,42 @@ +/* Test that expand can generate correct stores to misaligned data even on + strict alignment platforms. */ + +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +extern void abort (); + +typedef unsigned int myint __attribute__((aligned(1))); + +void +foo (myint *p, unsigned int i) +{ + *p = i; +} + +#define cst 0xdeadbeef +#define NUM 8 + +struct blah +{ + char c; + myint i[NUM]; +}; + +struct blah g; + +#define cst 0xdeadbeef + +int +main (int argc, char **argv) +{ + int k; + + for (k = 0; k < NUM; k++) + { + foo (&g.i[k], cst); + if (g.i[k] != cst) + abort (); + } + return 0; +}