<div dir="ltr">> It's an arbitrary set of lane masks, and<br>> there's no way to go backwards from a set of lanemasks to a set of<br>> subregister indexes to implicitly def.<br><div><br></div><div>There is a precedent for trying to solve that problem: it's what SplitEditor::buildCopy does. Perhaps that logic could be factored out and reused.</div><div><br></div><div>Jay.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 19 Nov 2020 at 23:32, Matt Arsenault via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi,<br>
<br>
I'm stuck trying to fix a variety of problems that occur with undef<br>
subregisters when the register coalescer eliminates identity<br>
copies. The fundamental problem is complexity from the fact that undef<br>
values are a special case since they don't have an associated<br>
VNInfo/Segment unless the value is used across blocks.<br>
<br>
For example, in this case, %0 has 2 subregisters sub0 and sub1:<br>
  bb.0:<br>
    undef %0.sub1:vreg_64 = COPY killed $vgpr0<br>
<br>
  bb.1:<br>
    %0:vreg_64 = COPY %0<br>
    S_CBRANCH_EXECNZ %bb.1, implicit $exec<br>
<br>
  bb.2:<br>
    undef %0.sub1:vreg_64 = nofpexcept V_CEIL_F32_e32 killed %0.sub1, implicit $mode, implicit $exec<br>
    S_BRANCH %bb.1<br>
<br>
sub0 has no defined values anywhere in this function. The value only<br>
exists due to this identity copy in %bb.1, which is removed.<br>
<br>
When the copy is erased and the interval is updated<br>
(<a href="https://github.com/llvm/llvm-project/blob/523cc097fdafa1bb60373dcc70df7dfd31551f56/llvm/lib/CodeGen/RegisterCoalescer.cpp#L1871" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/523cc097fdafa1bb60373dcc70df7dfd31551f56/llvm/lib/CodeGen/RegisterCoalescer.cpp#L1871</a>),<br>
the new live interval looks like this:<br>
<br>
%0 [16r,32B:2)[32B,96r:0)[96r,128B:1)  0@32B-phi 1@96r 2@16r<br>
  L0000000000000003 [32B,80B:0)  0@32B-phi // sub0<br>
<br>
This remaining [32B,80B:0) across %bb.1 is a fake phi-only segment. If<br>
I freshly recompute LiveIntervals, the subrange is empty as it should<br>
be. The verifier doesn't care about this, however it does end up<br>
confusing RenameIndependentSubregs. After RenameIndependentSubregs,<br>
this becomes<br>
<br>
%0 [24r,24d:0)[104r,104d:1) 0@24r 1@104r L0000000000000003<br>
[24r,24d:1)[104r,104d:2) which fails the verifier with "Multiple<br>
connected components in live interval".<br>
<br>
I'm able to hack this segment out in simple situations when the<br>
identity copy is removed, but so far have been unable to get it to<br>
work correctly in more complex situtations where there are other valid<br>
segments present. This requires a more complex analysis of the<br>
incoming value than should really be necessary when eliminating a<br>
trivial copy. In a similar situation where undef copies are<br>
eliminated, an IMPLICIT_DEF is inserted in place to give a<br>
corresponding instruction / value number for the cross-block undef<br>
value. However in this situation, there's no specific subregister<br>
index associated to define. It's an arbitrary set of lane masks, and<br>
there's no way to go backwards from a set of lanemasks to a set of<br>
subregister indexes to implicitly def.<br>
<br>
I've also hit a second family of this same fundamental problem with a<br>
slight variant of the testcase:<br>
<br>
  bb.0:<br>
    liveins: $vgpr0<br>
<br>
    undef %0.sub1:vreg_64 = COPY killed $vgpr0<br>
<br>
  bb.1:<br>
    %1:vreg_64 = COPY killed %0<br>
    %0:vreg_64 = COPY %1  // Indirect identity copy<br>
    S_CBRANCH_EXECNZ %bb.1, implicit $exec<br>
<br>
  bb.2:<br>
    undef %2.sub1:vreg_64 = COPY %0.sub1<br>
    %0:vreg_64 = COPY killed %2<br>
    S_BRANCH %bb.1<br>
<br>
...<br>
<br>
Here, pruneSubRegValues  (<a href="https://github.com/llvm/llvm-project/blob/3ded927cf80ac519f9f9c4664fef08787f7c537d/llvm/lib/CodeGen/RegisterCoalescer.cpp#L3114" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/blob/3ded927cf80ac519f9f9c4664fef08787f7c537d/llvm/lib/CodeGen/RegisterCoalescer.cpp#L3114</a>) ends up leaving behind a similarly dead segment.<br>
<br>
1. Is omitting undef lanes from the live segments a good idea in the<br>
first place? This isn't the first time this special case has been an<br>
issue.<br>
<br>
2. Should effectively empty segments be a verifier error? I'm not sure<br>
what the exact rule would be.<br>
<br>
3. Should RenameIndependentSubregs tolerate these weird segments<br>
instead?<br>
<br>
4. Do we need some way to represent an arbitrary lanemask def to have<br>
something to insert in place of the copy?<br>
<br>
-Matt<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>