This is an archive of the discontinued LLVM Phabricator instance.

[MachineVerifier] Verify the RegUsageInfo collected for the current function.
AbandonedPublic

Authored by jonpa on Apr 2 2018, 2:28 AM.

Details

Reviewers
qcolombet
Summary

https://bugs.llvm.org/show_bug.cgi?id=36587 discovered a set of used (preserved) pregs in function that was corrupt which led to wrong code.

This patch adds a check in the MachineVerifier that makes sure that any registers defined by any instruction in the current function which are call-preserved have all their aliases marked as used in function in the set produced by RegUsageInfoCollector.

As it is now no verification will be done if CallPreservedMask is nullptr (this happens with a lot of AMDGPU tests).

This test fails now: LLVM :: CodeGen/AMDGPU/function-returns.ll

The test in 36587 fails like:

`# End machine code for function fn2.

    • Bad machine code: Defined register (alias) not in RegUsageInfo: R0H ***
  • function: fn2
  • basic block: %bb.1 (0x50f3540)
  • instruction: renamable $r0d = LGHI 0

LLVM ERROR: Found 1 machine code errors.`

Diff Detail

Event Timeline

jonpa created this revision.Apr 2 2018, 2:28 AM
jonpa added a comment.Apr 2 2018, 2:49 AM

Note: the AMDGPU test failure is not helped by https://reviews.llvm.org/D45157.

junbuml added a subscriber: junbuml.Apr 2 2018, 6:56 AM
jonpa updated this revision to Diff 141832.Apr 10 2018, 6:25 AM

I discovered that a subreg may be call-preserved even though the full register is not. Patch updated to handle this.

fhahn added a subscriber: fhahn.Apr 16 2018, 2:50 AM
qcolombet added inline comments.Apr 23 2018, 1:51 PM
lib/CodeGen/MachineVerifier.cpp
360

I would have named it verifyPreservedMask or something.
I would expect a verifyUsedPhysReg to work on UsedPhysRegMask not the PreservedMask one.

jonpa added inline comments.Apr 29 2018, 12:27 AM
lib/CodeGen/MachineVerifier.cpp
360

To me verifyPreservedMask mostly associates to getCallPreservedMask(), on the other hand :-) How about verifyRegUsageInfoCollector() ?

BTW, is my naming for PreservedRegs good? It seems to be called just RegMask elsewhere. 'PreservedRegs' reflects the fact that if a bit is set, then that reg is preserved. But this is always true for a RegMask, then perhaps we should stick to that name? Or 'FunctionRegMask'?

qcolombet accepted this revision.May 3 2018, 3:51 PM
qcolombet added inline comments.
lib/CodeGen/MachineVerifier.cpp
360

I'd say it doesn't hurt to be explicit :). (I.e., I think having preserved in the name is good.)

I like the verifyRegUsageInfoCollector name!

This revision is now accepted and ready to land.May 3 2018, 3:51 PM
jonpa requested review of this revision.May 4 2018, 1:31 AM

Wait - don't we need to check if current function returns true with isSafeForNoCSROpt()?

Good catch!

Actually, following the other related patch, I think we should use determineCalleeSaved. Moreover, I don't remember when this function is supposed to give the right answer, but we probably need to gate the check behind NoVRegs or something like that.

jonpa marked 3 inline comments as done.May 25 2018, 3:46 AM

Good catch!

Actually, following the other related patch, I think we should use determineCalleeSaved. Moreover, I don't remember when this function is supposed to give the right answer, but we probably need to gate the check behind NoVRegs or something like that.

I think it's ok since PRUI is not set until the pass has been run.

I tried to simply reuse the new function from the related patch now, but ran into a problem: A reg with subregs had one subreg completely unclobbered, and the other one saved/restored. We could check subregs again with a new loop to see if they are all saved or unclobbered, or we could just add this extra check in computeCalleeSavedRegs like

// Add PReg to SavedRegs if all subregs are saved or unmodified.                                                                                                                                                             
bool AllSubRegsSaved = true;
for (MCSubRegIterator SR(PReg, TRI, false); SR.isValid(); ++SR)
  if (!SavedRegs.test(*SR) && MRI->isPhysRegModified(*SR)) {
    AllSubRegsSaved = false;
    break;
  }

I am however having second thoughts about verifying this in the MachineVerifier, given that the Collector pass is run after all else (at least after post-RA pseudo expansion and scheduling), so it seems that we are just verifying our own algorithm without having any real benefit of verifying other passes.

Do you agree we could drop this patch?

Do you agree we could drop this patch?

Agreed.

jonpa abandoned this revision.May 25 2018, 10:12 AM