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

vivek pandya via llvm-dev llvm-dev at lists.llvm.org
Thu Mar 9 08:59:07 PST 2017


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>


More information about the llvm-dev mailing list