LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 3800 - asm inline : Ran out of registers at -O0
Summary: asm inline : Ran out of registers at -O0
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: LLVM Codegen (show other bugs)
Version: unspecified
Hardware: PC Linux
: P normal
Assignee: Unassigned LLVM Bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-03-13 13:40 PDT by Matthieu castet
Modified: 2010-07-15 19:55 PDT (History)
7 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Matthieu castet 2009-03-13 13:40:34 PDT
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>
Comment 1 Chris Lattner 2009-03-23 13:54:15 PDT
This is actually a really bad clang bug where it is expanding + constraints twice!
Comment 2 Chris Lattner 2009-03-23 13:55:03 PDT
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.
Comment 3 Daniel Dunbar 2009-08-01 14:09:51 PDT
I heard Anders loves inline asm. :)
Comment 5 Anders Carlsson 2009-08-04 13:19:14 PDT
The fix for this lead to PR4677 so I backed it out.
Comment 6 Eli Friedman 2010-07-15 19:55:42 PDT
Fixed in r108489.