[LLVMdev] undefs in phis

David Greene dag at cray.com
Mon Feb 2 10:08:11 PST 2009


On Friday 30 January 2009 16:54, Evan Cheng wrote:

> I don't have the whole context to understand why you think this is a
> bug. An implicit_def doesn't actually define any value. So we don't
> care if a live interval overlaps live ranges defined by an implicit_def.

It's a bug because the coalerscer does illegal coaescing.

Our last episode left us here:

bb134:
2696    %reg1645<def> = FsMOVAPSrr %reg1458<kill>        ; srcLine 0

bb74:
2700    %reg1176<def> = FsMOVAPSrr %reg1645<kill>        ; srcLine 0
[deleted copy]
2708    %reg1178<def> = FsMOVAPSrr %reg1647<kill>        ; srcLine 0  *** u
before d
2712    TEST64rr %reg1173, %reg1173, %EFLAGS<imp-def>    ; srcLine 30
2716    JLE mbb<file test.f90, bb90,0x3c37ed0>, %EFLAGS<imp-use,kill> ; 
srcLine
0

bb108:
[...]
4352    %reg1253<def> = MAXSSrr %reg1253, %reg1588<kill>         ; srcLine 60
4356    %reg1645<def> = FsMOVAPSrr %reg1253<kill>        ; srcLine 0
4360    %reg1177<def> = FsMOVAPSrr %reg1176<kill>        ; srcLine 0  ***
updated
4364    %reg1647<def> = FsMOVAPSrr %reg1243<kill>        ; srcLine 0
4368    JMP mbb<file test.f90, bb74,0x3c63a60>   ; srcLine 0

This still looks correct.  The coalescer then says:

4360    %reg1177<def> = FsMOVAPSrr %reg1176<kill>        ; srcLine 0
                Inspecting %reg1176,0 = [2702,4362:0)  0 at 2702-(4362) and
%reg1177,0 = 
[2700,3712:0)[3768,3878:0)[4362,4372:0)  0 at 4362-(3878): 
                Joined.  Result = %reg1177,0 = [2700,4372:0)  0 at 2702-(4362)

Now let's look at the resulting code:

bb134:
2696    %reg1645<def> = FsMOVAPSrr %reg1458<kill>        ; srcLine 0

bb74:
2700    %reg1177<def> = FsMOVAPSrr %reg1645<kill>        ; srcLine 0 *** u
[deleted copy]
2708    %reg1178<def> = FsMOVAPSrr %reg1647<kill>        ; srcLine 0  *** u
before d
2712    TEST64rr %reg1173, %reg1173, %EFLAGS<imp-def>    ; srcLine 30
2716    JLE mbb<file test.f90, bb90,0x3c37ed0>, %EFLAGS<imp-use,kill> ; 
srcLine
0

bb108:
[...]
4352    %reg1253<def> = MAXSSrr %reg1253, %reg1588<kill>         ; srcLine 60
4356    %reg1645<def> = FsMOVAPSrr %reg1253<kill>        ; srcLine 0
[deleted copy]
4364    %reg1647<def> = FsMOVAPSrr %reg1243<kill>        ; srcLine 0
4368    JMP mbb<file test.f90, bb74,0x3c63a60>   ; srcLine 0

The very first instruction in bb74 is wrong.  The coalescer has said that y 
always has the same value of x and that's incorrect.  y is always one value 
"behind" x in the original source.

The coalescer thinks it can do this because %reg1177 only has one value number 
and that VN is marked as a copy from %reg1176.  What I'm saying is that while 
%reg1177 really is copied from %reg1176, it also has some initial value 
("undef") coming into the loop.  That value is not captured by the live 
interval information.  It's because of this value that we cannot coalesce 
%reg1177 and %reg1176.  It's because of this value that %reg1177 is always one 
value "behind" %reg1176.

Now, if there's some other way to tell the coalescer that the coalescing is 
illegal, that's fine.  I don't care about the undef value number itself.  I 
care about the coalescer behaving itself.  :)  I just don't know how to tell 
the coalescer not to coalesce this without disabling all coalescings of 
interfering live intervals, even those that are just copies from the source 
register.

Can you think of another way to fix this that's quick and easy?

> That said, the way we models undef in machine instruction has always
> bugged me. I thought about adding a MachineOperand type to represent
> undef. Then we don't have to muddle the semantics of a "def". To me,
> that's a cleaner representation, but it will require work.

Long-term I don't have an opinion on what happens here.  But right now I
need to fix this.

                                                 -Dave



More information about the llvm-dev mailing list