I got that message from a call to InstrEmitter::AddOperand. I am writing a back end for CortexM0 (for self teaching purposes), I am working on LDR with immediate offset instruction.
In the ARM backend, if the offset is 0, the following code is executed by the function ARMDAGToDAGISel::SelectThumbAddrModeImm5S
Base = N.getOperand(0);
OffImm = CurDAG->getTargetConstant(0, MVT::i32);
If I do a similar thing in my backend, I get this assertion message. I found out that if I execute the code below, the problem disappear.
Base = N;
OffImm = CurDAG->getTargetConstant(0, TM.getTargetLowering()->getPointerTy());
Only the change for Base seems relevant to the error though.
Could someone give me some pointers to understand what’s going on. For example, something to read about what is “chain & glue”.
Could someone give me some pointers to understand what's going on. For
example, something to read about what is "chain & glue".
The documentation in this area is a little terse, but there's *some*
relevant information at http://llvm.org/docs/CodeGenerator.html
(search for "chain").
My guess is that your "N" already has a chain attached as input
operand 0; when LLVM goes to use the Base and Imm you provide provide
it calls something like:
DAG.getMachineNode(SOME_LOAD, dl, MVT::whatever, Chain, Base, OffImm);
If Base ends up as another chain then LLVM will probably complain as
you're describing because the node being created has two input chains.
Now, the next question is whether N should have a chain in the first
place. That rather depends on what it is and where it comes from, but
it is a little suspicious.
The best advice is probably to make sure you understand exactly what
kind of node N is (more than one possibility may exist) and what its
operands mean before deciding what to write here. Notice that the
current ARM backend checks for exact node types it understands when
deciding where the base lives.
Either a conventional debugger ("call N.dump()") or the llc options
"-view-isel-dags" and friends can be very useful here.