Handling Tied Operands in backend code generator


I have two instructions of the form below in SSA form where there is a tied operand constraint on the instruction definition.

%1:GPR = INST1 .. 
%100:GPR = INST2 .. implicit %1 (tied-def 0)

Later, during another target specific pass while still in SSA form, I hit the assert below when removeOperand() is called on one of the source operands (not the implicit operand in this case)

#ifndef NDEBUG
  // Moving tied operands would break the ties.
  for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i)
    if (Operands[i].isReg())
      assert(!Operands[i].isTied() && "Cannot move tied operands");

a) Is the expectation that the pass should untie register operands, call removeOperand() and tie them back together? I see some upstream passes doing this.

b) Since any instruction in the target specific backend can have tied-def constraint described above, should optimizations on the MIR in SSA form be aware of tied-operands and handle them appropriately?
For instance if there is a peephole optimization that looks at defs/uses of an instruction and performs an optimization if the use is a source operand on an instruction, I might have to bail out from the optimization if the source operands are tied-defs during this peephole optimization since this might result in incorrect code. Should the target backend handle such cases correctly?

  • Jayashree

There isn’t a fundamental limitation, there’s just missing API to handle this. They could be moved, but it requires updating the operand indices in all tied operand pairs. You can untie and re-tie as an ugly way to achieve this.

Thanks, figured that there must be missing API support.