[llvm-dev] Help understanding and lowering LLVM IDS conditional codes correctly

vivek pandya via llvm-dev llvm-dev at lists.llvm.org
Tue Mar 14 09:29:53 PDT 2017


On Tue, Mar 14, 2017 at 7:19 PM, Hal Finkel <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).
>
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>
> 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
>>>
>>> --
> 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/a33c5b0c/attachment.html>


More information about the llvm-dev mailing list