Pattern matching of CopyToReg SDNode in DAGToDAG::Select()

I am working on implementing custom port for a DSP. My aim is to do custom lowering of CopyToReg with STORE32rr.

My goal is to replace CopyToReg with dummy store instruction placeholder without caring addressing modes for now.

Input LLVM IR -

define i32 @fn(i32 %a, i32 %b) {
        %res = add i32 %a, %b
        ret i32 %res
}

SelectionDAG -

t0: ch,glue = EntryToken
      t2: i32,ch = CopyFromReg t0, Register:i32 %0
      t4: i32,ch = CopyFromReg t0, Register:i32 %1
    t5: i32 = add t2, t4
  t7: ch,glue = CopyToReg t0, Register:i32 $d0, t5
  t8: ch = CustomISD::Ret t7, Register:i32 $d0, t7:1

With these 2 lines of code in CustomDAGToDAGISel::Select() -

  case ISD::CopyToReg:
    {
      SDValue Ops[] = { Node->getOperand(0), Node->getOperand(1), Node->getOperand(2) };
      ReplaceNode(Node, CurDAG->getMachineNode(Custom::STORE32rr, dl, MVT::Other,
                                            MVT::Glue, Ops));
   }

I am able to get below replacement successfully during instruction selection but code is crashing in ASM printer -

t7: ch,glue = STORE32rr t0, Register:i32 $d0, t5

Now, coming to pattern matching present in CustomInstrInfo.td, I have -

class MAU32_rr<string opcodestr>
    : CustomInst<(outs Int32Reg
               : $rZ32),
              (ins Int32Reg
               : $rX32, Int32Reg
               : $rY32),
              opcodestr, "$rZ32, $rX32, $rY32", []>;

def STORE32rr : MAU32_rr<"st32">;

The above code is crashing while printing operand 2 since it only expects operand 0 and operand 1.

There is something missing in above pattern matching which I am unable to figure out. How do I match chain/glue node t0 here? If I give 3 input operands in above pattern then tablegen is complaining that store can have only 2 operands.

What is wrong with above pattern? Can someone please point me what should I change/look for?

Glue and chain are different things. You probably do not want output glue here, and should only be using MVT::Other as the type for STORE32rr. You may want the input glue from the copy as an input to the store

1 Like

@arsenm - Thanks for the reply. Your comment was helpful. Pattern matching was incomplete. I could generate dummy store as placeholder since store expects 2 operands using -

class MAU32_rr<string opcodestr>
    : CustomInst<(outs Int32Reg
               : $rZ32),
              (ins Int32Reg
               : $rX32, Int32Reg
               : $rY32),
              opcodestr, "$rZ32, $rX32, []>;

instead of -

class MAU32_rr<string opcodestr>
    : CustomInst<(outs Int32Reg
               : $rZ32),
              (ins Int32Reg
               : $rX32, Int32Reg
               : $rY32),
              opcodestr, "$rZ32, $rX32, $rY32", []>;

Although, if I just pass MVT::Other, code was crashing and hence, I kept both.