This is an archive of the discontinued LLVM Phabricator instance.

[MachineVerifier] Handle the PHI node for verifyLiveVariables()
ClosedPublic

Authored by ZhangKang on May 20 2020, 12:06 AM.

Details

Summary

When doing MachineVerifier for LiveVariables, the MachineVerifier pass will calculate the LiveVariables,
and compares the result with the result livevars pass gave. If they are different, verifyLiveVariables()
will give error.
But when we calculate the LiveVariables in MachineVerifier, we don't consider the PHI node, while livevars
considers, so we will get different result and verifyLiveVariables() will be failed.
Now, we don't enable the verificatoin for LiveVariables, so we haven't gotten the failure for verifyLiveVariables().

For below case:

48 body:             |
49   bb.0.entry:
50     successors: %bb.1(0x80000000)
51     liveins: $x3
52
53     %4:g8rc_and_g8rc_nox0 = COPY killed $x3
54     %0:g8rc = LD 0, %4 :: (dereferenceable load 8 from %ir.p)
55
56   bb.1.loop:
57     successors: %bb.1(0x20000000), %bb.2(0x60000000)
58
59     %1:g8rc_and_g8rc_nox0 = PHI %0, %bb.0, %2, %bb.1, %3, %bb.3, %2, %bb.2
60     %5:gprc = LBZ 0, %1 :: (load 1 from %ir.0)
61     %6:crrc = CMPWI killed %5, 0
62     %7:crbitrc = COPY killed %6.sub_eq
63     %2:g8rc = nuw ADDI8 %1, 1
64     STD %2, 0, %4 :: (store 8 into %ir.p)
65     %8:gprc = LBZ 1, %1 :: (load 1 from %ir.incdec.ptr)
66     BCn killed %7, %bb.1
67     B %bb.2
68
69   bb.2.loop:
70     successors: %bb.3(0x55555555), %bb.1(0x2aaaaaab)
71
72     %9:crrc = CMPWI killed %8, 0
73     %10:crbitrc = COPY killed %9.sub_eq
74     BC killed %10, %bb.1
75     B %bb.3
76
77   bb.3.if.then3:
78     successors: %bb.1(0x80000000)
79
80     %3:g8rc = nuw ADDI8 killed %1, 2
81     STD %3, 0, %4 :: (store 8 into %ir.p)
82     B %bb.1

We will get below error:

# Bad machine code: LiveVariables: Block should not be in AliveBlocks
# - function:    zext_free
# - basic block: %bb.2 loop
# Virtual register %2 is not needed live through the block.
# LLVM ERROR: Found 1 machine code errors.

But in fact, %2 is should live through the %bb.2. In the line 59 for PHI, %2 can be
from %bb.1 or %bb.2, and %2 is defined in %bb.1, so %2 is live through %bb2, not live
through %bb1.

Below is the liveVariables info for above case:

Reg: %1  Alive in blocks: 2,
  Killed by:
    #0: %3:g8rc = nuw ADDI8 killed %1:g8rc_and_g8rc_nox0, 2

Reg: %2  Alive in blocks: 2,
  Killed by: No instructions.

Reg: %4  Alive in blocks: 1, 2, 3,
  Killed by: No instructions.

This patch can fix 210 verification error for LiveVariables.

Diff Detail

Event Timeline

ZhangKang created this revision.May 20 2020, 12:06 AM
ZhangKang retitled this revision from [MachineVerifier] Handle the PHI node for Live verifyLiveVariables() to [MachineVerifier] Handle the PHI node for verifyLiveVariables().May 20 2020, 12:08 AM
ZhangKang edited reviewers, added: efriedma; removed: eli.friedman. ZhangKang removed 1 blocking reviewer(s): thegameg.May 20 2020, 12:48 AM
ZhangKang added a subscriber: efriedma.
ZhangKang edited the summary of this revision. (Show Details)Jun 10 2020, 10:58 PM

@dexonsmith Do you have any comments for this patch?

dexonsmith resigned from this revision.Jun 15 2020, 10:37 AM
aprantl added inline comments.Jun 15 2020, 4:44 PM
llvm/test/CodeGen/PowerPC/livevars-crash2.mir
2

A test that doesn't CHECK anything is almost entirely useless. It will succeed even if you symlink llc to /bin/true. Without a CHECK there is zero indication about what code path is supposed to be covered by it, so future maintainers will not know what aspect to preserve when updating the test. Please try to add a meaningful CHECK or delete the test.

ZhangKang updated this revision to Diff 270983.Jun 16 2020, 2:01 AM

Add CHECK for the case.

ZhangKang marked 2 inline comments as done.Jun 16 2020, 2:02 AM
ZhangKang added inline comments.
llvm/test/CodeGen/PowerPC/livevars-crash2.mir
2

Have added CHECK for the test case.

ZhangKang marked an inline comment as done.Jul 10 2020, 9:30 AM

ping...

lenary removed a subscriber: lenary.Jul 14 2020, 2:51 AM

