https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86555
Bug ID: 86555
Summary: unaligned address for ldrd/strd on armv5e
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: raj.khem at gmail dot com
Target Milestone: ---
Following example generates LDRD instructions which are loading for a 4byte
aligned address instead of 8-byte aligned address. This does not work on
armv5te systems and results in alignment traps
ldrd.c
======
/* taken from musl readdir.c
* issue not present with gcc 6.x and 7.2 (OE/Yocto toolchain)
* with gcc 7.3 and gcc 8.1 -march=armv5te -O2 -ffreestanding
* with volatile int lock[2] no issues ldrd r4, [r0, #40]
* with volatile int lock[1] we get ldrd r4, [r0, #36]
* but adress must be 8 bytes aligned
*/
typedef long long off_t;
typedef off_t ino_t;
typedef unsigned int size_t;
struct DIR
{
int fd;
off_t tell;
int buf_pos;
int buf_end;
volatile int lock[1]; /* was 2, with 1 we get ldrd unalignment */
char buf[2048];
};
struct dirent {
ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
};
struct dirent *readdir(struct DIR *dir)
{
struct dirent *de;
dir->buf_pos = 0;
de = (void *)(dir->buf + dir->buf_pos);
dir->tell = de->d_off;
};
==================
compiled with -O2 -S -march=armv5te
=======================
generated code
readdir:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
push {r4, r5}
ldrd r4, [r0, #36] <============== this is the problem !!
mov r3, r0
mov r2, #0
strd r4, [r3, #8]
str r2, [r3, #16]
pop {r4, r5}
bx lr
This issue did not happen when musl used lock[2] but it has been changed
recently
for efficiency.