Skip to content

Commit b7b170c

Browse files
committed
[MachineVerifier] Improve verification of live-in lists.
MachineVerifier::visitMachineFunctionAfter() is extended to check the live-through case for live-in lists. This is only done for registers without aliases and that are neither allocatable or reserved, such as the SystemZ::CC register. The MachineVerifier earlier only catched the case of a live-in use without an entry in the live-in list (as "using an undefined physical register"). A comment in LivePhysRegs.h has been added stating a guarantee that addLiveOuts() can be trusted for a full register both before and after register allocation. Review: Quentin Colombet https://reviews.llvm.org/D68267
1 parent a0324e9 commit b7b170c

File tree

5 files changed

+151
-0
lines changed

5 files changed

+151
-0
lines changed

llvm/include/llvm/CodeGen/LivePhysRegs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ class LivePhysRegs {
137137
/// Live out registers are the union of the live-in registers of the successor
138138
/// blocks and pristine registers. Live out registers of the end block are the
139139
/// callee saved registers.
140+
/// If a register is not added by this method, it is guaranteed to not be
141+
/// live out from MBB, although a sub-register may be. This is true
142+
/// both before and after regalloc.
140143
void addLiveOuts(const MachineBasicBlock &MBB);
141144

142145
/// Adds all live-out registers of basic block \p MBB but skips pristine

llvm/lib/CodeGen/MachineVerifier.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,32 @@ void MachineVerifier::visitMachineFunctionAfter() {
23042304
if (LiveInts)
23052305
verifyLiveIntervals();
23062306

2307+
// Check live-in list of each MBB. If a register is live into MBB, check
2308+
// that the register is in regsLiveOut of each predecessor block. Since
2309+
// this must come from a definition in the predecesssor or its live-in
2310+
// list, this will catch a live-through case where the predecessor does not
2311+
// have the register in its live-in list. This currently only checks
2312+
// registers that have no aliases, are not allocatable and are not
2313+
// reserved, which could mean a condition code register for instance.
2314+
if (MRI->tracksLiveness())
2315+
for (const auto &MBB : *MF)
2316+
for (MachineBasicBlock::RegisterMaskPair P : MBB.liveins()) {
2317+
MCPhysReg LiveInReg = P.PhysReg;
2318+
bool hasAliases = MCRegAliasIterator(LiveInReg, TRI, false).isValid();
2319+
if (hasAliases || isAllocatable(LiveInReg) || isReserved(LiveInReg))
2320+
continue;
2321+
for (const MachineBasicBlock *Pred : MBB.predecessors()) {
2322+
BBInfo &PInfo = MBBInfoMap[Pred];
2323+
if (!PInfo.regsLiveOut.count(LiveInReg)) {
2324+
report("Live in register not found to be live out from predecessor.",
2325+
&MBB);
2326+
errs() << TRI->getName(LiveInReg)
2327+
<< " not found to be live out from "
2328+
<< printMBBReference(*Pred) << "\n";
2329+
}
2330+
}
2331+
}
2332+
23072333
for (auto CSInfo : MF->getCallSitesInfo())
23082334
if (!CSInfo.first->isCall())
23092335
report("Call site info referencing instruction that is not call", MF);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s
2+
3+
# Test that a the machine verifier reports an error when a register in
4+
# liveins is not liveout from predecessor.
5+
6+
---
7+
name: f1
8+
tracksRegLiveness: true
9+
machineFunctionInfo: {}
10+
body: |
11+
bb.0:
12+
liveins: $r2l, $r3l
13+
14+
%1:gr32bit = COPY $r3l
15+
%0:gr32bit = COPY $r2l
16+
CHIMux %0, 0, implicit-def $cc
17+
18+
bb.1:
19+
liveins: $cc
20+
21+
bb.2:
22+
liveins: $cc
23+
24+
%2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc
25+
$r2l = COPY %2
26+
Return implicit $r2l
27+
...
28+
29+
# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. ***
30+
# CHECK:- function: f2
31+
# CHECK:- basic block: %bb.2
32+
# CHECK:CC not found to be live out from %bb.1
33+
---
34+
name: f2
35+
tracksRegLiveness: true
36+
machineFunctionInfo: {}
37+
body: |
38+
bb.0:
39+
liveins: $r2l, $r3l
40+
41+
%1:gr32bit = COPY $r3l
42+
%0:gr32bit = COPY $r2l
43+
CHIMux %0, 0, implicit-def $cc
44+
45+
bb.1:
46+
liveins: $cc
47+
KILL killed $cc
48+
49+
bb.2:
50+
liveins: $cc
51+
52+
%2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc
53+
$r2l = COPY %2
54+
Return implicit $r2l
55+
56+
...
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s
2+
3+
# Test that a the machine verifier reports an error when a register in
4+
# liveins is not liveout from predecessor.
5+
6+
---
7+
name: f1
8+
tracksRegLiveness: true
9+
machineFunctionInfo: {}
10+
body: |
11+
bb.0:
12+
liveins: $r2l, $r3l
13+
14+
%1:gr32bit = COPY $r3l
15+
%0:gr32bit = COPY $r2l
16+
CHIMux %0, 0, implicit-def $cc
17+
18+
bb.1:
19+
20+
bb.2:
21+
liveins: $cc
22+
23+
%2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc
24+
$r2l = COPY %2
25+
Return implicit $r2l
26+
...
27+
28+
# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. ***
29+
# CHECK:- function: f1
30+
# CHECK:- basic block: %bb.2
31+
# CHECK:CC not found to be live out from %bb.1
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s
2+
3+
# Test that a the machine verifier reports an error when a register in
4+
# liveins is not liveout from predecessor.
5+
6+
---
7+
name: f1
8+
tracksRegLiveness: true
9+
machineFunctionInfo: {}
10+
body: |
11+
bb.0:
12+
liveins: $r2l, $r3l
13+
14+
%1:gr32bit = COPY $r3l
15+
%0:gr32bit = COPY $r2l
16+
CHIMux %0, 0, implicit-def $cc
17+
18+
bb.1:
19+
liveins: $cc
20+
BRC 14, 8, %bb.3, implicit $cc
21+
22+
bb.2:
23+
24+
bb.3:
25+
liveins: $cc
26+
27+
%2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc
28+
$r2l = COPY %2
29+
Return implicit $r2l
30+
...
31+
32+
# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. ***
33+
# CHECK:- function: f1
34+
# CHECK:- basic block: %bb.3
35+
# CHECK:CC not found to be live out from %bb.2

0 commit comments

Comments
 (0)