From e1d9628bba5f42790ba73d37fe961d560d921408 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 19 Sep 2016 16:49:45 +0000 Subject: [PATCH] LiveRangeCalc: Fix reporting of invalid vreg usage in liveness calculation Machine programs need a definition of each vreg before reaching a use (the definition may come from an IMPLICIT_DEF instruction). This class of errors is not detected by the MachineVerifier because of efficiency concerns. LiveRangeCalc used to report these problems, make it do that again (followup to r279625). Also use report_fatal_error() instead of llvm_unreachable() as the error reporting is only present in asserts build anyway. llvm-svn: 281914 --- llvm/lib/CodeGen/LiveRangeCalc.cpp | 6 +++--- llvm/test/CodeGen/X86/invalid-liveness.mir | 31 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 llvm/test/CodeGen/X86/invalid-liveness.mir diff --git a/llvm/lib/CodeGen/LiveRangeCalc.cpp b/llvm/lib/CodeGen/LiveRangeCalc.cpp index 281cf1f..9f6262b 100644 --- a/llvm/lib/CodeGen/LiveRangeCalc.cpp +++ b/llvm/lib/CodeGen/LiveRangeCalc.cpp @@ -361,14 +361,14 @@ bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, MachineBasicBlock *MBB = MF->getBlockNumbered(WorkList[i]); #ifndef NDEBUG - if (Undefs.size() > 0 && MBB->pred_empty()) { + if (MBB->pred_empty()) { MBB->getParent()->verify(); errs() << "Use of " << PrintReg(PhysReg) << " does not have a corresponding definition on every path:\n"; const MachineInstr *MI = Indexes->getInstructionFromIndex(Use); if (MI != nullptr) errs() << Use << " " << *MI; - llvm_unreachable("Use not jointly dominated by defs."); + report_fatal_error("Use not jointly dominated by defs."); } if (TargetRegisterInfo::isPhysicalRegister(PhysReg) && @@ -378,7 +378,7 @@ bool LiveRangeCalc::findReachingDefs(LiveRange &LR, MachineBasicBlock &UseMBB, errs() << "The register " << PrintReg(PhysReg, TRI) << " needs to be live in to BB#" << MBB->getNumber() << ", but is missing from the live-in list.\n"; - llvm_unreachable("Invalid global physical register"); + report_fatal_error("Invalid global physical register"); } #endif FoundUndef |= MBB->pred_empty(); diff --git a/llvm/test/CodeGen/X86/invalid-liveness.mir b/llvm/test/CodeGen/X86/invalid-liveness.mir new file mode 100644 index 0000000..ca86247 --- /dev/null +++ b/llvm/test/CodeGen/X86/invalid-liveness.mir @@ -0,0 +1,31 @@ +# RUN: not llc -march=x86 -run-pass liveintervals -o - %s 2>&1 | FileCheck %s +# REQUIRES: asserts + +--- | + define void @func() { ret void } +... +--- +# Liveness calculation should detect that we do not have a definition for vreg0 +# on all paths; In this example a def for vreg0 is missing when jumping from +# bb.0 to bb.3. +# +# CHECK: Use of %vreg0 does not have a corresponding definition on every path +# CHECK: ERROR: Use not jointly dominated by defs. +name: func +registers: + - { id: 0, class: gr32 } +body: | + bb.0: + successors: %bb.2, %bb.3 + JG_1 %bb.2, implicit %eflags + JMP_1 %bb.3 + + bb.2: + successors: %bb.3 + %0 = IMPLICIT_DEF + JMP_1 %bb.3 + + bb.3: + %eax = COPY %0 + RETQ %eax +... -- 2.7.4