Req-sequence, partial defs

Hi,

I’m having an issue with subregisters on my target.

With a pseudo that writes to a 32 bit reg:

%vreg20 = toHi16_low0_pseudo %vreg2; reg32:%vreg20 hi16:%vreg2

expands to

%vreg2 = COPY %a2h; hi16:%vreg2
%vreg43 = mov 0, pred:0, pred:%noreg, %ac0, %ac1; lo16:%vreg43
%vreg20 = REG_SEQUENCE %vreg2, hi16, %vreg43, lo16; reg32:%vreg20 hi16:%vreg2 lo16:%vreg43

Becomes

16L %vreg20:hi16<def,undef> = COPY %a2h, %vreg20; reg32:%vreg20
368L %vreg20:lo16 = mov 0, pred:0, pred:%noreg, %ac0, %ac1; reg32:%vreg20

Becomes

Live Ins: %a0h %a1_32 %a2h %a3_32
… (COPY coalesced as a2h is live in)
%a2l = mov 0, pred:0, pred:%noreg, %ac0, %ac1, %a2_32

results in:

** Bad machine code: Using an undefined physical register ***

  • function: lfixedconv8
  • basic block: 0x91a1940 (BB#0)
  • instruction: %a2l = mov 0, pred:0, pred:%noreg, %ac0, %ac1, %a2_32
  • operand 6: %a2_32

I cannot quite figure what’s wrong here - the a2_32 operand was added by the VirtualRegRewriter, because the partial def was not marked undef. The reason for this was that the LiveIntervalsAnalysis pass cleaned up after REG_SEQUENCE lowering by making the first occurence - when the interval for the reg was empty and thus created - an <def,undef>, but then it does not do the same for the other subreg, as at that time the interval for the reg is not empty.

Can anyone say what went wrong?

Thanks,

Jonas

The COPY with additional operands shouldn’t have been deleted. It should have been turned into a KILL pseudo-instruction instead, preserving the operands and the liveness of the super-register.

This bug was fixed by deleting VirtRegRewriter :wink:

/jakob