ping. @thegameg @qcolombet , do you have any comments for this patch?

bjope added inline comments.Jul 21 2020, 6:28 AM
llvm/lib/CodeGen/MachineVerifier.cpp
135–136

Add a comment here that vregsLiveIn doesn't include regs that only are used by PHI nodes.

2306

Can't you just simply loop over the PHI nodes belonging to MBB here, finding all the PHI-related <vreg, pred> pairs.
That should give you all the additional vregs that should be live in (that earlier has been left our from the vregsLiveIn map), and from which predecessors the value should be required.

That way you do not need the PHIVarFrom map (and being even more dependant on what visitMachineInstrBefore is doing). I mean the map is only caching the information stored in the PHI instructions anyway.

bjope added a comment.Jul 21 2020, 6:42 AM

I'm a bit curious about the overall plan here. Some years ago the plan was to remove LiveVariables, and use LiveIntervals instead. And afaik PHIElimination was updated to support both LiveVariables and LiveIntervals, while TwoAddressInstructionPass only got partially updated. So for several years there have been a technical debt here, considering that the passes involved in de-SSA to some degree are supporting both LiveVaribels and LiveIntervals, while only LiveVariables is used in practise (and the support for LiveIntervals may have rotten since it is poorly tested).

Considering that work now is being done to tidy up the LiveVariables support (or at least the verification of it), maybe we should consider dropping LiveIntervals support in the de-SSA phase completely. Or maybe we should spend time on finalizing the phase-out of LiveVariables instead. Is this perhaps something that you have been thinking about?

arsenm added a subscriber: arsenm.Jul 22 2020, 10:29 AM

I'm a bit curious about the overall plan here. Some years ago the plan was to remove LiveVariables, and use LiveIntervals instead. And afaik PHIElimination was updated to support both LiveVariables and LiveIntervals, while TwoAddressInstructionPass only got partially updated. So for several years there have been a technical debt here, considering that the passes involved in de-SSA to some degree are supporting both LiveVaribels and LiveIntervals, while only LiveVariables is used in practise (and the support for LiveIntervals may have rotten since it is poorly tested).

Considering that work now is being done to tidy up the LiveVariables support (or at least the verification of it), maybe we should consider dropping LiveIntervals support in the de-SSA phase completely. Or maybe we should spend time on finalizing the phase-out of LiveVariables instead. Is this perhaps something that you have been thinking about?

The idea is to remove kill flags and LiveVariables

ZhangKang updated this revision to Diff 280382.Jul 24 2020, 3:14 AM

Update the patch to follow reviewers' comments.

ZhangKang marked 3 inline comments as done.Jul 24 2020, 3:15 AM
ZhangKang added inline comments.
llvm/lib/CodeGen/MachineVerifier.cpp
2306

Have updated the patch to remvoe PHIVarFrom .

bjope added inline comments.Jul 27 2020, 4:14 AM
llvm/lib/CodeGen/MachineVerifier.cpp
2309

Should be possible to use MBB.phis() on previous line, to iterate over the range of MI:s that are PHI nodes.

2319

I had expected something like this, simply dealing with the vregs being live in and used in the PHI instructions (earlier left out from vregsLiveIn since we need to care about the control flow edges).

for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
  // Skip those Operands which are undef regs or not regs.
  if (!MI.getOperand(i).isReg() || !MI.getOperand(i).readsReg())
    continue;.

  // Get register and predecessor for one PHI edge.
  unsigned Reg = MI.getOperand(i).getReg();
  const MachineBasicBlock *Pred = MI.getOperand(i + 1).getMBB();

  BBInfo &PInfo = MBBInfoMap[Pred];
  if (PInfo.addRequired(Reg))
    todo.insert(Pred);
}

Notice that addRequired will return false if Reg isn't a virtual register, or if Reg already is in the required set. So the outer if-statement here seems redundant due to that.

Another question is if you need to do the MRI->getVRegDef(Reg)->getParent() != FromMBB check or not.
That would map to something like this

bb8:
  %t = phi i32 [ ... ], [ %y, %bb8 ]
  %y = add ...
  ...
  br i1 ..., %bb8

From the LiveVariables verifications point of view we expect that vregsRequired should match AliveBlocks information. And afaict %bb8 won't be in AliveBlocks for %y (since %y is defined in %bb8), so it should not be in vregsRequired. However, since addRequired also checks regsLiveOut before adding anything to vregsRequired, that situation should be covered as well.

ZhangKang updated this revision to Diff 280943.Jul 27 2020, 9:23 AM
ZhangKang marked 2 inline comments as done.

Simplify the code.

ZhangKang marked an inline comment as done.Jul 27 2020, 9:24 AM
bjope accepted this revision.Jul 29 2020, 5:59 AM

LGTM!

This revision is now accepted and ready to land.Jul 29 2020, 5:59 AM
This revision was landed with ongoing or failed builds.Jul 29 2020, 8:49 AM
This revision was automatically updated to reflect the committed changes.