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

vivek pandya via llvm-dev llvm-dev at lists.llvm.org
Sat Feb 25 01:06:26 PST 2017


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


More information about the llvm-dev mailing list