Ok, I understand a bit more of what's going on in my phi example.
Coming into DAGtoDAG we have this code:
bb74:
x = phi(1.0:bb134, %r1450:bb108)
y = phi(undef:bb134, x:bb108)
[...]
bb108:
%r1450 = <expr>
After DAGtoDAG we have:
bb134:
%reg1459 = IMPLICIT_DEF
%reg1458 = 1.0
bb74:
%reg1176 = phi(%reg1458:bb134, %reg1253:bb108)
%reg1177 = phi(%reg1459:bb134, %reg1176:bb108)
[...]
bb108:
%reg1253 = <expr>
So far so good, though the IMPLICIT_DEF is worrisome. I'm guessing
that's
what causes problems later.
After phi elimination we have:
bb134:
%reg1645 = 1.0
bb74:
%reg1176 = MOVAPS %reg1645
%reg1177 = MOVAPS %reg1646
[...]
bb108:
%reg1645 = <expr>
%reg1646 = %reg1176
Again, this is all good except that %reg1646 is not defined on the first entry
to bb74. This is actually consistent with the original code which is:
x = 1.0
do
if (x == 1.0) {
[...use x...]
else {
[...use x and y...]
}
y = x
x = <expr>
end do
So there is a use-before-def in the dataflow sense but it's safe due to the
control flow.
My guess is that regalloc or some other pass after phi elimination gets
confused due to the use-before-def of %reg1646.
My question is, who is responsible for fixing up a situation like this? My
guess is that llvm-gcc takes care of patching holes like this and our
frontend could do the same. Should llvm be able to handle situations like
this or is the result undefined?
-Dave