vivek pandya via llvm-dev
2017-Feb-25 09:06 UTC
[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
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 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170225/bd6e23b2/attachment.html>
Hal Finkel via llvm-dev
2017-Mar-09 16:05 UTC
[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
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 sameNo, 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> 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 > http://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/4e821159/attachment-0001.html>
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>
Possibly Parallel 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