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>
Maybe Matching Threads
- Help understanding and lowering LLVM IDS conditional codes correctly
- Help understanding and lowering LLVM IDS conditional codes correctly
- [LLVMdev] Help with promotion/custom handling of MUL i32 and MUL i64
- [LLVMdev] HEAD broken?
- [LLVMdev] Help with promotion/custom handling of MUL i32 and MUL i64