From 659efa21f1b3eded304b7239b356eecf1f5034ae Mon Sep 17 00:00:00 2001 From: Jonas Paulsson Date: Tue, 19 Nov 2019 12:34:49 +0100 Subject: [PATCH] Recommit "[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 Differential Revision: https://reviews.llvm.org/D68267 --- llvm/include/llvm/CodeGen/LivePhysRegs.h | 3 ++ llvm/lib/CodeGen/MachineVerifier.cpp | 26 ++++++++++++++ llvm/test/MachineVerifier/live-ins-01.mir | 57 +++++++++++++++++++++++++++++++ llvm/test/MachineVerifier/live-ins-02.mir | 32 +++++++++++++++++ llvm/test/MachineVerifier/live-ins-03.mir | 36 +++++++++++++++++++ 5 files changed, 154 insertions(+) create mode 100644 llvm/test/MachineVerifier/live-ins-01.mir create mode 100644 llvm/test/MachineVerifier/live-ins-02.mir create mode 100644 llvm/test/MachineVerifier/live-ins-03.mir diff --git a/llvm/include/llvm/CodeGen/LivePhysRegs.h b/llvm/include/llvm/CodeGen/LivePhysRegs.h index 50da0b3..0858934 100644 --- a/llvm/include/llvm/CodeGen/LivePhysRegs.h +++ b/llvm/include/llvm/CodeGen/LivePhysRegs.h @@ -137,6 +137,9 @@ public: /// Live out registers are the union of the live-in registers of the successor /// blocks and pristine registers. Live out registers of the end block are the /// callee saved registers. + /// If a register is not added by this method, it is guaranteed to not be + /// live out from MBB, although a sub-register may be. This is true + /// both before and after regalloc. void addLiveOuts(const MachineBasicBlock &MBB); /// Adds all live-out registers of basic block \p MBB but skips pristine diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp index ca57e51..b2534c2 100644 --- a/llvm/lib/CodeGen/MachineVerifier.cpp +++ b/llvm/lib/CodeGen/MachineVerifier.cpp @@ -2312,6 +2312,32 @@ void MachineVerifier::visitMachineFunctionAfter() { if (LiveInts) verifyLiveIntervals(); + // Check live-in list of each MBB. If a register is live into MBB, check + // that the register is in regsLiveOut of each predecessor block. Since + // this must come from a definition in the predecesssor or its live-in + // list, this will catch a live-through case where the predecessor does not + // have the register in its live-in list. This currently only checks + // registers that have no aliases, are not allocatable and are not + // reserved, which could mean a condition code register for instance. + if (MRI->tracksLiveness()) + for (const auto &MBB : *MF) + for (MachineBasicBlock::RegisterMaskPair P : MBB.liveins()) { + MCPhysReg LiveInReg = P.PhysReg; + bool hasAliases = MCRegAliasIterator(LiveInReg, TRI, false).isValid(); + if (hasAliases || isAllocatable(LiveInReg) || isReserved(LiveInReg)) + continue; + for (const MachineBasicBlock *Pred : MBB.predecessors()) { + BBInfo &PInfo = MBBInfoMap[Pred]; + if (!PInfo.regsLiveOut.count(LiveInReg)) { + report("Live in register not found to be live out from predecessor.", + &MBB); + errs() << TRI->getName(LiveInReg) + << " not found to be live out from " + << printMBBReference(*Pred) << "\n"; + } + } + } + for (auto CSInfo : MF->getCallSitesInfo()) if (!CSInfo.first->isCall()) report("Call site info referencing instruction that is not call", MF); diff --git a/llvm/test/MachineVerifier/live-ins-01.mir b/llvm/test/MachineVerifier/live-ins-01.mir new file mode 100644 index 0000000..51c05da --- /dev/null +++ b/llvm/test/MachineVerifier/live-ins-01.mir @@ -0,0 +1,57 @@ +# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s +# REQUIRES: systemz-registered-target + +# Test that a the machine verifier reports an error when a register in +# liveins is not liveout from predecessor. + +--- +name: f1 +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $r2l, $r3l + + %1:gr32bit = COPY $r3l + %0:gr32bit = COPY $r2l + CHIMux %0, 0, implicit-def $cc + + bb.1: + liveins: $cc + + bb.2: + liveins: $cc + + %2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc + $r2l = COPY %2 + Return implicit $r2l +... + +# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. *** +# CHECK:- function: f2 +# CHECK:- basic block: %bb.2 +# CHECK:CC not found to be live out from %bb.1 +--- +name: f2 +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $r2l, $r3l + + %1:gr32bit = COPY $r3l + %0:gr32bit = COPY $r2l + CHIMux %0, 0, implicit-def $cc + + bb.1: + liveins: $cc + KILL killed $cc + + bb.2: + liveins: $cc + + %2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc + $r2l = COPY %2 + Return implicit $r2l + +... diff --git a/llvm/test/MachineVerifier/live-ins-02.mir b/llvm/test/MachineVerifier/live-ins-02.mir new file mode 100644 index 0000000..d76325c --- /dev/null +++ b/llvm/test/MachineVerifier/live-ins-02.mir @@ -0,0 +1,32 @@ +# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s +# REQUIRES: systemz-registered-target + +# Test that a the machine verifier reports an error when a register in +# liveins is not liveout from predecessor. + +--- +name: f1 +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $r2l, $r3l + + %1:gr32bit = COPY $r3l + %0:gr32bit = COPY $r2l + CHIMux %0, 0, implicit-def $cc + + bb.1: + + bb.2: + liveins: $cc + + %2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc + $r2l = COPY %2 + Return implicit $r2l +... + +# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. *** +# CHECK:- function: f1 +# CHECK:- basic block: %bb.2 +# CHECK:CC not found to be live out from %bb.1 diff --git a/llvm/test/MachineVerifier/live-ins-03.mir b/llvm/test/MachineVerifier/live-ins-03.mir new file mode 100644 index 0000000..b5345cc --- /dev/null +++ b/llvm/test/MachineVerifier/live-ins-03.mir @@ -0,0 +1,36 @@ +# RUN: not llc -o - %s -mtriple=s390x-linux-gnu -mcpu=z14 -run-pass none 2>&1 | FileCheck %s +# REQUIRES: systemz-registered-target + +# Test that a the machine verifier reports an error when a register in +# liveins is not liveout from predecessor. + +--- +name: f1 +tracksRegLiveness: true +machineFunctionInfo: {} +body: | + bb.0: + liveins: $r2l, $r3l + + %1:gr32bit = COPY $r3l + %0:gr32bit = COPY $r2l + CHIMux %0, 0, implicit-def $cc + + bb.1: + liveins: $cc + BRC 14, 8, %bb.3, implicit $cc + + bb.2: + + bb.3: + liveins: $cc + + %2:grx32bit = LOCRMux %1, %0, 14, 8, implicit $cc + $r2l = COPY %2 + Return implicit $r2l +... + +# CHECK: *** Bad machine code: Live in register not found to be live out from predecessor. *** +# CHECK:- function: f1 +# CHECK:- basic block: %bb.3 +# CHECK:CC not found to be live out from %bb.2 -- 2.7.4