[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 05:16:55 PDT 2017


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.

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?

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
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170314/efddbb27/attachment.html>


More information about the llvm-dev mailing list