Can we hint some virtual registers to the same physical registers

I try to legalize below MIR

%0:GPR = MOVI  0XFF 0   #move 0xFF to bit 0~7 of an GPR register
%1:GPR = MOVI  0XFF 1   #move 0xFF to bit 8~15 of an GPR register
%2:GPR = MOVI  0XFF 2   #move 0xFF to bit 16~23 of an GPR register
%3:GPR = MOVI  0XFF 3   #move 0xFF to bit 24~31 of an GPR register
$S10 = COPY %3:GPR

Our GPR register is 32 bit width, and our MOVI has two source operands, operand 0 is a 8 bit immediate number, the second immediate is the offset of the dest register.

So using above four instructions, I move four int8 number to a 32 bit GPR register. Of course, virtual register %0, %1, %2, %3 should be assigned to the same physical register.

But seems compiler dose not know this, it will think %0, %1, %2 are dead code and eliminate them. So if there is a way to hint LLVM Codegen assign %0, %1, %2, %3 the same physical register?

This instruction is actually read-modify-write instruction so it needs an input register operand:

%4:GRP = IMPLICIT_DEF
%0:GPR = MOVI  %4, 0XFF 0   #move 0xFF to bit 0~7 of an GPR register
%1:GPR = MOVI  %0, 0XFF 1   #move 0xFF to bit 8~15 of an GPR register
%2:GPR = MOVI  %1, 0XFF 2   #move 0xFF to bit 16~23 of an GPR register
%3:GPR = MOVI  %2, 0XFF 3   #move 0xFF to bit 24~31 of an GPR register
$S10 = COPY %3:GPR

For that operand to be allocated to the same physical register, it should be tied to the output register, e.g.:

def MOVI : Instruction {
  let OutOperandList = (outs GPR:$rd)
  let InOperandList = (ins GPR:$rs, i8imm:$val, i8imm:$idx);
  let Constraints = "$rs = $rd";
}

Thanks for your reply. Should I set this MOVI instruction as a Pseudo Instruction? Our cpu dosen’t have encoding fileds for the input register.

There is no need to turn it into a pseudo. Since the input and the output registers are going to be the same after register allocation (more precisely, after TwoAddressInstructionPass), you only need to encode one of them. Look for existing examples in other backends.

Thanks a lot.