[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