[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly
Hal Finkel via llvm-dev
llvm-dev at lists.llvm.org
Tue Mar 14 11:43:42 PDT 2017
On 03/14/2017 01:16 PM, vivek pandya wrote:
>
>
> On Tue, Mar 14, 2017 at 9:59 PM, vivek pandya <vivekvpandya at gmail.com
> <mailto:vivekvpandya at gmail.com>> wrote:
>
>
>
> On Tue, Mar 14, 2017 at 7:19 PM, Hal Finkel <hfinkel at anl.gov
> <mailto:hfinkel at anl.gov>> wrote:
>
>
> 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.
>
> I don't think it is LLVM bug but I am missing some thing or I have
> not implemented something related properly.
> But I will experiment it with and let you my findings.
>
>>
>> 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).
>
> Hey Hal,
> I have few questions here,
> Do you here mean FCMP sets any physical register ?
Yes.
> Because as per my understanding getCopyFromReg() requires a reg
> operand to copy from.
> What if it set some virtual register? Then how to use getCopyFromReg()
> method?
You wouldn't. If your FCMP node sets a virtual register, then it should
be one of the return values of the node (i.e. there should be a some
value type (MVT::i8 or whatever) in the value-type list for the FCMP node).
-Hal
>
> getCopyFromReg() requires a Chain operand so I have to make FCMP both
> Chain and Glue (by using SDVTList
> <http://llvm.org/docs/doxygen/html/structllvm_1_1SDVTList.html>VTs =
> getVTList
> <http://llvm.org/docs/doxygen/html/classllvm_1_1SelectionDAG.html#a196c23d6cb4d768d037970f1f35bbf66>(MVT::Other
> <http://llvm.org/docs/doxygen/html/classllvm_1_1MVT.html#afd69b4f2dff97a2d7c0192cc769ef50ca62a222acce6360abd2726719fabc2797>,
> MVT::Glue
> <http://llvm.org/docs/doxygen/html/classllvm_1_1MVT.html#afd69b4f2dff97a2d7c0192cc769ef50ca59a1908cf136662bcfdc11ed49515ca9>)) right
> ?
>
> Sincerely,
> Vivek
>
> Ok I will see some examples for getCopyFromReg().
>
> Thanks,
> Vivek
>
>
>
> -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
>
--
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/e1ade691/attachment-0001.html>
More information about the llvm-dev
mailing list