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

Jakob Stoklund Olesen stoklund at 2pi.dk
Sun Aug 2 06:01:56 PDT 2009


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.

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.
* Don't eliminate an identity copy when the source register is  
<undef>. Instead, replace INSERT_SUBREG with an IMPLICIT_DEF  
instruction.
* When replacing %Q1<def, dead> = INSERT_SUBREG ..., add an <imp-kill>  
of the super register.
* 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.
* Allow redefining a sub-register of a live super register.

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.


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.

/jakob
-------------- next part --------------
A non-text attachment was scrubbed...
Name: subreg-elim.patch
Type: application/octet-stream
Size: 7802 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20090802/d4d7d6f4/attachment.obj>
-------------- next part --------------



More information about the llvm-commits mailing list