Hi, On Mon, Mar 12, 2012 at 03:09:04PM +0100, Martin Jambor wrote: > Hi, > > this patch is very similar to the one I posted before > (http://gcc.gnu.org/ml/gcc-patches/2012-02/msg01377.html) except that > it is now adjusted to sit on top of the new one before this and does > not ignore complex numbers...
This is the same patch updated to apply on top of the new version of the previous one (which I have committed a moment ago). Again, bootstrapped and tested on x86_64-linux (all languages including Ada and Java), usparc64-linux (without Java) and ia64-linux (without Ada), the i686 compile farm machine was not accessible yesterday so I don't have any results from it but will start a test right now. OK for trunk? Thanks, Martin 2012-03-12 Martin Jambor <mjam...@suse.cz> * expr.c (expand_expr_real_1): handle misaligned scalar reads from memory through MEM_REFs by calling extract_bit_field. * testsuite/gcc.dg/misaligned-expand-1.c: New test. * testsuite/gcc.dg/misaligned-expand-3.c: Likewise. Index: src/gcc/expr.c =================================================================== --- src.orig/gcc/expr.c +++ src/gcc/expr.c @@ -9411,21 +9411,27 @@ expand_expr_real_1 (tree exp, rtx target MEM_VOLATILE_P (temp) = 1; if (modifier != EXPAND_WRITE && mode != BLKmode - && align < GET_MODE_ALIGNMENT (mode) - /* If the target does not have special handling for unaligned - loads of mode then it can use regular moves for them. */ - && ((icode = optab_handler (movmisalign_optab, mode)) - != CODE_FOR_nothing)) + && align < GET_MODE_ALIGNMENT (mode)) { - struct expand_operand ops[2]; + if ((icode = optab_handler (movmisalign_optab, mode)) + != CODE_FOR_nothing) + { + struct expand_operand ops[2]; - /* We've already validated the memory, and we're creating a - new pseudo destination. The predicates really can't fail, - nor can the generator. */ - create_output_operand (&ops[0], NULL_RTX, mode); - create_fixed_operand (&ops[1], temp); - expand_insn (icode, 2, ops); - return ops[0].value; + /* We've already validated the memory, and we're creating a + new pseudo destination. The predicates really can't fail, + nor can the generator. */ + create_output_operand (&ops[0], NULL_RTX, mode); + create_fixed_operand (&ops[1], temp); + expand_insn (icode, 2, ops); + return ops[0].value; + } + else if (SLOW_UNALIGNED_ACCESS (mode, align)) + temp = extract_bit_field (temp, GET_MODE_BITSIZE (mode), + 0, TYPE_UNSIGNED (TREE_TYPE (exp)), + true, (modifier == EXPAND_STACK_PARM + ? NULL_RTX : target), + mode, mode); } return temp; } Index: src/gcc/testsuite/gcc.dg/misaligned-expand-1.c =================================================================== --- /dev/null +++ src/gcc/testsuite/gcc.dg/misaligned-expand-1.c @@ -0,0 +1,41 @@ +/* Test that expand can generate correct loads of misaligned data even on + strict alignment platforms. */ + +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +extern void abort (); + +typedef unsigned int myint __attribute__((aligned(1))); + +unsigned int +foo (myint *p) +{ + return *p; +} + +#define cst 0xdeadbeef +#define NUM 8 + +struct blah +{ + char c; + myint i[NUM]; +}; + +struct blah g; + +int +main (int argc, char **argv) +{ + int i, k; + for (k = 0; k < NUM; k++) + { + g.i[k] = cst; + i = foo (&g.i[k]); + + if (i != cst) + abort (); + } + return 0; +} Index: src/gcc/testsuite/gcc.dg/misaligned-expand-3.c =================================================================== --- /dev/null +++ src/gcc/testsuite/gcc.dg/misaligned-expand-3.c @@ -0,0 +1,43 @@ +/* Test that expand can generate correct stores to misaligned data of complex + type even on strict alignment platforms. */ + +/* { dg-do run } */ +/* { dg-options "-O0" } */ + +extern void abort (); + +typedef _Complex float mycmplx __attribute__((aligned(1))); + +void +foo (mycmplx *p, float r, float i) +{ + __real__ *p = r; + __imag__ *p = i; +} + +#define cvr 3.2f +#define cvi 2.5f +#define NUM 8 + +struct blah +{ + char c; + mycmplx x[NUM]; +} __attribute__((packed)); + +struct blah g; + +int +main (int argc, char **argv) +{ + int k; + + for (k = 0; k < NUM; k++) + { + foo (&g.x[k], cvr, cvi); + if (__real__ g.x[k] != cvr + || __imag__ g.x[k] != cvi) + abort (); + } + return 0; +}