union unaligned { void *ptr; } __attribute__((__packed__)); void *foo(union unaligned *p) { return (p->ptr); } -------------------- sh-elf-gcc -V4.1.1 -S -O2 -m4a test2.c combine optimize change movua.l to mov.l instruction. .file "test2.c" .text .text .align 1 .align 5 .global _foo .type _foo, @function _foo: mov.l @r4,r0 mov.l r14,@-r15 mov r15,r14 mov r14,r15 mov.l @r15+,r14 rts nop .size _foo, .-_foo .ident "GCC: (GNU) 4.1.1"
I've confirmed that 4.0 and 4.2 behave same as 4.1. So all compilers which support -m4a option have this issue. It seems that the combine is too smart and replaces the movua insn (define_insn "movua" [(set (match_operand:SI 0 "register_operand" "=z") (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>") (const_int 32) (const_int 0)))] "TARGET_SH4A_ARCH" "movua.l %1,%0" [(set_attr "type" "movua")]) with the usual load insn. I'm testing the patch below. --- ORIG/trunk/gcc/config/sh/sh.md 2006-06-14 06:15:09.000000000 +0900 +++ LOCAL/trunk/gcc/config/sh/sh.md 2006-07-03 16:43:56.000000000 +0900 @@ -152,6 +152,7 @@ (UNSPEC_THUNK 36) (UNSPEC_SP_SET 40) (UNSPEC_SP_TEST 41) + (UNSPEC_MOVUA 42) ;; These are used with unspec_volatile. (UNSPECV_BLOCKAGE 0) @@ -11121,8 +11122,8 @@ mov.l\\t1f,r0\\n\\ (define_insn "movua" [(set (match_operand:SI 0 "register_operand" "=z") - (sign_extract:SI (match_operand:SI 1 "unaligned_load_operand" "Sua>") - (const_int 32) (const_int 0)))] + (unspec:SI [(match_operand:SI 1 "unaligned_load_operand" "Sua>")] + UNSPEC_MOVUA))] "TARGET_SH4A_ARCH" "movua.l %1,%0" [(set_attr "type" "movua")])
Subject: Bug number PR target/28232 A patch for this bug has been added to the patch tracker. The mailing list url for the patch is http://gcc.gnu.org/ml/gcc-patches/2006-07/msg00266.html
Richard Sandiford gave a more thorough patch in http://gcc.gnu.org/ml/gcc-patches/2006-07/msg00335.html and it's approved for the next stage1 of mainline.
Subject: Bug 28232 Author: kkojima Date: Mon Oct 23 00:14:39 2006 New Revision: 117961 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=117961 Log: PR target/28232 * config/sh/sh.c (expand_block_move): Use a BLKmode rather than SImode memory reference for the source of a movua. * config/sh/sh.md (UNSPEC_MOVUA): New macro. (movua): Use an unspec instead of sign_extract. Expect the source to have mode BLKmode. (extv, insv): Use a BLKmode rather than SImode memory reference for the source of a movua. Modified: trunk/gcc/ChangeLog trunk/gcc/config/sh/sh.c trunk/gcc/config/sh/sh.md
Fixed.