Hi, when compiling asm inline at -O0, we can hit easily the "Ran out of registers" case. $ cat /tmp/toto.c #include <stdint.h> void ff_h264_idct_dc_add_mmx2(uint8_t *dst, int16_t *block, int stride) { __asm__ volatile( "movd %0, %%mm2 \n\t" "movd %1, %%mm3 \n\t" "movd %2, %%mm4 \n\t" "movd %3, %%mm5 \n\t" "movd %%mm2, %0 \n\t" "movd %%mm3, %1 \n\t" "movd %%mm4, %2 \n\t" "movd %%mm5, %3 \n\t" :"+m"(*(uint32_t*)(dst+0*stride)), "+m"(*(uint32_t*)(dst+1*stride)), "+m"(*(uint32_t*)(dst+2*stride)), "+m"(*(uint32_t*)(dst+3*stride)) ); } $ ccc -c -o /tmp/toto.o /tmp/toto.c Ran out of registers during register allocation! Please check your inline asm statement for invalid constraints: INLINEASM <es:movd $0, %mm2 movd $1, %mm3 movd $2, %mm4 movd $3, %mm5 movd %mm2, $0 movd %mm3, $1 movd %mm4, $2 movd %mm5, $3 >, 36, %EDI<kill>, 1, %reg0, 0, 36, %EBX<kill>, 1, %reg0, 0, 36, %EAX<kill>, 1, %reg0, 0, 36, %EDX<kill>, 1, %reg0, 0, 36, %ECX<kill>, 1, %reg0, 0, 36, %ESI<kill>, 1, %reg0, 0, 36, %EDI<kill>, 1, %reg0, 0, 36, %reg1070<kill>, 1, %reg0, 0, 14, %EFLAGS<earlyclobber,def,dead>
This is actually a really bad clang bug where it is expanding + constraints twice!
Specifically, I see: %tmp27 = load i8** %dst.addr ; <i8*> [#uses=1] %tmp28 = load i32* %stride.addr ; <i32> [#uses=1] %mul29 = mul i32 3, %tmp28 ; <i32> [#uses=1] %add.ptr30 = getelementptr i8* %tmp27, i32 %mul29 ; <i8*> [#uses=1] %conv31 = bitcast i8* %add.ptr30 to i32* ; <i32*> [#uses=1] %tmp32 = load i8** %dst.addr ; <i8*> [#uses=1] %tmp33 = load i32* %stride.addr ; <i32> [#uses=1] %mul34 = mul i32 3, %tmp33 ; <i32> [#uses=1] %add.ptr35 = getelementptr i8* %tmp32, i32 %mul34 Which means that if this had side effects, that it would be evaluated twice. We also have the other issue with +m constraints where they are passed as two operands, this is badness as well.
I heard Anders loves inline asm. :)
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20090727/019917.html
The fix for this lead to PR4677 so I backed it out.
Fixed in r108489.