vivek pandya via llvm-dev
2017-Mar-09 16:59 UTC
[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
On Thu, Mar 9, 2017 at 9:35 PM, Hal Finkel <hfinkel at anl.gov> wrote:> > On 02/25/2017 03:06 AM, vivek pandya via llvm-dev wrote: > > Note: Question is written after describing what I have coded. > > Hello LLVMDevs, > > I am trying to impliment floating point comparsion for an architecture > which > supports following type of floating point comparision if FPU is available: > fcmp.un --> true if one of the operand is NaN > fcmp.lt --> ordered less than, if any input NaN then return false > fcmp.eq --> ordered equal, if any input NaN then return false > fcmp.le --> ordered less equal, if any input NaN then return false > fcmp.gt --> ordered grater than, if any input NaN then return false > fcmp.ne --> ordered not equal, if any input NaN then return true > fcmp.ge --> ordered grater equal, if any input NaN then return false > > When FPU is not present I need to generate a library call, > > so I have added following code in LowerBR_CC function in > XXXISelLowering.cpp > > const XXXSubtarget &STI = static_cast<const XXXSubtarget&> > (DAG.getSubtarget()); > XXXCC::CondCodes TCC; > getFPCCtoXXCC(CC,TCC); > TargetCC = DAG.getConstant(TCC, dl, MVT::i8); > if (STI.useHardFloat()) { > // if fcmp instruction is available use it > SDValue Flag = DAG.getNode(XXXISD::FCMP, dl, MVT::Glue, LHS, RHS, > TargetCC); > return DAG.getNode(XXXISD::BR_CC, dl, Op.getValueType(), > Chain, Dest, TargetCC, Flag); > } > else { > // else generate library call > DAG.getTargetLoweringInfo().softenSetCCOperands(DAG, MVT::f32, LHS, > RHS, > CC, dl); > > SDValue Flag = DAG.getNode(XXXISD::CMP, dl, MVT::Glue, LHS, RHS); > > if (!RHS.getNode()) { > RHS = DAG.getConstant(0, dl, LHS.getValueType()); > TargetCC = DAG.getConstant(XXXCC::COND_NE, dl, MVT::i8); > } > return DAG.getNode(XXXISD::BR_CC, dl, MVT::Other, > Chain, Dest, TargetCC, Flag); > } > > and code for getFPCCtoXXCC() is as following: > > static void getFPCCtoXXCC(ISD::CondCode CC, XXXCC::CondCodes &CondCode) { > switch (CC) { > default: > llvm_unreachable("Unknown FP condition!"); > case ISD::SETEQ: > case ISD::SETOEQ: > CondCode = XXXCC::COND_E; > break; > case ISD::SETGT: > case ISD::SETOGT: > CondCode = XXXCC::COND_GT; > break; > case ISD::SETGE: > case ISD::SETOGE: > CondCode = XXXCC::COND_GE; > break; > case ISD::SETOLT: > case ISD::SETLT: > CondCode = XXXCC::COND_LT; > break; > case ISD::SETOLE: > case ISD::SETLE: > CondCode = XXXCC::COND_LE; > break; > case ISD::SETONE: > case ISD::SETNE: > CondCode = XXXCC::COND_NE; > break; > case ISD::SETUO: > CondCode = XXXCC::COND_UN; > break; > case ISD::SETO: > case ISD::SETUEQ: > case ISD::SETUGT: > case ISD::SETUGE: > case ISD::SETULT: > case ISD::SETULE: > case ISD::SETUNE: > CC = getSetCCInverse(CC,false); > getFPCCtoMBCC(CC,CondCode); > break; > } > } > > I am generating wrong code when using floating point library call for > comparions. For the following simple case: > float branchTest(float a, float b) { > float retVal; > if (a == b) { > retVal = a / b + 22.34; > } > return retVal; > } > I am getting: > brlid r15,__nesf2 > nop > beqi r3,.LBB0_2 ; r3 is return regsiter > > Now I want to understand difference between three different version of > Condition > Codes for same operation and how according to my target I should handle > them. > For example let's consider SETNE, SETONE and SETUNE so for my architecture > I think for floating point all three are same > > > No, they're not the same. Please see: > > http://llvm.org/docs/LangRef.html#id290 > > which explains the difference between SETONE (one) and SETUNE (une). > Regarding how SETNE is interpreted for FP, see the comment in the > definition of CondCode in include/llvm/CodeGen/ISDOpcodes.h which > explains, "// Don't care operations: undefined if the input is a nan.". > > To support the unordered comparisons, if your FPU has only ordered > comparisons, then you might need to do the underlying comparison, and a NaN > check, and then OR the results. I think that using setCondCodeAction will > cause the expansions for the hardware-unsupported variants to happen for > you. > > -Hal >Thanks Hal for the guidance ! -Vivek> > so do I need to use > getSetCCInverse() ? Also when I look at the code of > TargetLowering::softenSetCCOperands I see that for some condition code it > uses > getSetCCInverse() and also I am not able to understand the way it groups > condition code in switch case for example : > case ISD::SETEQ: > case ISD::SETOEQ: > LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : > (VT == MVT::f64) ? RTLIB::OEQ_F64 : RTLIB::OEQ_F128; > break; > case ISD::SETNE: > case ISD::SETUNE: > LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : > (VT == MVT::f64) ? RTLIB::UNE_F64 : RTLIB::UNE_F128; > break; > here why SETNE and SETUNE is considered same, why SETONE is considered > differently. Is there any guideline to lower conditional code properly? > > Sincerely, > Vivek > > > > _______________________________________________ > LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > -- > Hal Finkel > Lead, Compiler Technology and Programming Languages > Leadership Computing Facility > Argonne National Laboratory > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170309/5f3400d4/attachment.html>
vivek pandya via llvm-dev
2017-Mar-14 12:16 UTC
[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
Hello Hal, setCondCodeAction(expand) for un ordered comparison generates semantically wrong code for me for example SETUNE gets converted to SETOE that causes infinite loops. What is ideal place where I can convert unordered comparison to un comparison + OR + ordered comparison ? Can I do it by adding required SDNodes ? for example I am trying to do it in LowerBR_CC as shown below: getFPCCtoMBCC(CC,TCC); TargetCC = DAG.getConstant(TCC, dl, MVT::i8); Flag = DAG.getNode(XXXISD::FCMP, dl, MVT::Glue, LHS, RHS, TargetCC); if (isUnordered) { TCC = XXX::COND_UN; TargetCC = DAG.getConstant(TCC, dl, MVT::i8); SDValue UnComp = DAG.getNode(XXX::FCMP, dl, MVT::Glue, LHS, RHS, TargetCC); Flag = DAG.getNode(ISD::OR, dl, MVT::Glue, Flag, UnComp); } but here I can't OR 2 MVT::Glue value. How can I compare results of two fcmp SDValue objs? Please provide some guidance. Sincerely, Vivek On Thu, Mar 9, 2017 at 10:29 PM, vivek pandya <vivekvpandya at gmail.com> wrote:> > > On Thu, Mar 9, 2017 at 9:35 PM, Hal Finkel <hfinkel at anl.gov> wrote: > >> >> On 02/25/2017 03:06 AM, vivek pandya via llvm-dev wrote: >> >> Note: Question is written after describing what I have coded. >> >> Hello LLVMDevs, >> >> I am trying to impliment floating point comparsion for an architecture >> which >> supports following type of floating point comparision if FPU is available: >> fcmp.un --> true if one of the operand is NaN >> fcmp.lt --> ordered less than, if any input NaN then return false >> fcmp.eq --> ordered equal, if any input NaN then return false >> fcmp.le --> ordered less equal, if any input NaN then return false >> fcmp.gt --> ordered grater than, if any input NaN then return false >> fcmp.ne --> ordered not equal, if any input NaN then return true >> fcmp.ge --> ordered grater equal, if any input NaN then return false >> >> When FPU is not present I need to generate a library call, >> >> so I have added following code in LowerBR_CC function in >> XXXISelLowering.cpp >> >> const XXXSubtarget &STI = static_cast<const XXXSubtarget&> >> (DAG.getSubtarget()); >> XXXCC::CondCodes TCC; >> getFPCCtoXXCC(CC,TCC); >> TargetCC = DAG.getConstant(TCC, dl, MVT::i8); >> if (STI.useHardFloat()) { >> // if fcmp instruction is available use it >> SDValue Flag = DAG.getNode(XXXISD::FCMP, dl, MVT::Glue, LHS, RHS, >> TargetCC); >> return DAG.getNode(XXXISD::BR_CC, dl, Op.getValueType(), >> Chain, Dest, TargetCC, Flag); >> } >> else { >> // else generate library call >> DAG.getTargetLoweringInfo().softenSetCCOperands(DAG, MVT::f32, LHS, >> RHS, >> CC, dl); >> >> SDValue Flag = DAG.getNode(XXXISD::CMP, dl, MVT::Glue, LHS, RHS); >> >> if (!RHS.getNode()) { >> RHS = DAG.getConstant(0, dl, LHS.getValueType()); >> TargetCC = DAG.getConstant(XXXCC::COND_NE, dl, MVT::i8); >> } >> return DAG.getNode(XXXISD::BR_CC, dl, MVT::Other, >> Chain, Dest, TargetCC, Flag); >> } >> >> and code for getFPCCtoXXCC() is as following: >> >> static void getFPCCtoXXCC(ISD::CondCode CC, XXXCC::CondCodes &CondCode) { >> switch (CC) { >> default: >> llvm_unreachable("Unknown FP condition!"); >> case ISD::SETEQ: >> case ISD::SETOEQ: >> CondCode = XXXCC::COND_E; >> break; >> case ISD::SETGT: >> case ISD::SETOGT: >> CondCode = XXXCC::COND_GT; >> break; >> case ISD::SETGE: >> case ISD::SETOGE: >> CondCode = XXXCC::COND_GE; >> break; >> case ISD::SETOLT: >> case ISD::SETLT: >> CondCode = XXXCC::COND_LT; >> break; >> case ISD::SETOLE: >> case ISD::SETLE: >> CondCode = XXXCC::COND_LE; >> break; >> case ISD::SETONE: >> case ISD::SETNE: >> CondCode = XXXCC::COND_NE; >> break; >> case ISD::SETUO: >> CondCode = XXXCC::COND_UN; >> break; >> case ISD::SETO: >> case ISD::SETUEQ: >> case ISD::SETUGT: >> case ISD::SETUGE: >> case ISD::SETULT: >> case ISD::SETULE: >> case ISD::SETUNE: >> CC = getSetCCInverse(CC,false); >> getFPCCtoMBCC(CC,CondCode); >> break; >> } >> } >> >> I am generating wrong code when using floating point library call for >> comparions. For the following simple case: >> float branchTest(float a, float b) { >> float retVal; >> if (a == b) { >> retVal = a / b + 22.34; >> } >> return retVal; >> } >> I am getting: >> brlid r15,__nesf2 >> nop >> beqi r3,.LBB0_2 ; r3 is return regsiter >> >> Now I want to understand difference between three different version of >> Condition >> Codes for same operation and how according to my target I should handle >> them. >> For example let's consider SETNE, SETONE and SETUNE so for my >> architecture >> I think for floating point all three are same >> >> >> No, they're not the same. Please see: >> >> http://llvm.org/docs/LangRef.html#id290 >> >> which explains the difference between SETONE (one) and SETUNE (une). >> Regarding how SETNE is interpreted for FP, see the comment in the >> definition of CondCode in include/llvm/CodeGen/ISDOpcodes.h which >> explains, "// Don't care operations: undefined if the input is a nan.". >> >> To support the unordered comparisons, if your FPU has only ordered >> comparisons, then you might need to do the underlying comparison, and a NaN >> check, and then OR the results. I think that using setCondCodeAction will >> cause the expansions for the hardware-unsupported variants to happen for >> you. >> >> -Hal >> > > Thanks Hal for the guidance ! > > -Vivek > >> >> so do I need to use >> getSetCCInverse() ? Also when I look at the code of >> TargetLowering::softenSetCCOperands I see that for some condition code >> it uses >> getSetCCInverse() and also I am not able to understand the way it groups >> condition code in switch case for example : >> case ISD::SETEQ: >> case ISD::SETOEQ: >> LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : >> (VT == MVT::f64) ? RTLIB::OEQ_F64 : RTLIB::OEQ_F128; >> break; >> case ISD::SETNE: >> case ISD::SETUNE: >> LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : >> (VT == MVT::f64) ? RTLIB::UNE_F64 : RTLIB::UNE_F128; >> break; >> here why SETNE and SETUNE is considered same, why SETONE is considered >> differently. Is there any guideline to lower conditional code properly? >> >> Sincerely, >> Vivek >> >> >> >> _______________________________________________ >> LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> >> >> -- >> Hal Finkel >> Lead, Compiler Technology and Programming Languages >> Leadership Computing Facility >> Argonne National Laboratory >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170314/efddbb27/attachment.html>
Hal Finkel via llvm-dev
2017-Mar-14 13:49 UTC
[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
On 03/14/2017 07:16 AM, vivek pandya wrote:> Hello Hal, > setCondCodeAction(expand) for un ordered comparison generates > semantically wrong code for me for example SETUNE gets converted to > SETOE that causes infinite loops.Can you please explain what is happening? It sounds like a bug we should fix.> > What is ideal place where I can convert unordered comparison to un > comparison + OR + ordered comparison ? > Can I do it by adding required SDNodes ? > for example I am trying to do it in LowerBR_CC as shown below: > getFPCCtoMBCC(CC,TCC); > TargetCC = DAG.getConstant(TCC, dl, MVT::i8); > Flag = DAG.getNode(XXXISD::FCMP, dl, MVT::Glue, LHS, RHS, > TargetCC); > if (isUnordered) { > TCC = XXX::COND_UN; > TargetCC = DAG.getConstant(TCC, dl, MVT::i8); > SDValue UnComp = DAG.getNode(XXX::FCMP, dl, MVT::Glue, LHS, RHS, > TargetCC); > Flag = DAG.getNode(ISD::OR, dl, MVT::Glue, Flag, UnComp); > } > but here I can't OR 2 MVT::Glue value. > How can I compare results of two fcmp SDValue objs?If your FCMP node sets some register, you'd need to read it (DAG.getCopyFromReg). -Hal> > Please provide some guidance. > > Sincerely, > Vivek > > On Thu, Mar 9, 2017 at 10:29 PM, vivek pandya <vivekvpandya at gmail.com > <mailto:vivekvpandya at gmail.com>> wrote: > > > > On Thu, Mar 9, 2017 at 9:35 PM, Hal Finkel <hfinkel at anl.gov > <mailto:hfinkel at anl.gov>> wrote: > > > On 02/25/2017 03:06 AM, vivek pandya via llvm-dev wrote: >> Note: Question is written after describing what I have coded. >> >> Hello LLVMDevs, >> >> I am trying to impliment floating point comparsion for an >> architecture which >> supports following type of floating point comparision if FPU >> is available: >> fcmp.un --> true if one of the operand is NaN >> fcmp.lt <http://fcmp.lt> --> ordered less than, if any input >> NaN then return false >> fcmp.eq --> ordered equal, if any input NaN then return false >> fcmp.le --> ordered less equal, if any input NaN then return >> false >> fcmp.gt <http://fcmp.gt> --> ordered grater than, if any >> input NaN then return false >> fcmp.ne <http://fcmp.ne> --> ordered not equal, if any input >> NaN then return true >> fcmp.ge <http://fcmp.ge> --> ordered grater equal, if any >> input NaN then return false >> >> When FPU is not present I need to generate a library call, >> >> so I have added following code in LowerBR_CC function in >> XXXISelLowering.cpp >> >> const XXXSubtarget &STI = static_cast<const XXXSubtarget&> >> (DAG.getSubtarget()); >> XXXCC::CondCodes TCC; >> getFPCCtoXXCC(CC,TCC); >> TargetCC = DAG.getConstant(TCC, dl, MVT::i8); >> if (STI.useHardFloat()) { >> // if fcmp instruction is available use it >> SDValue Flag = DAG.getNode(XXXISD::FCMP, dl, MVT::Glue, >> LHS, RHS, >> TargetCC); >> return DAG.getNode(XXXISD::BR_CC, dl, Op.getValueType(), >> Chain, Dest, TargetCC, Flag); >> } >> else { >> // else generate library call >> DAG.getTargetLoweringInfo().softenSetCCOperands(DAG, >> MVT::f32, LHS, RHS, >> CC, dl); >> >> SDValue Flag = DAG.getNode(XXXISD::CMP, dl, MVT::Glue, >> LHS, RHS); >> >> if (!RHS.getNode()) { >> RHS = DAG.getConstant(0, dl, LHS.getValueType()); >> TargetCC = DAG.getConstant(XXXCC::COND_NE, dl, MVT::i8); >> } >> return DAG.getNode(XXXISD::BR_CC, dl, MVT::Other, >> Chain, Dest, TargetCC, Flag); >> } >> >> and code for getFPCCtoXXCC() is as following: >> >> static void getFPCCtoXXCC(ISD::CondCode CC, XXXCC::CondCodes >> &CondCode) { >> switch (CC) { >> default: >> llvm_unreachable("Unknown FP condition!"); >> case ISD::SETEQ: >> case ISD::SETOEQ: >> CondCode = XXXCC::COND_E; >> break; >> case ISD::SETGT: >> case ISD::SETOGT: >> CondCode = XXXCC::COND_GT; >> break; >> case ISD::SETGE: >> case ISD::SETOGE: >> CondCode = XXXCC::COND_GE; >> break; >> case ISD::SETOLT: >> case ISD::SETLT: >> CondCode = XXXCC::COND_LT; >> break; >> case ISD::SETOLE: >> case ISD::SETLE: >> CondCode = XXXCC::COND_LE; >> break; >> case ISD::SETONE: >> case ISD::SETNE: >> CondCode = XXXCC::COND_NE; >> break; >> case ISD::SETUO: >> CondCode = XXXCC::COND_UN; >> break; >> case ISD::SETO: >> case ISD::SETUEQ: >> case ISD::SETUGT: >> case ISD::SETUGE: >> case ISD::SETULT: >> case ISD::SETULE: >> case ISD::SETUNE: >> CC = getSetCCInverse(CC,false); >> getFPCCtoMBCC(CC,CondCode); >> break; >> } >> } >> >> I am generating wrong code when using floating point library >> call for >> comparions. For the following simple case: >> float branchTest(float a, float b) { >> float retVal; >> if (a == b) { >> retVal = a / b + 22.34; >> } >> return retVal; >> } >> I am getting: >> brlidr15,__nesf2 >> nop >> beqir3,.LBB0_2 ; r3 is return regsiter >> >> Now I want to understand difference between three different >> version of Condition >> Codes for same operation and how according to my target I >> should handle them. >> For example let's consider SETNE, SETONE and SETUNE so for my >> architecture >> I think for floating point all three are same > > No, they're not the same. Please see: > > http://llvm.org/docs/LangRef.html#id290 > <http://llvm.org/docs/LangRef.html#id290> > > which explains the difference between SETONE (one) and SETUNE > (une). Regarding how SETNE is interpreted for FP, see the > comment in the definition of CondCode in > include/llvm/CodeGen/ISDOpcodes.h which explains, "// Don't > care operations: undefined if the input is a nan.". > > To support the unordered comparisons, if your FPU has only > ordered comparisons, then you might need to do the underlying > comparison, and a NaN check, and then OR the results. I think > that using setCondCodeAction will cause the expansions for the > hardware-unsupported variants to happen for you. > > -Hal > > Thanks Hal for the guidance ! > > -Vivek > > >> so do I need to use >> getSetCCInverse() ? Also when I look at the code of >> TargetLowering::softenSetCCOperands I see that for some >> condition code it uses >> getSetCCInverse() and also I am not able to understand the >> way it groups >> condition code in switch case for example : >> case ISD::SETEQ: >> case ISD::SETOEQ: >> LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : >> (VT == MVT::f64) ? RTLIB::OEQ_F64 : RTLIB::OEQ_F128; >> break; >> case ISD::SETNE: >> case ISD::SETUNE: >> LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : >> (VT == MVT::f64) ? RTLIB::UNE_F64 : RTLIB::UNE_F128; >> break; >> here why SETNE and SETUNE is considered same, why SETONE is >> considered >> differently. Is there any guideline to lower conditional code >> properly? >> >> Sincerely, >> Vivek >> >> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org> >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >> <http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev> > > -- > Hal Finkel > Lead, Compiler Technology and Programming Languages > Leadership Computing Facility > Argonne National Laboratory >-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170314/3656b35c/attachment.html>
Apparently Analagous Threads
- Help understanding and lowering LLVM IDS conditional codes correctly
- Help understanding and lowering LLVM IDS conditional codes correctly
- [LLVMdev] HEAD broken?
- [LLVMdev] Help with promotion/custom handling of MUL i32 and MUL i64
- [LLVMdev] Help with promotion/custom handling of MUL i32 and MUL i64