[LLVMdev] Problems expanding fcmp to a libcall

Evan Cheng evan.cheng at apple.com
Wed Jul 2 10:53:13 PDT 2008


On Jul 1, 2008, at 3:42 PM, Richard Osborne wrote:

> Evan Cheng wrote:
>> On Jun 25, 2008, at 5:13 AM, Richard Osborne wrote:
>>
>>
>>> Evan Cheng wrote:
>>>
>>>> On Jun 23, 2008, at 5:35 AM, Richard Osborne wrote:
>>>>
>>>>
>>>>> I'm trying to write a backend for a target with no hardware  
>>>>> floating
>>>>> point support. I've added a single i32 register class. I'm  
>>>>> wanting  all
>>>>> floating point operations to be lowered to library function  
>>>>> calls.  For
>>>>> the most part LLVM seems to get this right. For example
>>>>>
>>>>> define double @div(double %a, double %b) {
>>>>> %result = fdiv double %a, %b
>>>>> ret double %result
>>>>> }
>>>>>
>>>>> is expanded to a ISD::CALL of __divdf3 which is then lowered via  
>>>>> the
>>>>> LowerOperation hook of my backend.
>>>>>
>>>>> However I run into problems with fcmp. With the following code:
>>>>>
>>>>> define i1 @fmp(double %a) {
>>>>> %result = fcmp uno double %a, 0.000000e+00
>>>>> ret i1 %result
>>>>> }
>>>>>
>>>>> the fcmp is expanded to the a call to __unorddf2 which is then
>>>>> lowered via the LowerOperation hook of my backend. However for  
>>>>> some
>>>>> reason
>>>>> there remains a ISD::CALL node with __unorddf2 in the DAG after
>>>>> legalization. This
>>>>> then causes selection to fail with
>>>>>
>>>>> Cannot yet select: 0x13b7cc0: i32,i32,ch = call 0x13b76e0,   
>>>>> 0x13b7800,
>>>>> 0x13b7800, 0x13b7800, 0x13b77a0, 0x13b78f0, 0x13b79a0, 0x13b80d0,
>>>>> 0x13b7a00, 0x13b78f0, 0x13b79a0, 0x13b80d0, 0x13b7a00
>>>>>
>>>>> Are there any additional steps I need to take in my target, or  
>>>>> could
>>>>> this be a bug in the Legalization phase?
>>>>>
>>>>>
>>>> This sounds like a bug in your target. Why not custom lower the f32
>>>> setcc nodes directly to the desired target nodes rather than doing
>>>> this  two stage lowering?
>>>>
>>>> Evan
>>>>
>>>>
>>> At the moment I'm not doing any custom lowering in my target - the
>>> lowering I was describing was what I observed the SectionDAG was   
>>> doing.
>>> I was under the impression that LLVM's soft float support meant  
>>> that  if
>>> I didn't call addRegisterClass() with any FP types then floating  
>>> point
>>> operations would be expanded into libcalls and it would all just
>>> work(tm). And for the most part it does work - addition, division,  
>>> etc
>>> on floating point types are all lower correctly by the SelectionDAG
>>> without any further intervention.
>>>
>>> However it fails fcmp. I was wanting to understand if this was   
>>> expected
>>> and if so what I should do about it. It sounds like I need to custom
>>> lower the nodes directly. I would certainly be nice if this wasn't
>>> necessary.
>>>
>>
>> Ok, I am not sure I understand your original question then.  
>> Legalizer  is converting the setcc node into a call to __unorddf2.  
>> Is that what  you want?
> Yes, this is exactly what I want
>> But you also stated:
>>
>>
>>>>> he fcmp is expanded to the a call to __unorddf2 which is then
>>>>> lowered via the LowerOperation hook of my backend.
>>>>>
>>
>> Does that mean you are then lowering the call to some other   
>> operations?  That means your lowering code is somehow not removing  
>> the  call code. Perhaps you are not updating all the uses.  
>> Nevertheless  this is not the right approach, you should instead  
>> custom lower the  setcc node directly to the target specific node.
>>
> When the LowerOperation method is called with a call node I create a  
> new
> chain of operations and the return the a new operand. However, as  
> you say,
> printing the DAG shows that not all the uses are replaced.

Are you examining the DAG before you lower the ISD::CALL node?

>
>
> I tracked this down to SelectionDAGLegalize::ExpandLibCall().
> Here the TargetLowering's LowerCallTo is called to create the call  
> node,
> which returns a pair of operands for the chain and the result. The  
> chain
> is legalized but the result isn't. Modifying the code to call  
> LegalizeOp on
> the result seems to fix the problem I was having: the code
> compiles and I see a call to __unorddf2 in the assembly.
>
> I'm not entirely sure if this fix is correct but it seems to work so  
> far for
> my target. See the attached diff.
>
>> Evan
> --- /home/richard/local/src/llvm-2.3/lib/CodeGen/SelectionDAG/ 
> LegalizeDAG.cpp   2008-05-12 20:46:27.000000000 +0100
> +++ /home/richard/local/llvm/tools_llvm/src/lib/CodeGen/SelectionDAG/ 
> LegalizeDAG.cpp    2008-07-01 23:33:21.000000000 +0100
> @@ -5287,9 +5287,11 @@
>     break;
>   case Expand:
>     ExpandOp(CallInfo.first, Result, Hi);
> +    if (Hi.Val)
> +      Hi = LegalizeOp(Hi);
>     break;
>   }
> -  return Result;
> +  return LegalizeOp(Result);
> }

This seems to break the convention. It should be the responsibility of  
the caller to further legalize the results.

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