Hello LLVM Developers,
Could you please provide review for following code snippet ? I would like to understand if this is correct way to generate unordered comparison when architecture natively does not support such comparison or not. Also I am facing some assertion failure but not for all cases and not for all optimization level that makes it herder to detect. I am facing :
clang-3.9: /home/vpandya/llvm_old/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp:356:
void llvm::ScheduleDAGSDNodes::BuildSchedUnits(): Assertion `N->getNodeId() == -1 && “Node already inserted!”’ failed.
I have explained the code which caused this assertion but I am not able to understand why it happens.
SDValue XXXTargetLowering::LowerSELECT_CC(SDValue Op,
SelectionDAG &DAG) const {
SDValue LHS = Op.getOperand(0);
SDValue RHS = Op.getOperand(1);
SDValue TrueV = Op.getOperand(2);
SDValue FalseV = Op.getOperand(3);
ISD::CondCode CC = cast(Op.getOperand(4))->get();
SDLoc dl (Op);
SDValue TargetCC;
MVT SVT = LHS.getSimpleValueType();
SDValue Flag;
const XXXSubtarget &STI = static_cast<const XXXSubtarget&>
(DAG.getSubtarget());
if (SVT == MVT::f32 && STI.hasFPU() ) {
XXXCC::CondCodes TCC;
bool isUnordered = false;
switch (CC) {
case ISD::SETUEQ:
isUnordered = true;
CC = ISD::SETEQ;
break;
case ISD::SETUNE:
isUnordered = true;
CC = ISD::SETNE;
break;
case ISD::SETUGT:
isUnordered = true;
CC = ISD::SETGT;
break;
case ISD::SETUGE:
isUnordered = true;
CC = ISD::SETGE;
break;
case ISD::SETULT:
isUnordered = true;
CC = ISD::SETLT;
break;
case ISD::SETULE:
isUnordered = true;
CC = ISD::SETLE;
break;
}
if (CC == ISD::SETO)
TCC = XXXCC::COND_UN;
else
getFPCCtoMBCC(CC,TCC); // just converts CC to Target specific code
TargetCC = DAG.getConstant(TCC, dl, MVT::i32);
// Here if I keeo MVT::Other I am facing above mentioned asserion
// the reason for keeping this is I want to use this node as Chain node
// in getCopyFromReg() but when I remove this still it works
// Is this correct use of Glue and Chain type?
SDVTList VTList = DAG.getVTList(MVT::Glue,/* MVT::Other*/);
Flag = DAG.getNode(XXXISD::FCMP, dl, VTList, LHS, RHS,
TargetCC);
//TODO: if setCondCodeAction(unorderedCom , Exapnd) works properly then we
// do not have to do this manually
if (isUnordered) {
// read result of first FCMP from R18
SDValue Reg1 = DAG.getCopyFromReg(Flag, dl, XXX::R18, MVT::i32,
Flag);
TCC = XXXCC::COND_UN;
TargetCC = DAG.getConstant(TCC, dl, MVT::i32);
SDValue UnComp = DAG.getNode(XXXISD::FCMP, dl,VTList, LHS, RHS,
TargetCC);
// read result of second FCMP from R18
SDValue Reg2 = DAG.getCopyFromReg(UnComp, dl, XXX::R18, MVT::i32,
UnComp);
SDVTList VTList1 = DAG.getVTList(MVT::i32, MVT::Other);
// OR results of both comparion if result is 1 then jump to destination
SDValue ORV = DAG.getNode(ISD::OR, dl, MVT::i32, Reg1, Reg2);
SDVTList VTs = DAG.getVTList(MVT::Glue,MVT::Other);
SDValue Ops = {ORV, DAG.getRegister(XXX::R18,
ORV.getValueType()), ORV, ORV};
Flag = DAG.getNode(ISD::CopyToReg, dl, VTs,
makeArrayRef(Ops, ORV.getNode() ? 4 : 3));
}
// fcmp instruction results 0 or 1 so next instruction will be bne{i}
// that should branch to destination
if (CC == ISD::SETO)
TargetCC = DAG.getConstant(XXXCC::COND_E, dl, MVT::i32);
else
TargetCC = DAG.getConstant(XXXCC::COND_NE, dl, MVT::i32);
}
else {
Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
}
SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Glue);
SDValue Ops = {TrueV, FalseV, TargetCC, Flag};
return DAG.getNode(XXXISD::SELECT_CC, dl, VTs, Ops);
}
Thanks,
Vivek