This is an archive of the discontinued LLVM Phabricator instance.

ExpandPostRAPseudos should transfer implicit uses, not only implicit defs
ClosedPublic

Authored by mkuper on Jul 15 2016, 2:42 PM.

Details

Summary

This fixes PR28560.

ExpandPostRAPseudos would transform:

%BL<def> = COPY %DL<kill>, %EBX<imp-use,kill>, %EBX<imp-def>

Into:

%BL<def> = MOV8rr %DL<kill>, %EBX<imp-def>

That caused problems for CriticalAntiDepBreaker which - I believe, correctly - assumes that if an instruction defs but doesn't use a register, that register was dead immediately before the instruction. However, in our case, the high part of EBX is very much alive.

Two notes about the tests:

  1. The new instruction in the arm test isn't really new, it's a scheduling change. The vmov used to be immediately before the vld1, instead of after. Unfortunately, I don't understand ARM enough (= at all) to judge whether this is significant.
  2. The regalloc for the x86 test looks like it could be better - and I'm not entirely sure we need the mov at all. But that's a separate issue.

Diff Detail

Repository
rL LLVM

Event Timeline

mkuper updated this revision to Diff 64195.Jul 15 2016, 2:42 PM
mkuper retitled this revision from to ExpandPostRAPseudos should transfer implicit uses, not only implicit defs.
mkuper updated this object.
mkuper added reviewers: qcolombet, MatzeB.
mkuper added subscribers: llvm-commits, echristo.
echristo accepted this revision.Jul 15 2016, 2:44 PM
echristo added a reviewer: echristo.

This makes complete sense to me. Letting Quentin or Matthias give an ack though.

-eric

This revision is now accepted and ready to land.Jul 15 2016, 2:44 PM
MatzeB accepted this revision.Jul 15 2016, 2:56 PM
MatzeB edited edge metadata.

If BL is defined, it does not mean that the other lanes are dead before the instruction. So there is still a bug in the anti dependency breaker.

On the other hand this patch is obviously good and there is no reason not to do it, so LGTM.

Have you considered writing a .mir test ("llc -run-pass postrapseudos ...")? That should give you a much more stable test.

lib/CodeGen/ExpandPostRAPseudos.cpp
72–77 ↗(On Diff #64195)

If we are on it anyway we could clean this code up:

for (const MachineOperand &MO : MI->implicit_operands()) {
  if (MO.isReg())
    CopyMI->addOperand(MO);
}

If BL is defined, it does not mean that the other lanes are dead before the instruction. So there is still a bug in the anti dependency breaker.

If I understand the code there correctly, the anti dependency breaker will not declare the super-register dead just because the sub-register is dead, it actually needs a def (or imp-def) of the super-register. So I'm not sure there's still a bug.

On the other hand this patch is obviously good and there is no reason not to do it, so LGTM.
Have you considered writing a .mir test ("llc -run-pass postrapseudos ...")? That should give you a much more stable test.

Is MIR is stable enough to write tests *in* it, not just *for* it?
I'd go for that if I were unable to come up with an IR test, but since the IR test looks fairly sane, I'd prefer to keep it.

lib/CodeGen/ExpandPostRAPseudos.cpp
72–77 ↗(On Diff #64195)

Right, thanks!

If BL is defined, it does not mean that the other lanes are dead before the instruction. So there is still a bug in the anti dependency breaker.

If I understand the code there correctly, the anti dependency breaker will not declare the super-register dead just because the sub-register is dead, it actually needs a def (or imp-def) of the super-register. So I'm not sure there's still a bug.

On the other hand this patch is obviously good and there is no reason not to do it, so LGTM.
Have you considered writing a .mir test ("llc -run-pass postrapseudos ...")? That should give you a much more stable test.

Is MIR is stable enough to write tests *in* it, not just *for* it?
I'd go for that if I were unable to come up with an IR test, but since the IR test looks fairly sane, I'd prefer to keep it.

MIR still has clunky syntax and if you are unlucky crashs, but it is certainly good enough for most situations nowadays.

> ls PowerPC/*.mir X86/*.mir AArch64/*.mir | wc -l
14

It worked for 14 real world tests already.

For cases like this I really like the fact that the test is not depend on isel and other unrelated passes which IMO even outweights the clunky syntax...

  • Matthias

If BL is defined, it does not mean that the other lanes are dead before the instruction. So there is still a bug in the anti dependency breaker.

If I understand the code there correctly, the anti dependency breaker will not declare the super-register dead just because the sub-register is dead, it actually needs a def (or imp-def) of the super-register. So I'm not sure there's still a bug.

On the other hand this patch is obviously good and there is no reason not to do it, so LGTM.
Have you considered writing a .mir test ("llc -run-pass postrapseudos ...")? That should give you a much more stable test.

Is MIR is stable enough to write tests *in* it, not just *for* it?
I'd go for that if I were unable to come up with an IR test, but since the IR test looks fairly sane, I'd prefer to keep it.

MIR still has clunky syntax and if you are unlucky crashs, but it is certainly good enough for most situations nowadays.

> ls PowerPC/*.mir X86/*.mir AArch64/*.mir | wc -l
14

It worked for 14 real world tests already.

For cases like this I really like the fact that the test is not depend on isel and other unrelated passes which IMO even outweights the clunky syntax...

  • Matthias

That said I'm fine with keeping the .ll test here.

This revision was automatically updated to reflect the committed changes.