[LLVMdev] Possible bug in the ARM backend?

Dale Johannesen
Fri, 09 Jan 2009 19:54:05 -0000

On Jan 9, 2009, at 11:37 AMPST, Evan Cheng wrote:

> This looks like a bar in ARMInstrInfo.td:
>
> BX_RET should be marked with Uses = [LR] since it uses LR. However,
> this won't work if there is a call BL before the BX_RET. BL is marked
> as if it implicitly define LR. So we'll end up with this (hello world
> example):

PPC has the call (BL) marked with Defs=LR and the return (BLR)
marked with Uses=LR, and works AFAIK.  Let me figure out what's
different...

> Live Ins: %LR %R7
>         %SP<def> = SUBri %SP<kill>, 8, 14, %reg0, %reg0
>         STR %LR<kill>, %SP, %reg0, 4, 14, %reg0
>         STR %R7<kill>, %SP, %reg0, 0, 14, %reg0
>         %R7<def> = MOVr %SP, 14, %reg0, %reg0
>         %R0<def> = LDR <cp#0>, %reg0, 0, 14, %reg0, Mem:LD(4,4)
> [<unknown> + 0]
>         BL <ga:puts>, %R0<kill>, %R0<imp-def,dead>,
%R1<imp-
> def,dead>, %R2<imp-def,dead>, %R3<imp-def,dead>,
%R12<imp-def,dead>,
> %LR<imp-def>, %D0<imp-def,dead>, %D1<imp-def,de\
> ad>, %D2<imp-def,dead>, %D3<imp-def,dead>,
%D4<imp-def,dead>, %D5<imp-
> def,dead>, %D6<imp-def,dead>, %D7<imp-def,dead>,
%CPSR<imp-def,dead>
>         %R0<def> = MOVi 0, 14, %reg0, %reg0
>         %R7<def> = LDR %SP, %reg0, 0, 14, %reg0
>         %LR<def> = LDR %SP, %reg0, 4, 14, %reg0
> 	%SP<def> = ADDri %SP<kill>, 8, 14, %reg0, %reg0
>         BX_RET 14, %reg0, %R0<imp-use,kill>, %LR<imp-use,kill>
>
> The LR defined by BL is not killed before the PEI inserted LR restore.
> The register scavenger doesn't like this.
>
> The issue is while BL does modifies LR, it doesn't actually defines LR
> so later instructions can use it. I'll think about how to fix this.
> It's not obvious to me at this point.
>
> Evan
>
> On Jan 7, 2009, at 2:24 PM, Roman Levenstein wrote:
>
>> Hi Evan,
>>
>> Thanks for your feedback!
>>
>> 2009/1/7 Evan Cheng <evan.cheng at apple.com>:
>>>
>>> On Jan 7, 2009, at 2:48 AM, Roman Levenstein wrote:
>>>
>>>
>>> As you can see, PrologEpilogInserter has inserted at the beginning
>>> of the function some code for manipulation of the frame pointer and
>>> this inserted code uses the LR register.
>>> As far as I understand,  ARMRegisterInfo.td should exclude the LR
>>> register from the set of allocatable registers for functions that
>>> require frame pointer manipulation.
>>> But currently it is not the case, or?
>>>
>>> No, LR is not the frame pointer. It's the link register (caller
>>> address). It
>>> should be available as a general purpose register.
>>
>> OK.
>>
>>> The bug is elsewhere. It  has to do with kill / dead markers.
>>>      %LR<def> = LDR <fi#0>, %reg0, 0, 14, %reg0
>>>      %SP<def> = ADDri %SP<kill>, 4, 14, %reg0, %reg0
>>>      BX_RET 14, %reg0
>>> LR is restored here but it's not killed before the end of the
block
>>> is
>>> reached.
>>
>> Hmm. I have no idea about what ARM backend does. My register
>> allocator
>> just assigns the registers as I explained in my original mail.
>> Then it lets VirtRegMap.cpp do its job, i.e. it lets it rewrite the
>> code and replace virtual registers by the assigned physical
>> registers.
>> You can see the result in the step (3) of my original mail. In my
>> opinion, it still looks correct. May be this rewriting process does
>> something wrong?
>>
>> Then PrologEpilogInserter and some other standard post RA passes are
>> invoked for the ARM backend. But I have not changed anything there,
>> so
>> I have no idea what happens.
>>
>> And, BTW, the instructions you mentioned above are after the
>> instruction triggering the assertion, which is:
>> STR %LR<kill>, %R0<kill>, %reg0, 0, 14, %reg0, Mem:ST(4,4)
>> [0x8fc2d68 + 0]
>>
>>> Should BX_RET use it?
>>
>> I don't know the semantics of BX_RET on the ARM platform. May be it
>> uses BX_RET somehow.
>>
>> BTW, an idea: May be it is easy to trigger exactly the same behaviour
>> with the linear scan if one does the following:
>> - comment out dependency on the coalescer, so that it is not invoked
>> - change the allocation order of the GPR register class for ARM, so
>> that it starts with the LR register.
>> ,
>> Any ideas how to proceed with the current situation?
>>
>> -Roman
>>
>>> I hope that I provided enough information to explain my problem. I
>>> also provided my initial analysis, but may be I'm wrong.
>>>
>>> Can someone more knowledgeable in ARM backend and LLVM's
register
>>> allocation framework have a look at it?
>>> If it is a bug in the ARM backend, could it be fixed?
>>>
>>> Thanks,
>>> Roman
>>> <bugpoint-reduced-simplified.bc>
>>>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev