------- Comment #7 from jakub at gcc dot gnu dot org 2009-02-09 20:17 ------- This is different from that PR. In this case the code does nothing dangerous in the block with the register vars. For %rdi and a couple of other regs on x86-64 one could actually use "D" etc. constraints, but r8-r15 already don't have a single register class for each register, and on most of the other targets this isn't available either. So just to show that this isn't x86-64 only issue, here is a testcase for sparc64-linux: static inline int foo (unsigned int x, void *y) { register unsigned long r asm ("o0"); register unsigned long a1 asm ("g1") = a1; register unsigned long a2 asm ("g5") = a2; a1 = (unsigned long) x; a2 = (unsigned long) y; asm volatile ("# %0 %1 %2" : "=r" (r), "+r" (a1), "+r" (a2) : : "memory"); return (int) r; }
struct T { unsigned long t1, t2; unsigned int t3, t4, t5; }; int bar (unsigned long x, unsigned int y, unsigned long u, unsigned int v) { long r; struct T e = { .t1 = x, .t2 = u }; if (x << y != u << v) return 5; r = foo (11, &e); return e.t3 == x; } compile with -Os -m64 and -Os -m64 -fno-tree-sink. See in the latter: add %fp, 2015, %l0 mov 0, %o1 mov %l0, %o0 call memset, 0 mov 32, %o2 ... mov %l0, %g5 mov 11, %g1 #APP ! 9 "pr39139.c" 1 # %o0 %g1 %g5 #NO_APP I.e. it would work just fine, both are initialized to the expected value. With sinking we have: save %sp, -208, %sp sllx %i0, %i1, %i1 sllx %i2, %i3, %i3 cmp %i1, %i3 bne,pt %xcc, .LL3 mov 5, %g1 add %fp, 2015, %o0 mov 0, %o1 call memset, 0 mov 32, %o2 stx %i2, [%fp+2023] stx %i0, [%fp+2015] #APP ! 9 "mm.c" 1 # %o0 %g1 %g5 #NO_APP where neither g1 nor g5 are initialized at all (they were initialized during expand, but before the memset call, and as both g1 and g5 are call clobbered their value would (or could) be corrupted during the call anyway). I'd say easiest fix would be for tree-ssa-sink.c to punt sinking = {} if there are any DECL_HARD_REGISTER vars in the function. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39139