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? Regards, Richard Osborne
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> > > Regards, > > Richard Osborne > _______________________________________________ > 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 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