aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/MachineVerifier.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/CodeGen/MachineVerifier.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/CodeGen/MachineVerifier.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineVerifier.cpp93
1 files changed, 57 insertions, 36 deletions
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 969743edca52..6c0402df8489 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -59,6 +59,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/InitializePasses.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrDesc.h"
@@ -123,8 +124,8 @@ namespace {
void addRegWithSubRegs(RegVector &RV, unsigned Reg) {
RV.push_back(Reg);
if (Register::isPhysicalRegister(Reg))
- for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid(); ++SubRegs)
- RV.push_back(*SubRegs);
+ for (const MCPhysReg &SubReg : TRI->subregs(Reg))
+ RV.push_back(SubReg);
}
struct BBInfo {
@@ -801,18 +802,16 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
report("MBB live-in list contains non-physical register", MBB);
continue;
}
- for (MCSubRegIterator SubRegs(LI.PhysReg, TRI, /*IncludeSelf=*/true);
- SubRegs.isValid(); ++SubRegs)
- regsLive.insert(*SubRegs);
+ for (const MCPhysReg &SubReg : TRI->subregs_inclusive(LI.PhysReg))
+ regsLive.insert(SubReg);
}
}
const MachineFrameInfo &MFI = MF->getFrameInfo();
BitVector PR = MFI.getPristineRegs(*MF);
for (unsigned I : PR.set_bits()) {
- for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
- SubRegs.isValid(); ++SubRegs)
- regsLive.insert(*SubRegs);
+ for (const MCPhysReg &SubReg : TRI->subregs_inclusive(I))
+ regsLive.insert(SubReg);
}
regsKilled.clear();
@@ -1100,7 +1099,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
break;
}
- case TargetOpcode::G_GEP: {
+ case TargetOpcode::G_PTR_ADD: {
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT PtrTy = MRI->getType(MI->getOperand(1).getReg());
LLT OffsetTy = MRI->getType(MI->getOperand(2).getReg());
@@ -1408,18 +1407,6 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
break;
}
- const Constant *Mask = MaskOp.getShuffleMask();
- auto *MaskVT = dyn_cast<VectorType>(Mask->getType());
- if (!MaskVT || !MaskVT->getElementType()->isIntegerTy(32)) {
- report("Invalid shufflemask constant type", MI);
- break;
- }
-
- if (!Mask->getAggregateElement(0u)) {
- report("Invalid shufflemask constant type", MI);
- break;
- }
-
LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
LLT Src0Ty = MRI->getType(MI->getOperand(1).getReg());
LLT Src1Ty = MRI->getType(MI->getOperand(2).getReg());
@@ -1435,8 +1422,7 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
int SrcNumElts = Src0Ty.isVector() ? Src0Ty.getNumElements() : 1;
int DstNumElts = DstTy.isVector() ? DstTy.getNumElements() : 1;
- SmallVector<int, 32> MaskIdxes;
- ShuffleVectorInst::getShuffleMask(Mask, MaskIdxes);
+ ArrayRef<int> MaskIdxes = MaskOp.getShuffleMask();
if (static_cast<int>(MaskIdxes.size()) != DstNumElts)
report("Wrong result type for shufflemask", MI);
@@ -1609,13 +1595,23 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
} else if (MONum < MCID.getNumOperands()) {
const MCOperandInfo &MCOI = MCID.OpInfo[MONum];
// Don't check if it's the last operand in a variadic instruction. See,
- // e.g., LDM_RET in the arm back end.
- if (MO->isReg() &&
- !(MI->isVariadic() && MONum == MCID.getNumOperands()-1)) {
- if (MO->isDef() && !MCOI.isOptionalDef())
- report("Explicit operand marked as def", MO, MONum);
- if (MO->isImplicit())
- report("Explicit operand marked as implicit", MO, MONum);
+ // e.g., LDM_RET in the arm back end. Check non-variadic operands only.
+ bool IsOptional = MI->isVariadic() && MONum == MCID.getNumOperands() - 1;
+ if (!IsOptional) {
+ if (MO->isReg()) {
+ if (MO->isDef() && !MCOI.isOptionalDef())
+ report("Explicit operand marked as def", MO, MONum);
+ if (MO->isImplicit())
+ report("Explicit operand marked as implicit", MO, MONum);
+ }
+
+ // Check that an instruction has register operands only as expected.
+ if (MCOI.OperandType == MCOI::OPERAND_REGISTER &&
+ !MO->isReg() && !MO->isFI())
+ report("Expected a register operand.", MO, MONum);
+ if ((MCOI.OperandType == MCOI::OPERAND_IMMEDIATE ||
+ MCOI.OperandType == MCOI::OPERAND_PCREL) && MO->isReg())
+ report("Expected a non-register operand.", MO, MONum);
}
int TiedTo = MCID.getOperandConstraint(MONum, MCOI::TIED_TO);
@@ -2005,9 +2001,9 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
bool Bad = !isReserved(Reg);
// We are fine if just any subregister has a defined value.
if (Bad) {
- for (MCSubRegIterator SubRegs(Reg, TRI); SubRegs.isValid();
- ++SubRegs) {
- if (regsLive.count(*SubRegs)) {
+
+ for (const MCPhysReg &SubReg : TRI->subregs(Reg)) {
+ if (regsLive.count(SubReg)) {
Bad = false;
break;
}
@@ -2025,9 +2021,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (!Register::isPhysicalRegister(MOP.getReg()))
continue;
- for (MCSubRegIterator SubRegs(MOP.getReg(), TRI); SubRegs.isValid();
- ++SubRegs) {
- if (*SubRegs == Reg) {
+ for (const MCPhysReg &SubReg : TRI->subregs(MOP.getReg())) {
+ if (SubReg == Reg) {
Bad = false;
break;
}
@@ -2304,6 +2299,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);