Not implicitly, you need another vreg with class GR32 and some
operation to widen the narrow one. And actually you probably need that
to be a real sign/zero extension or something because I don't think
x86 clears the high bits of eax when writing to ax, does it?
If it was 32 -> 64 bit, I think the rules are different and rax would
be zero-extended automatically. In that case you could use a
SUBREG_TO_REG which would eventually go away.
One of the first things I tried was to insert a zero extend 16-to-32-bit instruction, but that also caused an additional 32-bit physical register to be generated, which is not what I want.
The actual implementation I'm doing is a bit more complex than the example I provided for illustrative purposes. In my case, I don't need to care about the upper bits at all.
OK, in that case I think SUBREG_TO_REG is what you want. Something like
BuildMI(MBB, InsertPt, Loc, TII->get(X86::SUBREG_TO_REG), ExtendedReg)
.addImm(0) // Never been entirely sure what this was here for.
It's always 0.
.addReg(NarrowReg)
.addImm(X86::sub_16bit);
then use ExtendedReg (a GR32 vreg) in the compare.
If there’s no guarantee of a value for the upper bits don’t you want INSERT_SUBREG? SUBREG_TO_REG says the upper bits are 0(or whatever the immediate says). Not that I’ve ever found a place that checks it.
Thanks Tim and Craig. I tried both of your suggestions, and both generate the correct machine code for the test examples I have written. Looking at the documentation for SUBREG_TO_REG:
/// SUBREG_TO_REG - This instruction is similar to INSERT_SUBREG except that
/// the first operand is an immediate integer constant. This constant is
/// often zero, because it is commonly used to assert that the instruction
/// defining the register implicitly clears the high bits.
So I think I agree with Craig that the more natural solution is to stick with INSERT_SUBREG.