[LLVMdev] Possible bug in the ARM backend?

Dale Johannesen dalej at apple.com
Fri Jan 9 12:04:07 PST 2009


On Jan 9, 2009, at 11:54 AMPST, Dale Johannesen wrote:
> 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...

OK, it's got special MFLR/MTLR instructions to do the save/restore of  
LR (actually
they go through a GR first) which are marked as use/def of LR.  You  
could simulate
something like that on ARM I guess.

>> 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
>




More information about the llvm-dev mailing list