[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