[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 06:49:16 PDT 2017


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.

>
> 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).

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


More information about the llvm-dev mailing list