LowerCALL (TargetLowering)

Hi,

I am trying to write a LowerCALL() function for my (custom) target ISA.
All I need to do is map a CALL instruction directly onto an SDNode that
takes an equal number of arguments (very much alike intrinsics, except
that these are custom to my target.) I do not need to implement any call
sequences, stack frames etc.

I get the following assertion failure:

llc: LegalizeDAG.cpp:834: llvm::SDOperand <unnamed>::SelectionDAGLegalize::LegalizeOp(llvm::SDOperand): Assertion `Tmp3.Val->getNumValues() == Result.Val->getNumValues() && "Lowering call/formal_arguments produced unexpected # results!"' failed.

This is what my LowerCALL looks like:

SDOperand MCTargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
    SDOperand Chain = Op.getOperand(0);
    bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
    assert(!isVarArg);
    bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
    SDOperand Callee = Op.getOperand(4);
    MVT::ValueType RetVT= Op.Val->getValueType(0);
    unsigned NumOps = (Op.getNumOperands() - 5) / 2;

    std::string Name;
    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
  Name = G->getGlobal()->getName();
    else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
  Name = S->getSymbol();

    unsigned opcode = funcname_to_opc[Name];
    assert(opcode != 0 && "Unknown function call.");

    std::vector<MVT::ValueType> Tys;
    std::vector<SDOperand> Ops;

    for (unsigned i = 0; i != NumOps; ++i) {
  SDOperand Arg = Op.getOperand(5+2*i);
  Tys.push_back(Arg.getValueType());
  Ops.push_back(Arg);
    }
    Tys.push_back(MVT::Other);
    Ops.push_back(Chain);

    Chain = DAG.getNode(opcode, Tys, &Ops[0], Ops.size());

    assert(RetVT == MVT::Other);
    return Chain;
}

Everything works fine for functions with no arguments, but otherwise I
get this assert. Can anyone point out my mistake?

Any help will be greatly appreciated,

Thanks,
Nikhil

Hi Nickhil,

The Legalizer expects lower'd call is the node that produce the same number of values as the non-lowered node. That's what the assertion is checking.

Take a look at the LowerCall routine for any other targets. You will see that in the non-void function case, it returns a MERGE_VALUES, i.e. all the results merged along with the chain.

Cheers,

Evan

Hi Evan,

Hi Nickhil,

The Legalizer expects lower'd call is the node that produce the same
number of values as the non-lowered node. That's what the assertion
is checking.

Take a look at the LowerCall routine for any other targets. You will
see that in the non-void function case, it returns a MERGE_VALUES,
i.e. all the results merged along with the chain.

Sorry, I don't understand. I am only trying to look at functions that
return void here (hence the RetVT == MVT::Other assertion near the end
of my function). So, I think there should be only a single result -
the SDOperand returned by the DAG.getNode(..), and I shouldn't need any
MERGE_VALUES node.

Am I missing something?

Thanks!
Nikhil

Aah, I figured this out now. I had misunderstood the semantics of the
getNode operator. The following code snippet now works.

Sorry for the noise! :slight_smile:
Nikhil

  Tys.push_back(MVT::Other);
  Ops.push_back(Chain);
  for (unsigned i = 0; i != NumOps; ++i) {
      SDOperand Arg = Op.getOperand(5+2*i);
      Tys.push_back(Arg.getValueType());
      Ops.push_back(Arg);
  }
  
  Chain = DAG.getNode(opcode, RetVT, &Ops[0], Ops.size());
  
  assert(RetVT == MVT::Other);
  return Chain;

(as opposed to the earlier:)