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. I tried the same code with the MIPS target and it also fails in the same manner - a ISD::CALL node remains in the DAG after legalization and the instruction selection fails. Richard
Hi,> 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. > > I tried the same code with the MIPS target and it also fails in the same > manner - a ISD::CALL node remains in the DAG after legalization and the > instruction selection fails.you may want to try the new LegalizeTypes infrastructure once it is finished (hopefully in a week or two). Ciao, Duncan.
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? 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. Evan> > > I tried the same code with the MIPS target and it also fails in the > same > manner - a ISD::CALL node remains in the DAG after legalization and > the > instruction selection fails. > > Richard > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
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. 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-------------- next part -------------- A non-text attachment was scrubbed... Name: expandlibcall.diff Type: text/x-patch Size: 447 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20080701/2674b6db/attachment.bin>