ISelDAGToDAG breaks node ordering

Hi,

During instruction selection, I have the following code for certain LOAD instructions:

       const LoadSDNode *LD = cast<LoadSDNode>(N);
       SDNode* LDW = CurDAG->getMachineNode(AVR::LDWRdPtr, SDLoc(N), VT, PtrVT, MVT::Other,
           LD->getBasePtr(), LD->getChain());

       // Honestly, I have no idea what this does, but other memory
       // accessing instructions have something similar...
       MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
       MemOp[0] = cast<MemSDNode>(N)->getMemOperand();
       cast<MachineSDNode>(LDW)->setMemRefs(MemOp, MemOp + 1);

       // Reshuffle LDW's results so that the first two match LOAD's result
       // type
       SDValue Unpack = { SDValue(LDW, 0), SDValue(LDW, 2), SDValue(LDW, 1) };
       SDNode* NN = CurDAG->getMergeValues(Unpack, SDLoc(N)).getNode();

       ReplaceUses(N, NN);
       CurDAG->RemoveDeadNode(N);

With this code, I get correct-looking machine instructions, but the node order is all botched up. For example, given this input:

SelectionDAG has 8 nodes:
   t0: ch = EntryToken
     t2: i16,ch = CopyFromReg t0, Register:i16 %vreg0
   t5: i16,ch = load<Volatile LD2[%1](align=1)(dereferenceable)> t0, t2, undef:i16
   t7: ch,glue = CopyToReg t5:1, Register:i16 %R25R24, t5
   t8: ch = RET_FLAG t7, Register:i16 %R25R24, t7:1

The resulting output is

SelectionDAG has 8 nodes:
   t0: ch = EntryToken
   t7: ch,glue = CopyToReg t10:1, Register:i16 %R25R24, t10
     t2: i16,ch = CopyFromReg t0, Register:i16 %vreg0
   t9: i16,i16,ch = LDWRdPtr<Mem:Volatile LD2[%1](align=1)(dereferenceable)> t2, t0
   t10: i16,ch,i16 = merge_values t9, t9:2, t9:1
   t8: ch = RET Register:i16 %R25R24, t7, t7:1

As you can see, even though the edges are correct, t7 should be after t10. This trips up LLVM further downstream:

   lib/CodeGen/SelectionDAG/InstrEmitter.cpp:303:
   unsigned int llvm::InstrEmitter::getVR(llvm::SDValue, llvm::DenseMap<llvm::SDValue, unsigned int>&):
   Assertion `I != VRBaseMap.end() && "Node emitted out of order - late"' failed.

Any idea what might be causing this? Where does the order of nodes come from anyway?

Thanks,
   Gergo

Calling getMergeValues in ISelDAGToDAG is a bad idea; there aren't supposed to be any MERGE_VALUES nodes at that point in the pipeline.

You can call ReplaceUses with SDValues rather than SDNodes.

-Eli

Oh wow, yes! These are exactly the two pieces of information I was missing. This works now:

       SDNode* LDW = CurDAG->getMachineNode(AVR::LDWRdPtr, SDLoc(N), VT, PtrVT, MVT::Other,
                                            LD->getBasePtr(), LD->getChain());
       transferMemOperands(N, LDW);

       ReplaceUses(SDValue(N, 0), SDValue(LDW, 0));
       ReplaceUses(SDValue(N, 1), SDValue(LDW, 2));
       CurDAG->RemoveDeadNode(N);

Thanks a lot!

   Gergo