[llvm-commits] [PATCH] Fix Bug 4657: register scavenger asserts with subreg lowering

Evan Cheng evan.cheng at apple.com
Sun Aug 2 12:47:43 PDT 2009


On Aug 2, 2009, at 6:01 AM, Jakob Stoklund Olesen wrote:

> Implicitly defined registers are marked with <undef>, and may be  
> used by a MachineOperand without being live. LowerSubregs does not  
> yet know about the <undef> flag, causing PR4657 in this code:
>
> %Q1<def> = INSERT_SUBREG %Q1<undef>, %D1<kill>, 5
> %Q1<def> = INSERT_SUBREG %Q1, %D0<kill>, 6
> ...
> subreg: CONVERTING: %Q1<def> = INSERT_SUBREG %Q1<undef>, %D1<kill>, 5
> subreg: %D2<def> = FCPYD %D1, 14, %reg0
>
> The original INSERT_SUBREG instruction defines %Q1, the replacement  
> FCPYD does not. The <undef> flag means that %Q1 may not be live, and  
> the register scavenger asserts later when %Q1 is used.

Ok, that's bad.

>
> The attached patch teaches LowerSubregs about the <undef> flag:
>
> * Add a %Q1<imp-def> operand to the inserted copy instruction. This  
> makes sure that the super register is live.

Ok.

> * Don't eliminate an identity copy when the source register is  
> <undef>. Instead, replace INSERT_SUBREG with an IMPLICIT_DEF  
> instruction.

Can we change this to <undef> of the subsequent use(s)? Or is it too  
much work?

> * When replacing %Q1<def, dead> = INSERT_SUBREG ..., add an <imp- 
> kill> of the super register.

I am not sure if I understand this? Can you show me an example?

> * Fix a bug in transferring the kill flag from InsReg: InsReg is  
> operand #2, not #1.
>
> In the regscavenger:
>
> * Allow imp-use of a dead register.

I don't get this part. Is this using an implicit_def?

> * Allow redefining a sub-register of a live super register.

To be precise, it should be modeled as a use and def. See  
LiveVariables.cpp

         // The larger register is previously defined. Now a smaller  
part is
         // being re-defined. Treat it as read/mod/write if there are  
uses
         // below.
         // EAX =
         // AX  =        EAX<imp-use,kill>, EAX<imp-def>
         // ...
         ///    =  EAX


>
> With the patch, the LowerSubregs replacement looks like this:
>
> subreg: CONVERTING: %Q1<def> = INSERT_SUBREG %Q1<undef>, %D1<kill>, 5
> subreg: %D2<def> = FCPYD %D1<kill>, 14, %reg0, %Q1<imp-def>
>
> The %D1<kill> flag has been correctly transferred and %Q1<imp-def>  
> was added. This fixes PR4657.

Great. Thanks.


>
>
> I am not completely sure it is a good idea to insert IMPLICIT_DEF  
> instructions in LowerSubregs. The problem is this instruction:
> %Q1<def> = INSERT_SUBREG %Q1<undef>, %D2<kill>, 5
> Since %D2 is subreg #5 of Q1 it is a noop and can be removed.  
> However, that would mean the %Q1 is no longer considered live after  
> the instruction, causing more regscavenger asserts. In the patch, I  
> replace INSERT_SUBREG with this instruction:
> %Q1<def> = IMPLICIT_DEF %Q1<imp-kill>
> It is a noop that makes sure %Q1 is live. It think it is a misuse of  
> IMPLICIT_DEF, but I don't know what else to do. Suggestions welcome.

The ideal solution is to add <undef> to the following uses of Q1 (and  
it's sub-registers). But that'll probably require scanning the  
following instructions. That's not a good idea either.

Are you saying in this case there isn't a matching q1 = insert_subreg  
%q1, x, 6? I think using implicit_def is perfectly ok then. Part of Q1  
is implicitly defined.

The patch looks good except for this part:


-    assert(isUsed(Reg) && "Using an undefined register!");
+    assert((MO.isImplicit() || isUsed(Reg)) && "Using an undefined  
register!");

Do you mean MO.isUndef()?

Evan

>
> /jakob
> <subreg-elim.patch>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list