[Bug c/56620] New: Memcpy optimization may lead to unaligned access on ARM Thumb
eleventen at gmail dot com
gcc-bugzilla@gcc.gnu.org
Thu Mar 14 18:12:00 GMT 2013
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56620
Bug #: 56620
Summary: Memcpy optimization may lead to unaligned access on
ARM Thumb
Classification: Unclassified
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
AssignedTo: unassigned@gcc.gnu.org
ReportedBy: eleventen@gmail.com
Created attachment 29668
--> http://gcc.gnu.org/bugzilla/attachment.cgi?id=29668
Sample source file
Whereas #53016 resolved to an alignment problem with the underlying structures,
this is a case where the builtin memcpy optimization emits instructions that
may access words on a non-word boundary.
The target is an ARM Cortex-M4. The compiler was generated by the summon-gcc
project in order to gain access to the hard-float feature of GCC 4.7.2. The
problem didn't appear until I implemented faults on unaligned access per the
ARM recommendations.
The example was compiled with both -O2 and -Os. In both instances the compiler
emitted unaligned ldr instructions. Below is pasted the disassembled code at
fault.
// Here we load the base address of the data array of bytes.
a: 4e0c ldr r6, [pc, #48] ; (3c <copy_unaligned+0x3c>)
c: f44f 74ff mov.w r4, #510 ; 0x1fe
10: 19a3 adds r3, r4, r6
// r3 has 510 - 16*i, an word unaligned offset assuming the data array aligned.
12: 466d mov r5, sp
14: f103 0710 add.w r7, r3, #16
// This next instruction faults.
18: 6818 ldr r0, [r3, #0]
1a: 6859 ldr r1, [r3, #4]
1c: 462a mov r2, r5
1e: c203 stmia r2!, {r0, r1}
20: 3308 adds r3, #8
22: 42bb cmp r3, r7
24: 4615 mov r5, r2
26: d1f7 bne.n 18 <copy_unaligned+0x18>
3c: 00000000 .word 0x00000000
I recall that a few versions back, GCC started putting stack allocated arrays
of bytes on odd or non-word address boundaries. If this is the case, I don't
see how memcpy could every legally emit the code above, even if it knew that
the array offset was word aligned.
While producing the sample, I noticed that it was necessary to have both the
unaligned offset like 510 and the indexed offset i*16 to trigger the errant
code.
Cheers
More information about the Gcc-bugs
mailing list