This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/64516] New: arm: wrong unaligned load generated
- From: "markus at oberhumer dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 07 Jan 2015 02:07:49 +0000
- Subject: [Bug target/64516] New: arm: wrong unaligned load generated
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64516
Bug ID: 64516
Summary: arm: wrong unaligned load generated
Product: gcc
Version: 4.9.2
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: markus at oberhumer dot com
Created attachment 34391
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=34391&action=edit
unaligned_load_bug.c to reproduce the problem.
arm: bad code generated => run time crash
- gcc 4.9.2 seems to forget the attribute(packed) in some cases.
- please see the disassembly for get16_unaligned().
- put16_unaligned() is correct !
- FWIW, gcc 4.3.5 and clang 3.5 work
~Markus
$ cat unaligned_load_bug.c
typedef struct { char a[2]; } __attribute__((__packed__)) TU2;
// OK: correct (but poor) code generated for the store
void put16_unaligned(void *p, unsigned short v) {
if (sizeof(TU2) == sizeof(v) && __alignof__(TU2) == 1) {
*(TU2 *)p = *(const TU2 *)(const void *)(&v);
}
}
// BUG: incorrect transformation into an aligned load => run time crash !!
unsigned short get16_unaligned(const void *p) {
unsigned short v;
if (sizeof(TU2) == sizeof(v) && __alignof__(TU2) == 1) {
*(TU2 *)(void *)(&v) = *(const TU2 *)p;
}
return v;
}
// aligned versions - just for comparison
void put16_aligned(void *p, unsigned short v) {
*(unsigned short *)p = *(&v);
}
unsigned short get16_aligned(const void *p) {
unsigned short v;
*(&v) = *(const unsigned short *)p;
return v;
}
// EOF
$ arm-linux-gnueabi-gcc-4.9 -v
gcc version 4.9.2 (Ubuntu/Linaro 4.9.2-7ubuntu3)
$ arm-linux-gnueabi-gcc-4.9 -march=armv4 -marm -O2 -Wall -W -Wcast-align -c
unaligned_load_bug.c
$ arm-linux-gnueabi-objdump -d unaligned_load_bug.o
unaligned_load_bug.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <put16_unaligned>:
0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
4: e24dd00c sub sp, sp, #12
8: e28d3008 add r3, sp, #8
c: e16310b2 strh r1, [r3, #-2]!
10: e3a02002 mov r2, #2
14: e1a01003 mov r1, r3
18: ebfffffe bl 0 <memcpy>
1c: e28dd00c add sp, sp, #12
20: e49de004 pop {lr} ; (ldr lr, [sp], #4)
24: e12fff1e bx lr
00000028 <get16_unaligned>:
28: e1d000b0 ldrh r0, [r0]
2c: e12fff1e bx lr
00000030 <put16_aligned>:
30: e1c010b0 strh r1, [r0]
34: e12fff1e bx lr
00000038 <get16_aligned>:
38: e1d000b0 ldrh r0, [r0]
3c: e12fff1e bx lr