http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48863

--- Comment #4 from Mikael Pettersson <mikpe at it dot uu.se> 2011-06-19 
16:26:25 UTC ---
Created attachment 24562
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24562
runtime test case

Here's a small runtime test case.

> cat pr48863.c
/* pr48863.c */

static inline int dosvc(int fd, unsigned long high, unsigned low)
{
    register int r0 asm("r0") = fd;
    register int r2 asm("r2") = high;
    register int r3 asm("r3") = low;

    asm volatile(""
                 : "=r"(r0)
                 : "0"(r0), "r"(r2), "r"(r3));
    return r0;
}

struct s {
    int fd;
    long long length;
} s = { 2, 0 }, *p = &s;

int main(void)
{
    unsigned low = p->length & 0xffffffff;
    unsigned high = p->length / 23;

    if (dosvc(p->fd, high, low) != 2)
        __builtin_abort();
    return 0;
}
> /mnt/scratch/objdir47/gcc/xgcc -B/mnt/scratch/objdir47/gcc/ -O2 pr48863.c ; 
> ./a.out
Abort
> /mnt/scratch/objdir47/gcc/xgcc -B/mnt/scratch/objdir47/gcc/ -O2 -S pr48863.c 
> ; cat pr48863.s
...
main:
        @ args = 0, pretend = 0, frame = 0
        @ frame_needed = 0, uses_anonymous_args = 0
# loads &p to r1
        ldr     r1, .L5
        stmfd   sp!, {r4, lr}
# loads *&p to r1
        ldr     r1, [r1, #0]
        mov     r2, #23
        mov     r3, #0
        ldr     r4, [r1, #8]
        ldr     r1, [r1, #12]
        mov     r0, r4
        bl      __aeabi_ldivmod
        mov     r3, r4
        mov     r2, r0

# here's where the SWI would have been, note how:
# 1. p->fd was never loaded into r0
# 2. r0 was clobbered by the libcall to __aeabi_ldivmod

        cmp     r0, #2

# so this comparison will fail and we'll abort
...

Works when compiled with -O0.

Reply via email to