When compiling the following code with -O2: #include <stdio.h> static unsigned long long __attribute__((noinline)) f(void *ptr, unsigned long long ull) { register unsigned long __r2 __asm__ ("r2") = (unsigned long) (&ull); __asm__ __volatile__ ("" : "+r" (__r2)); return * (unsigned long long *) __r2; } int main(void) { fprintf(stderr, "f(NULL, 0): %Lu\n", f(NULL, 0)); return 0; } we get the following warning: /tmp/ccJNzMaH.s: Assembler messages: /tmp/ccJNzMaH.s:21: Warning: source register same as write-back base And when running the program on target, the printed return value of f is not 0. A disassembly of f: 000083f4 <f>: 83f4: e24dd008 sub sp, sp, #8 ; 0x8 83f8: e28d2008 add r2, sp, #8 ; 0x8 83fc: e16220f8 strd r2, [r2, #-8]! 8400: e8920003 ldm r2, {r0, r1} 8404: e28dd008 add sp, sp, #8 ; 0x8 8408: e12fff1e bx lr shows that r2 seems to be clobbered before its value is saved on stack.
The following, even simpler test case: unsigned long long f(unsigned long long ull) { register unsigned long long *__r0 __asm__ ("r0") = &ull; __asm__ __volatile__ ("" : "+r" (__r0)); return * __r0; } gives the same warning, and the following assembly code: 00000000 <f>: 0: e24dd008 sub sp, sp, #8 ; 0x8 4: e28d0008 add r0, sp, #8 ; 0x8 8: e16000f8 strd r0, [r0, #-8]! c: e8900003 ldm r0, {r0, r1} 10: e28dd008 add sp, sp, #8 ; 0x8 14: e12fff1e bx lr
Confirmed. We need a way to represent an early-clobber between a register and a memory-address with side-effects.
This appears to have been fixed by r161920 2010-07-07 Bernd Schmidt <bernds@codesourcery.com> PR rtl-optimization/44404 * auto-inc-dec.c (find_inc): Avoid calling count_occurrences if possible, use reg_overlap_mentioned_p instead. *** This bug has been marked as a duplicate of bug 44404 ***