[llvm-dev] RegAlloc Q: spill when implicit-def physreg is also the output reg of instruction

Quentin Colombet via llvm-dev llvm-dev at lists.llvm.org
Wed May 8 10:34:06 PDT 2019

> On May 8, 2019, at 1:12 AM, Björn Pettersson A <bjorn.a.pettersson at ericsson.com> wrote:
> I think it looks a little bit weird have
>    %2:reg = MyInst %1:reg, ..., implicit-def dead $p1, ...;
> before regalloc. Where $p1 is an allocatable register, of the same class as %2, and it is marked as “dead” (since the deadness will depend on the register allocation)?

No the deadness depends on whether the implicit-def is used or not. The dead flags are actually mandatory *before* register allocation.

> Not sure if it is normal that we have implicit defs of allocatable registers before regalloc?

That is totally fine. E.g., X86 has a bunch of allocatable registers as implicit def/use for a lot of instructions, like pop.

> Is that avoided for other targets by using a different approach, such as using explicit defs when modelling how allocatable registers are updated by the instructions (at least before RA).

The problem is somewhat rare because it needs 3 things to happen at the same time on the same instruction for the bug to show up (and it is specific to the fast allocator):
- defines virtual register, and
- defines physical register, and
- has at least one physical register definition occurring *after* (in the operand list) the virtual register definition

Note that the dead flag is not part of the problem.

> Maybe the above should be perfectly OK (and maybe it is a common scenario even if I can’t remember that I’ve seen it before).
> Then I hope that the tentative fix also removes the “dead” on the implicit-def.

The dead is totally fine.

> It would be weird to have two defs, one dead and one live after regalloc. Or will the register allocator find $p1 as unavailable (even if the def is dead), selecting another register for the non-implicit def?

That’s what it should have done :).

> Regards,
> Björn
> From: llvm-dev <llvm-dev-bounces at lists.llvm.org> On Behalf Of Quentin Colombet via llvm-dev
> Sent: den 8 maj 2019 02:41
> To: Kevin Choi <code.kchoi at gmail.com>
> Cc: llvm-dev <llvm-dev at lists.llvm.org>
> Subject: Re: [llvm-dev] RegAlloc Q: spill when implicit-def physreg is also the output reg of instruction
> Thanks for the report Kevin!
> I’ve posted a tentative fix there for you to try.
> I haven’t tested it myself yet, but I’ll write a test case for it.
> On May 7, 2019, at 1:17 PM, Kevin Choi <code.kchoi at gmail.com <mailto:code.kchoi at gmail.com>> wrote:
> Hi Quentin,
> MyInst is a custom instruction that has implicit-defs of fixed registers. The implicit-defs are seen at the end of Instruction Selection. 
> I'd like to add a report, but I am working on an out-of-tree backend based on 7.0. I can try to help reduce the testcase down.
> Filed https://bugs.llvm.org/show_bug.cgi?id=41790 <https://bugs.llvm.org/show_bug.cgi?id=41790>
> Regards,
> Kevin
> On 2019-05-07 3:45 p.m., Quentin Colombet wrote:
> Hi Kevin, 
> That sounds like a bug :).
> When is the implicit-def added?
> What I am thinking is if it gets added after we computed the live intervals, then we may miss it is there.
> Could you file a public report?
> Thanks,
> -Quentin
> On May 6, 2019, at 3:13 PM, Kevin Choi via llvm-dev <llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>> wrote:
> Hi LLVM,
> I ran into a case where RegAlloc would insert a spill across instruction that had same register for output operand and implicit-def. The effect this had was that spill code would immediately overwrite the output result. Is this the expected result of setting up MyInst this way? In other words, does RegAlloc know to not insert spill in case it sees that output reg is same as one of implicit-def?
> If this is intended (always spilling live regs across implicit-def inst?), I am puzzled on how to use MyInst that has variable output reg with static implicit-defs. Any tips would be greatly appreciated.
> Reduced Example:
> Before RegAlloc:
> %1:reg = COPY ...;
> %2:reg = MyInst %1:reg, ..., implicit-def dead $p1, ...;
> %3:reg = Use %2:reg
> RegAlloc:
> >> %2:reg = MyInst %1:reg, ..., implicit-def dead $p1, ...;
> Regs: $p1=%1
> Killing last use: %1:reg
> Assigning %2 to $p1
> Spilling %2 in $p1 to stack slot #2  <-- suspicious if this is inserting spill, unaware of output reg being same
> << $p1 =MyInst killed $p1, ..., implicit-def dead $p1, ...; 
> After RegAlloc:
> $p1 = COPY ...;
> Store $p1 %stack.2;
> $p1 =MyInst killed $p1, ..., implicit-def dead $p1, ...;
> $p1 = Load %stack.2;
> $p2 = Use $p1, ...;
> Best Regards,
> Kevin
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org <mailto:llvm-dev at lists.llvm.org>
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev <https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190508/5b324cce/attachment.html>

More information about the llvm-dev mailing list