LLVM Backend DAGToDAGISel INTRINSIC

I am currently working on DAGToDAGISel class for MIPS and am trying to figure out a way to use INTRINSIC_W_CHAIN for an intrinsic which can return a value.

My intrinsic is defined as:
Intrinsic<[llvm_i32_ty],[llvm_i32_ty,llvm_i32_ty,llvm_i32_ty,llvm_i32_ty],[IntrReadWriteArgMem]>;

i.e. it has four arguments and one return value

In DAGToDAGISel when I try to pass it with four arguments and a return register it fails the assertion `ResNo < NumValues && “Illegal result number!”’.

More specifically I am doing something like:
EVT ReturnValueVT = Node->getValueType(0) ;
SDValue ChainIn = Node->getOperand(0);
SDValue Zero = CurDAG->getCopyFromReg(ChainIn, DL,
Mips::ZERO, MVT::i32);
SDValue op0 = Node->getOperand(2);
SDValue op1 = Node->getOperand(3);
SDValue op2= Node->getOperand(4);
SDValue op3 = Node->getOperand(5);
SDValue Ops[]= { op0, op1, op2, op3, Zero, ChainIn };
SDNode *Result = CurDAG->getMachineNode(Mips::BWT_DROP_RESULT, SDLoc(Node),
ReturnValueVT, Ops);
ReplaceUses(Node, Result);
return std::make_pair(true, Result);

Any clues on how INTRINSIC_W_CHAIN differs from INTRINSIC_VOID?

Thanks,

Ambuj Agrawal

Hi,

Have you found the mips_cfcmsa intrinsic? It’s the only example of a INTRINSIC_W_CHAIN with a result and an argument that I can think of.

This is just a guess but does the BWT_DROP_RESULT instruction have an output? If not, I’d guess that the problem is that ReplaceUses() is trying to use the first output of Result (which has no outputs and therefore asserts when it this is attempted) as a replacement for the first output of Node.

Thanks for your reply.

I was able to fix the problem by having a return type for result.

Something like:
SDNode *Result = CurDAG->getMachineNode(Mips::INSTR, SDLoc(Node),
ReturnValueVT, MVT::Other, Ops);