Pranav Bhandarkar
2012-Jul-05 15:53 UTC
[LLVMdev] MachineOperand: Subreg defines and the Undef flag
Hi Jakob, Thanks for your reply.> > The <undef> flag goes on NewMI_1 because the virtual register B isn't live > before that instruction. > > But you probably shouldn't be doing this yourself. Your NewMI code isn'tin> SSA form because B has multiple definitions. Just use a REG_SEQUENCE > instruction, and let the register allocator do the transformation for you.Aaargh. So you mean something like this ? New_MI_1:: Vreg1 = 0 ; Vreg1 and Vreg2 are 32 bit virt. regs. New_MI_2:: Vreg2 = COPY C:lo_sub_reg. New_MI_3:: B= REG_SEQUENCE<Vreg1, hi_sub_reg, Vreg2, lo_sub_reg> ; B is a 64 bit virt reg. TIA, Pranav
Jakob Stoklund Olesen
2012-Jul-05 16:21 UTC
[LLVMdev] MachineOperand: Subreg defines and the Undef flag
On Jul 5, 2012, at 8:53 AM, "Pranav Bhandarkar" <pranavb at codeaurora.org> wrote:> Hi Jakob, > > Thanks for your reply. >> >> The <undef> flag goes on NewMI_1 because the virtual register B isn't live >> before that instruction. >> >> But you probably shouldn't be doing this yourself. Your NewMI code isn't > in >> SSA form because B has multiple definitions. Just use a REG_SEQUENCE >> instruction, and let the register allocator do the transformation for you. > > Aaargh. So you mean something like this ? > > New_MI_1:: Vreg1 = 0 ; Vreg1 and Vreg2 > are 32 bit virt. regs. > New_MI_2:: Vreg2 = COPY C:lo_sub_reg. > New_MI_3:: B= REG_SEQUENCE<Vreg1, hi_sub_reg, Vreg2, lo_sub_reg> ; B is a > 64 bit virt reg.Yes. For this particular case, you can also use INSERT_SUBREG. That might be simpler. /jakob
Pranav Bhandarkar
2012-Jul-06 01:01 UTC
[LLVMdev] MachineOperand: Subreg defines and the Undef flag
Hi Jakob,> New_MI_1:: Vreg1 = 0 ; Vreg1 and Vreg2 > are 32 bit virt. regs. > New_MI_2:: Vreg2 = COPY C:lo_sub_reg. > New_MI_3:: B= REG_SEQUENCE<Vreg1, hi_sub_reg, Vreg2, lo_sub_reg> ; B > is a > 64 bit virt reg.I used this approach and it worked find until I hit, what I believe is, a bug in the register coalescer. When the register coalescer cannot trivially coalesce a copy, say C,, it calls AdjustCopiesBackFrom. In this function, we try to see if have this situation. A3 = B0 ..... ..... B1 = A3 <--The copy C And if so, we check if we can merge the two ranges of B into a single range. However, this is not safe if A3 is a subreg define while A3 is not a subreg use. For instance, consider this code (part of a single block loop). MI1:: %vreg7:subreg_loreg<def,undef>, %vreg30<def> = POST_LDriuh %vreg30, 2, // Post Inc. Load. Vreg7 is a 64bit reg. MI2:: %vreg7:subreg_hireg<def> = COPY %vreg32:subreg_hireg<kill> // This is the A3 = B0 above. MI3:: %vreg31<def> = ADD_rr %vreg31<kill>, %vreg32:subreg_loreg<kill> // Use the lo subreg that was setup in MI1: .... .... MI4:: %vreg32<def> = COPY %vreg7; //Not trivial because 7 is not killed. This is the Copy C i.e. B1=A3. .... MI5:: Conditional jump back to start of the block. The coalesce coalesces the copy withouth realizing that the instruction that defined the source of the copy was a copy instruction that only copied a subreg not the whole register. In the event, we lose the lower subreg. Let me know If I am missing something. Pranav Qualcomm Innovation Center, (QuIC) is a member of the Code Aurora Forum.
Jakob Stoklund Olesen
2012-Jul-06 01:48 UTC
[LLVMdev] MachineOperand: Subreg defines and the Undef flag
On Jul 5, 2012, at 6:01 PM, "Pranav Bhandarkar" <pranavb at codeaurora.org> wrote:> Hi Jakob, > >> New_MI_1:: Vreg1 = 0 ; Vreg1 and Vreg2 >> are 32 bit virt. regs. >> New_MI_2:: Vreg2 = COPY C:lo_sub_reg. >> New_MI_3:: B= REG_SEQUENCE<Vreg1, hi_sub_reg, Vreg2, lo_sub_reg> ; B >> is a >> 64 bit virt reg. > > I used this approach and it worked find until I hit, what I believe is, a > bug in the register coalescer. > When the register coalescer cannot trivially coalesce a copy, say C,, it > calls AdjustCopiesBackFrom. In this function, we try to see if have this > situation. > > A3 = B0 > ..... > ..... > B1 = A3 <--The copy C > > And if so, we check if we can merge the two ranges of B into a single range. > However, this is not safe if A3 is a subreg define while A3 is not a subreg > use. > For instance, consider this code (part of a single block loop). > > MI1:: %vreg7:subreg_loreg<def,undef>, %vreg30<def> = POST_LDriuh %vreg30, > 2, // Post Inc. Load. Vreg7 is a 64bit reg. > MI2:: %vreg7:subreg_hireg<def> = COPY %vreg32:subreg_hireg<kill> > // This is the A3 = B0 above. > MI3:: %vreg31<def> = ADD_rr %vreg31<kill>, %vreg32:subreg_loreg<kill> > // Use the lo subreg that was setup in MI1: > .... > .... > MI4:: %vreg32<def> = COPY %vreg7; //Not trivial > because 7 is not killed. This is the Copy C i.e. B1=A3. > .... > MI5:: Conditional jump back to start of the block. > > The coalesce coalesces the copy withouth realizing that the instruction that > defined the source of the copy was a copy instruction that only copied a > subreg not the whole register. > In the event, we lose the lower subreg. > > Let me know If I am missing something.That sounds like a bug, probably adjustCopiesBackFrom needs to check ACopyMI->isFullCopy(). Do you have a test case for this? /jakob
Maybe Matching Threads
- [LLVMdev] MachineOperand: Subreg defines and the Undef flag
- [LLVMdev] MachineOperand: Subreg defines and the Undef flag
- [LLVMdev] MachineOperand: Subreg defines and the Undef flag
- [LLVMdev] MachineOperand: Subreg defines and the Undef flag
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.