1044eb2f6SDimitry Andric //===- MachineVerifier.cpp - Machine Code Verifier ------------------------===//
2009b1c42SEd Schouten //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6009b1c42SEd Schouten //
7009b1c42SEd Schouten //===----------------------------------------------------------------------===//
8009b1c42SEd Schouten //
9009b1c42SEd Schouten // Pass to verify generated machine code. The following is checked:
10009b1c42SEd Schouten //
11009b1c42SEd Schouten // Operand counts: All explicit operands must be present.
12009b1c42SEd Schouten //
13009b1c42SEd Schouten // Register classes: All physical and virtual register operands must be
14009b1c42SEd Schouten // compatible with the register class required by the instruction descriptor.
15009b1c42SEd Schouten //
16009b1c42SEd Schouten // Register live intervals: Registers must be defined only once, and must be
17009b1c42SEd Schouten // defined before use.
18009b1c42SEd Schouten //
19cfca06d7SDimitry Andric // The machine code verifier is enabled with the command-line option
20cfca06d7SDimitry Andric // -verify-machineinstrs.
21009b1c42SEd Schouten //===----------------------------------------------------------------------===//
22009b1c42SEd Schouten
23ac9a064cSDimitry Andric #include "llvm/CodeGen/MachineVerifier.h"
24044eb2f6SDimitry Andric #include "llvm/ADT/BitVector.h"
25044eb2f6SDimitry Andric #include "llvm/ADT/DenseMap.h"
2659850d08SRoman Divacky #include "llvm/ADT/DenseSet.h"
27f8af5cf6SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
28cfca06d7SDimitry Andric #include "llvm/ADT/PostOrderIterator.h"
29044eb2f6SDimitry Andric #include "llvm/ADT/STLExtras.h"
3059850d08SRoman Divacky #include "llvm/ADT/SetOperations.h"
31044eb2f6SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
3259850d08SRoman Divacky #include "llvm/ADT/SmallVector.h"
33044eb2f6SDimitry Andric #include "llvm/ADT/StringRef.h"
34044eb2f6SDimitry Andric #include "llvm/ADT/Twine.h"
35145449b1SDimitry Andric #include "llvm/CodeGen/CodeGenCommonISel.h"
36b1c73532SDimitry Andric #include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
37044eb2f6SDimitry Andric #include "llvm/CodeGen/LiveInterval.h"
38044eb2f6SDimitry Andric #include "llvm/CodeGen/LiveIntervals.h"
39145449b1SDimitry Andric #include "llvm/CodeGen/LiveRangeCalc.h"
40c7dac04cSDimitry Andric #include "llvm/CodeGen/LiveStacks.h"
414a16efa3SDimitry Andric #include "llvm/CodeGen/LiveVariables.h"
42044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
43ac9a064cSDimitry Andric #include "llvm/CodeGen/MachineConvergenceVerifier.h"
44ac9a064cSDimitry Andric #include "llvm/CodeGen/MachineDominators.h"
454a16efa3SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
46044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
474a16efa3SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
48044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
49044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineInstrBundle.h"
504a16efa3SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
51044eb2f6SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
524a16efa3SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
53044eb2f6SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
54145449b1SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
55145449b1SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
56044eb2f6SDimitry Andric #include "llvm/CodeGen/SlotIndexes.h"
57d288ef4cSDimitry Andric #include "llvm/CodeGen/StackMaps.h"
58044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
59ac9a064cSDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
60044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetOpcodes.h"
61044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
62044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
63ac9a064cSDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
644a16efa3SDimitry Andric #include "llvm/IR/BasicBlock.h"
65145449b1SDimitry Andric #include "llvm/IR/Constants.h"
667fa27ce4SDimitry Andric #include "llvm/IR/EHPersonalities.h"
67044eb2f6SDimitry Andric #include "llvm/IR/Function.h"
684a16efa3SDimitry Andric #include "llvm/IR/InlineAsm.h"
694a16efa3SDimitry Andric #include "llvm/IR/Instructions.h"
70706b4fc4SDimitry Andric #include "llvm/InitializePasses.h"
71044eb2f6SDimitry Andric #include "llvm/MC/LaneBitmask.h"
724a16efa3SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
73145449b1SDimitry Andric #include "llvm/MC/MCDwarf.h"
74044eb2f6SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
75044eb2f6SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
76044eb2f6SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
77044eb2f6SDimitry Andric #include "llvm/Pass.h"
78044eb2f6SDimitry Andric #include "llvm/Support/Casting.h"
7959850d08SRoman Divacky #include "llvm/Support/ErrorHandling.h"
80044eb2f6SDimitry Andric #include "llvm/Support/MathExtras.h"
81e3b55780SDimitry Andric #include "llvm/Support/ModRef.h"
8259850d08SRoman Divacky #include "llvm/Support/raw_ostream.h"
834a16efa3SDimitry Andric #include "llvm/Target/TargetMachine.h"
84044eb2f6SDimitry Andric #include <algorithm>
85044eb2f6SDimitry Andric #include <cassert>
86044eb2f6SDimitry Andric #include <cstddef>
87044eb2f6SDimitry Andric #include <cstdint>
88044eb2f6SDimitry Andric #include <iterator>
89044eb2f6SDimitry Andric #include <string>
90044eb2f6SDimitry Andric #include <utility>
91044eb2f6SDimitry Andric
92009b1c42SEd Schouten using namespace llvm;
93009b1c42SEd Schouten
94009b1c42SEd Schouten namespace {
95009b1c42SEd Schouten
96044eb2f6SDimitry Andric struct MachineVerifier {
MachineVerifier__anon3a9898fa0111::MachineVerifier97ac9a064cSDimitry Andric MachineVerifier(MachineFunctionAnalysisManager &MFAM, const char *b)
98ac9a064cSDimitry Andric : MFAM(&MFAM), Banner(b) {}
99ac9a064cSDimitry Andric
MachineVerifier__anon3a9898fa0111::MachineVerifier100044eb2f6SDimitry Andric MachineVerifier(Pass *pass, const char *b) : PASS(pass), Banner(b) {}
101009b1c42SEd Schouten
MachineVerifier__anon3a9898fa0111::MachineVerifier102b1c73532SDimitry Andric MachineVerifier(const char *b, LiveVariables *LiveVars,
103b1c73532SDimitry Andric LiveIntervals *LiveInts, LiveStacks *LiveStks,
104b1c73532SDimitry Andric SlotIndexes *Indexes)
105b1c73532SDimitry Andric : Banner(b), LiveVars(LiveVars), LiveInts(LiveInts), LiveStks(LiveStks),
106b1c73532SDimitry Andric Indexes(Indexes) {}
107b1c73532SDimitry Andric
108b60736ecSDimitry Andric unsigned verify(const MachineFunction &MF);
109009b1c42SEd Schouten
110ac9a064cSDimitry Andric MachineFunctionAnalysisManager *MFAM = nullptr;
111b1c73532SDimitry Andric Pass *const PASS = nullptr;
112cf099d11SDimitry Andric const char *Banner;
1137fa27ce4SDimitry Andric const MachineFunction *MF = nullptr;
1147fa27ce4SDimitry Andric const TargetMachine *TM = nullptr;
1157fa27ce4SDimitry Andric const TargetInstrInfo *TII = nullptr;
1167fa27ce4SDimitry Andric const TargetRegisterInfo *TRI = nullptr;
1177fa27ce4SDimitry Andric const MachineRegisterInfo *MRI = nullptr;
1187fa27ce4SDimitry Andric const RegisterBankInfo *RBI = nullptr;
119009b1c42SEd Schouten
1207fa27ce4SDimitry Andric unsigned foundErrors = 0;
121009b1c42SEd Schouten
122b915e9e0SDimitry Andric // Avoid querying the MachineFunctionProperties for each operand.
1237fa27ce4SDimitry Andric bool isFunctionRegBankSelected = false;
1247fa27ce4SDimitry Andric bool isFunctionSelected = false;
1257fa27ce4SDimitry Andric bool isFunctionTracksDebugUserValues = false;
126b915e9e0SDimitry Andric
127b60736ecSDimitry Andric using RegVector = SmallVector<Register, 16>;
128044eb2f6SDimitry Andric using RegMaskVector = SmallVector<const uint32_t *, 4>;
129b60736ecSDimitry Andric using RegSet = DenseSet<Register>;
130b60736ecSDimitry Andric using RegMap = DenseMap<Register, const MachineInstr *>;
131044eb2f6SDimitry Andric using BlockSet = SmallPtrSet<const MachineBasicBlock *, 8>;
132009b1c42SEd Schouten
1337fa27ce4SDimitry Andric const MachineInstr *FirstNonPHI = nullptr;
1347fa27ce4SDimitry Andric const MachineInstr *FirstTerminator = nullptr;
135522600a2SDimitry Andric BlockSet FunctionBlocks;
13630815c53SDimitry Andric
137009b1c42SEd Schouten BitVector regsReserved;
138009b1c42SEd Schouten RegSet regsLive;
13959850d08SRoman Divacky RegVector regsDefined, regsDead, regsKilled;
14063faed5bSDimitry Andric RegMaskVector regMasks;
141009b1c42SEd Schouten
142cf099d11SDimitry Andric SlotIndex lastIndex;
143cf099d11SDimitry Andric
144009b1c42SEd Schouten // Add Reg and any sub-registers to RV
addRegWithSubRegs__anon3a9898fa0111::MachineVerifier145b60736ecSDimitry Andric void addRegWithSubRegs(RegVector &RV, Register Reg) {
146009b1c42SEd Schouten RV.push_back(Reg);
147b60736ecSDimitry Andric if (Reg.isPhysical())
148b60736ecSDimitry Andric append_range(RV, TRI->subregs(Reg.asMCReg()));
149009b1c42SEd Schouten }
150009b1c42SEd Schouten
151009b1c42SEd Schouten struct BBInfo {
152009b1c42SEd Schouten // Is this MBB reachable from the MF entry point?
153044eb2f6SDimitry Andric bool reachable = false;
154009b1c42SEd Schouten
155009b1c42SEd Schouten // Vregs that must be live in because they are used without being
156b60736ecSDimitry Andric // defined. Map value is the user. vregsLiveIn doesn't include regs
157b60736ecSDimitry Andric // that only are used by PHI nodes.
158009b1c42SEd Schouten RegMap vregsLiveIn;
159009b1c42SEd Schouten
160009b1c42SEd Schouten // Regs killed in MBB. They may be defined again, and will then be in both
161009b1c42SEd Schouten // regsKilled and regsLiveOut.
162009b1c42SEd Schouten RegSet regsKilled;
163009b1c42SEd Schouten
164009b1c42SEd Schouten // Regs defined in MBB and live out. Note that vregs passing through may
165009b1c42SEd Schouten // be live out without being mentioned here.
166009b1c42SEd Schouten RegSet regsLiveOut;
167009b1c42SEd Schouten
168009b1c42SEd Schouten // Vregs that pass through MBB untouched. This set is disjoint from
169009b1c42SEd Schouten // regsKilled and regsLiveOut.
170009b1c42SEd Schouten RegSet vregsPassed;
171009b1c42SEd Schouten
1727d453863SRoman Divacky // Vregs that must pass through MBB because they are needed by a successor
1737d453863SRoman Divacky // block. This set is disjoint from regsLiveOut.
1747d453863SRoman Divacky RegSet vregsRequired;
1757d453863SRoman Divacky
176522600a2SDimitry Andric // Set versions of block's predecessor and successor lists.
177522600a2SDimitry Andric BlockSet Preds, Succs;
178522600a2SDimitry Andric
179044eb2f6SDimitry Andric BBInfo() = default;
180009b1c42SEd Schouten
1817d453863SRoman Divacky // Add register to vregsRequired if it belongs there. Return true if
1827d453863SRoman Divacky // anything changed.
addRequired__anon3a9898fa0111::MachineVerifier::BBInfo183b60736ecSDimitry Andric bool addRequired(Register Reg) {
184b60736ecSDimitry Andric if (!Reg.isVirtual())
1857d453863SRoman Divacky return false;
1867d453863SRoman Divacky if (regsLiveOut.count(Reg))
1877d453863SRoman Divacky return false;
1887d453863SRoman Divacky return vregsRequired.insert(Reg).second;
1897d453863SRoman Divacky }
1907d453863SRoman Divacky
1917d453863SRoman Divacky // Same for a full set.
addRequired__anon3a9898fa0111::MachineVerifier::BBInfo1927d453863SRoman Divacky bool addRequired(const RegSet &RS) {
193cfca06d7SDimitry Andric bool Changed = false;
194b60736ecSDimitry Andric for (Register Reg : RS)
195cfca06d7SDimitry Andric Changed |= addRequired(Reg);
196cfca06d7SDimitry Andric return Changed;
1977d453863SRoman Divacky }
1987d453863SRoman Divacky
1997d453863SRoman Divacky // Same for a full map.
addRequired__anon3a9898fa0111::MachineVerifier::BBInfo2007d453863SRoman Divacky bool addRequired(const RegMap &RM) {
201cfca06d7SDimitry Andric bool Changed = false;
202cfca06d7SDimitry Andric for (const auto &I : RM)
203cfca06d7SDimitry Andric Changed |= addRequired(I.first);
204cfca06d7SDimitry Andric return Changed;
2057d453863SRoman Divacky }
2067d453863SRoman Divacky
207009b1c42SEd Schouten // Live-out registers are either in regsLiveOut or vregsPassed.
isLiveOut__anon3a9898fa0111::MachineVerifier::BBInfo208b60736ecSDimitry Andric bool isLiveOut(Register Reg) const {
209009b1c42SEd Schouten return regsLiveOut.count(Reg) || vregsPassed.count(Reg);
210009b1c42SEd Schouten }
211009b1c42SEd Schouten };
212009b1c42SEd Schouten
213009b1c42SEd Schouten // Extra register info per MBB.
214009b1c42SEd Schouten DenseMap<const MachineBasicBlock*, BBInfo> MBBInfoMap;
215009b1c42SEd Schouten
isReserved__anon3a9898fa0111::MachineVerifier216b60736ecSDimitry Andric bool isReserved(Register Reg) {
217b60736ecSDimitry Andric return Reg.id() < regsReserved.size() && regsReserved.test(Reg.id());
218009b1c42SEd Schouten }
219009b1c42SEd Schouten
isAllocatable__anon3a9898fa0111::MachineVerifier220b60736ecSDimitry Andric bool isAllocatable(Register Reg) const {
221b60736ecSDimitry Andric return Reg.id() < TRI->getNumRegs() && TRI->isInAllocatableClass(Reg) &&
222b60736ecSDimitry Andric !regsReserved.test(Reg.id());
22363faed5bSDimitry Andric }
22463faed5bSDimitry Andric
2257d453863SRoman Divacky // Analysis information if available
2267fa27ce4SDimitry Andric LiveVariables *LiveVars = nullptr;
2277fa27ce4SDimitry Andric LiveIntervals *LiveInts = nullptr;
2287fa27ce4SDimitry Andric LiveStacks *LiveStks = nullptr;
2297fa27ce4SDimitry Andric SlotIndexes *Indexes = nullptr;
2307d453863SRoman Divacky
231ac9a064cSDimitry Andric // This is calculated only when trying to verify convergence control tokens.
232ac9a064cSDimitry Andric // Similar to the LLVM IR verifier, we calculate this locally instead of
233ac9a064cSDimitry Andric // relying on the pass manager.
234ac9a064cSDimitry Andric MachineDominatorTree DT;
235ac9a064cSDimitry Andric
236009b1c42SEd Schouten void visitMachineFunctionBefore();
237009b1c42SEd Schouten void visitMachineBasicBlockBefore(const MachineBasicBlock *MBB);
23858b69754SDimitry Andric void visitMachineBundleBefore(const MachineInstr *MI);
239e6d15924SDimitry Andric
240c0981da4SDimitry Andric /// Verify that all of \p MI's virtual register operands are scalars.
241c0981da4SDimitry Andric /// \returns True if all virtual register operands are scalar. False
242c0981da4SDimitry Andric /// otherwise.
243c0981da4SDimitry Andric bool verifyAllRegOpsScalar(const MachineInstr &MI,
244c0981da4SDimitry Andric const MachineRegisterInfo &MRI);
245e6d15924SDimitry Andric bool verifyVectorElementMatch(LLT Ty0, LLT Ty1, const MachineInstr *MI);
246b1c73532SDimitry Andric
247b1c73532SDimitry Andric bool verifyGIntrinsicSideEffects(const MachineInstr *MI);
248b1c73532SDimitry Andric bool verifyGIntrinsicConvergence(const MachineInstr *MI);
249e6d15924SDimitry Andric void verifyPreISelGenericInstruction(const MachineInstr *MI);
250b1c73532SDimitry Andric
251009b1c42SEd Schouten void visitMachineInstrBefore(const MachineInstr *MI);
252009b1c42SEd Schouten void visitMachineOperand(const MachineOperand *MO, unsigned MONum);
25358b69754SDimitry Andric void visitMachineBundleAfter(const MachineInstr *MI);
254009b1c42SEd Schouten void visitMachineBasicBlockAfter(const MachineBasicBlock *MBB);
255009b1c42SEd Schouten void visitMachineFunctionAfter();
256009b1c42SEd Schouten
257009b1c42SEd Schouten void report(const char *msg, const MachineFunction *MF);
258009b1c42SEd Schouten void report(const char *msg, const MachineBasicBlock *MBB);
259009b1c42SEd Schouten void report(const char *msg, const MachineInstr *MI);
260eb11fae6SDimitry Andric void report(const char *msg, const MachineOperand *MO, unsigned MONum,
261eb11fae6SDimitry Andric LLT MOVRegType = LLT{});
262344a3780SDimitry Andric void report(const Twine &Msg, const MachineInstr *MI);
263dd58ef01SDimitry Andric
264dd58ef01SDimitry Andric void report_context(const LiveInterval &LI) const;
265b60736ecSDimitry Andric void report_context(const LiveRange &LR, Register VRegUnit,
266dd58ef01SDimitry Andric LaneBitmask LaneMask) const;
267dd58ef01SDimitry Andric void report_context(const LiveRange::Segment &S) const;
268dd58ef01SDimitry Andric void report_context(const VNInfo &VNI) const;
26901095a5dSDimitry Andric void report_context(SlotIndex Pos) const;
270d8e91e46SDimitry Andric void report_context(MCPhysReg PhysReg) const;
27101095a5dSDimitry Andric void report_context_liverange(const LiveRange &LR) const;
27201095a5dSDimitry Andric void report_context_lanemask(LaneBitmask LaneMask) const;
273b60736ecSDimitry Andric void report_context_vreg(Register VReg) const;
274b60736ecSDimitry Andric void report_context_vreg_regunit(Register VRegOrUnit) const;
275009b1c42SEd Schouten
276522600a2SDimitry Andric void verifyInlineAsm(const MachineInstr *MI);
277522600a2SDimitry Andric
27863faed5bSDimitry Andric void checkLiveness(const MachineOperand *MO, unsigned MONum);
27901095a5dSDimitry Andric void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
280b60736ecSDimitry Andric SlotIndex UseIdx, const LiveRange &LR,
281b60736ecSDimitry Andric Register VRegOrUnit,
282b915e9e0SDimitry Andric LaneBitmask LaneMask = LaneBitmask::getNone());
28301095a5dSDimitry Andric void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
284b60736ecSDimitry Andric SlotIndex DefIdx, const LiveRange &LR,
285b60736ecSDimitry Andric Register VRegOrUnit, bool SubRangeCheck = false,
286b915e9e0SDimitry Andric LaneBitmask LaneMask = LaneBitmask::getNone());
28701095a5dSDimitry Andric
288009b1c42SEd Schouten void markReachable(const MachineBasicBlock *MBB);
289829000e0SRoman Divacky void calcRegsPassed();
290044eb2f6SDimitry Andric void checkPHIOps(const MachineBasicBlock &MBB);
2917d453863SRoman Divacky
2927d453863SRoman Divacky void calcRegsRequired();
2937d453863SRoman Divacky void verifyLiveVariables();
294d39c594dSDimitry Andric void verifyLiveIntervals();
29558b69754SDimitry Andric void verifyLiveInterval(const LiveInterval&);
296b60736ecSDimitry Andric void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
297b915e9e0SDimitry Andric LaneBitmask);
298f8af5cf6SDimitry Andric void verifyLiveRangeSegment(const LiveRange &,
299b60736ecSDimitry Andric const LiveRange::const_iterator I, Register,
300b915e9e0SDimitry Andric LaneBitmask);
301b60736ecSDimitry Andric void verifyLiveRange(const LiveRange &, Register,
302b915e9e0SDimitry Andric LaneBitmask LaneMask = LaneBitmask::getNone());
303f8af5cf6SDimitry Andric
304f8af5cf6SDimitry Andric void verifyStackFrame();
305dd58ef01SDimitry Andric
306dd58ef01SDimitry Andric void verifySlotIndexes() const;
30701095a5dSDimitry Andric void verifyProperties(const MachineFunction &MF);
308009b1c42SEd Schouten };
3097d453863SRoman Divacky
310ac9a064cSDimitry Andric struct MachineVerifierLegacyPass : public MachineFunctionPass {
3117d453863SRoman Divacky static char ID; // Pass ID, replacement for typeid
312044eb2f6SDimitry Andric
31367c32a98SDimitry Andric const std::string Banner;
3147d453863SRoman Divacky
MachineVerifierLegacyPass__anon3a9898fa0111::MachineVerifierLegacyPass315ac9a064cSDimitry Andric MachineVerifierLegacyPass(std::string banner = std::string())
31671d5a254SDimitry Andric : MachineFunctionPass(ID), Banner(std::move(banner)) {
317ac9a064cSDimitry Andric initializeMachineVerifierLegacyPassPass(*PassRegistry::getPassRegistry());
318cf099d11SDimitry Andric }
3197d453863SRoman Divacky
getAnalysisUsage__anon3a9898fa0111::MachineVerifierLegacyPass3205ca98fd9SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
3211f917f69SDimitry Andric AU.addUsedIfAvailable<LiveStacks>();
322ac9a064cSDimitry Andric AU.addUsedIfAvailable<LiveVariablesWrapperPass>();
323ac9a064cSDimitry Andric AU.addUsedIfAvailable<SlotIndexesWrapperPass>();
324ac9a064cSDimitry Andric AU.addUsedIfAvailable<LiveIntervalsWrapperPass>();
3257d453863SRoman Divacky AU.setPreservesAll();
3267d453863SRoman Divacky MachineFunctionPass::getAnalysisUsage(AU);
327009b1c42SEd Schouten }
328009b1c42SEd Schouten
runOnMachineFunction__anon3a9898fa0111::MachineVerifierLegacyPass3295ca98fd9SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override {
330c0981da4SDimitry Andric // Skip functions that have known verification problems.
331c0981da4SDimitry Andric // FIXME: Remove this mechanism when all problematic passes have been
332c0981da4SDimitry Andric // fixed.
333c0981da4SDimitry Andric if (MF.getProperties().hasProperty(
334c0981da4SDimitry Andric MachineFunctionProperties::Property::FailsVerification))
335c0981da4SDimitry Andric return false;
336c0981da4SDimitry Andric
33701095a5dSDimitry Andric unsigned FoundErrors = MachineVerifier(this, Banner.c_str()).verify(MF);
33801095a5dSDimitry Andric if (FoundErrors)
33901095a5dSDimitry Andric report_fatal_error("Found "+Twine(FoundErrors)+" machine code errors.");
3407d453863SRoman Divacky return false;
3417d453863SRoman Divacky }
3427d453863SRoman Divacky };
3437d453863SRoman Divacky
344044eb2f6SDimitry Andric } // end anonymous namespace
3457d453863SRoman Divacky
346ac9a064cSDimitry Andric PreservedAnalyses
run(MachineFunction & MF,MachineFunctionAnalysisManager & MFAM)347ac9a064cSDimitry Andric MachineVerifierPass::run(MachineFunction &MF,
348ac9a064cSDimitry Andric MachineFunctionAnalysisManager &MFAM) {
349ac9a064cSDimitry Andric // Skip functions that have known verification problems.
350ac9a064cSDimitry Andric // FIXME: Remove this mechanism when all problematic passes have been
351ac9a064cSDimitry Andric // fixed.
352ac9a064cSDimitry Andric if (MF.getProperties().hasProperty(
353ac9a064cSDimitry Andric MachineFunctionProperties::Property::FailsVerification))
354ac9a064cSDimitry Andric return PreservedAnalyses::all();
355ac9a064cSDimitry Andric unsigned FoundErrors = MachineVerifier(MFAM, Banner.c_str()).verify(MF);
356ac9a064cSDimitry Andric if (FoundErrors)
357ac9a064cSDimitry Andric report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
358ac9a064cSDimitry Andric return PreservedAnalyses::all();
359ac9a064cSDimitry Andric }
360044eb2f6SDimitry Andric
361ac9a064cSDimitry Andric char MachineVerifierLegacyPass::ID = 0;
362ac9a064cSDimitry Andric
363ac9a064cSDimitry Andric INITIALIZE_PASS(MachineVerifierLegacyPass, "machineverifier",
364cf099d11SDimitry Andric "Verify generated machine code", false, false)
365009b1c42SEd Schouten
createMachineVerifierPass(const std::string & Banner)36667c32a98SDimitry Andric FunctionPass *llvm::createMachineVerifierPass(const std::string &Banner) {
367ac9a064cSDimitry Andric return new MachineVerifierLegacyPass(Banner);
368009b1c42SEd Schouten }
369009b1c42SEd Schouten
verifyMachineFunction(const std::string & Banner,const MachineFunction & MF)370ac9a064cSDimitry Andric void llvm::verifyMachineFunction(const std::string &Banner,
371b60736ecSDimitry Andric const MachineFunction &MF) {
372b60736ecSDimitry Andric // TODO: Use MFAM after porting below analyses.
373b60736ecSDimitry Andric // LiveVariables *LiveVars;
374b60736ecSDimitry Andric // LiveIntervals *LiveInts;
375b60736ecSDimitry Andric // LiveStacks *LiveStks;
376b60736ecSDimitry Andric // SlotIndexes *Indexes;
377b60736ecSDimitry Andric unsigned FoundErrors = MachineVerifier(nullptr, Banner.c_str()).verify(MF);
378b60736ecSDimitry Andric if (FoundErrors)
379b60736ecSDimitry Andric report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
380b60736ecSDimitry Andric }
381b60736ecSDimitry Andric
verify(Pass * p,const char * Banner,bool AbortOnErrors) const38201095a5dSDimitry Andric bool MachineFunction::verify(Pass *p, const char *Banner, bool AbortOnErrors)
38301095a5dSDimitry Andric const {
38401095a5dSDimitry Andric MachineFunction &MF = const_cast<MachineFunction&>(*this);
38501095a5dSDimitry Andric unsigned FoundErrors = MachineVerifier(p, Banner).verify(MF);
38601095a5dSDimitry Andric if (AbortOnErrors && FoundErrors)
38701095a5dSDimitry Andric report_fatal_error("Found "+Twine(FoundErrors)+" machine code errors.");
38801095a5dSDimitry Andric return FoundErrors == 0;
389907da171SRoman Divacky }
390907da171SRoman Divacky
verify(LiveIntervals * LiveInts,SlotIndexes * Indexes,const char * Banner,bool AbortOnErrors) const391b1c73532SDimitry Andric bool MachineFunction::verify(LiveIntervals *LiveInts, SlotIndexes *Indexes,
392b1c73532SDimitry Andric const char *Banner, bool AbortOnErrors) const {
393b1c73532SDimitry Andric MachineFunction &MF = const_cast<MachineFunction &>(*this);
394b1c73532SDimitry Andric unsigned FoundErrors =
395b1c73532SDimitry Andric MachineVerifier(Banner, nullptr, LiveInts, nullptr, Indexes).verify(MF);
396b1c73532SDimitry Andric if (AbortOnErrors && FoundErrors)
397b1c73532SDimitry Andric report_fatal_error("Found " + Twine(FoundErrors) + " machine code errors.");
398b1c73532SDimitry Andric return FoundErrors == 0;
399b1c73532SDimitry Andric }
400b1c73532SDimitry Andric
verifySlotIndexes() const401dd58ef01SDimitry Andric void MachineVerifier::verifySlotIndexes() const {
402dd58ef01SDimitry Andric if (Indexes == nullptr)
403dd58ef01SDimitry Andric return;
404dd58ef01SDimitry Andric
405dd58ef01SDimitry Andric // Ensure the IdxMBB list is sorted by slot indexes.
406dd58ef01SDimitry Andric SlotIndex Last;
407dd58ef01SDimitry Andric for (SlotIndexes::MBBIndexIterator I = Indexes->MBBIndexBegin(),
408dd58ef01SDimitry Andric E = Indexes->MBBIndexEnd(); I != E; ++I) {
409dd58ef01SDimitry Andric assert(!Last.isValid() || I->first > Last);
410dd58ef01SDimitry Andric Last = I->first;
411dd58ef01SDimitry Andric }
412dd58ef01SDimitry Andric }
413dd58ef01SDimitry Andric
verifyProperties(const MachineFunction & MF)41401095a5dSDimitry Andric void MachineVerifier::verifyProperties(const MachineFunction &MF) {
41501095a5dSDimitry Andric // If a pass has introduced virtual registers without clearing the
416b915e9e0SDimitry Andric // NoVRegs property (or set it without allocating the vregs)
41701095a5dSDimitry Andric // then report an error.
41801095a5dSDimitry Andric if (MF.getProperties().hasProperty(
419b915e9e0SDimitry Andric MachineFunctionProperties::Property::NoVRegs) &&
420b915e9e0SDimitry Andric MRI->getNumVirtRegs())
421b915e9e0SDimitry Andric report("Function has NoVRegs property but there are VReg operands", &MF);
42201095a5dSDimitry Andric }
42301095a5dSDimitry Andric
verify(const MachineFunction & MF)424b60736ecSDimitry Andric unsigned MachineVerifier::verify(const MachineFunction &MF) {
425009b1c42SEd Schouten foundErrors = 0;
426009b1c42SEd Schouten
427009b1c42SEd Schouten this->MF = &MF;
428009b1c42SEd Schouten TM = &MF.getTarget();
42967c32a98SDimitry Andric TII = MF.getSubtarget().getInstrInfo();
43067c32a98SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo();
431145449b1SDimitry Andric RBI = MF.getSubtarget().getRegBankInfo();
432009b1c42SEd Schouten MRI = &MF.getRegInfo();
433009b1c42SEd Schouten
434eb11fae6SDimitry Andric const bool isFunctionFailedISel = MF.getProperties().hasProperty(
435eb11fae6SDimitry Andric MachineFunctionProperties::Property::FailedISel);
436d8e91e46SDimitry Andric
437d8e91e46SDimitry Andric // If we're mid-GlobalISel and we already triggered the fallback path then
438d8e91e46SDimitry Andric // it's expected that the MIR is somewhat broken but that's ok since we'll
439d8e91e46SDimitry Andric // reset it and clear the FailedISel attribute in ResetMachineFunctions.
440d8e91e46SDimitry Andric if (isFunctionFailedISel)
441d8e91e46SDimitry Andric return foundErrors;
442d8e91e46SDimitry Andric
443cfca06d7SDimitry Andric isFunctionRegBankSelected = MF.getProperties().hasProperty(
444b915e9e0SDimitry Andric MachineFunctionProperties::Property::RegBankSelected);
445cfca06d7SDimitry Andric isFunctionSelected = MF.getProperties().hasProperty(
446b915e9e0SDimitry Andric MachineFunctionProperties::Property::Selected);
44777fc4c14SDimitry Andric isFunctionTracksDebugUserValues = MF.getProperties().hasProperty(
44877fc4c14SDimitry Andric MachineFunctionProperties::Property::TracksDebugUserValues);
449cfca06d7SDimitry Andric
450d39c594dSDimitry Andric if (PASS) {
451ac9a064cSDimitry Andric auto *LISWrapper = PASS->getAnalysisIfAvailable<LiveIntervalsWrapperPass>();
452ac9a064cSDimitry Andric LiveInts = LISWrapper ? &LISWrapper->getLIS() : nullptr;
453d39c594dSDimitry Andric // We don't want to verify LiveVariables if LiveIntervals is available.
454ac9a064cSDimitry Andric auto *LVWrapper = PASS->getAnalysisIfAvailable<LiveVariablesWrapperPass>();
455d39c594dSDimitry Andric if (!LiveInts)
456ac9a064cSDimitry Andric LiveVars = LVWrapper ? &LVWrapper->getLV() : nullptr;
457cf099d11SDimitry Andric LiveStks = PASS->getAnalysisIfAvailable<LiveStacks>();
458ac9a064cSDimitry Andric auto *SIWrapper = PASS->getAnalysisIfAvailable<SlotIndexesWrapperPass>();
459ac9a064cSDimitry Andric Indexes = SIWrapper ? &SIWrapper->getSI() : nullptr;
460ac9a064cSDimitry Andric }
461ac9a064cSDimitry Andric if (MFAM) {
462ac9a064cSDimitry Andric MachineFunction &Func = const_cast<MachineFunction &>(MF);
463ac9a064cSDimitry Andric LiveInts = MFAM->getCachedResult<LiveIntervalsAnalysis>(Func);
464ac9a064cSDimitry Andric if (!LiveInts)
465ac9a064cSDimitry Andric LiveVars = MFAM->getCachedResult<LiveVariablesAnalysis>(Func);
466ac9a064cSDimitry Andric // TODO: LiveStks = MFAM->getCachedResult<LiveStacksAnalysis>(Func);
467ac9a064cSDimitry Andric Indexes = MFAM->getCachedResult<SlotIndexesAnalysis>(Func);
4687d453863SRoman Divacky }
4697d453863SRoman Divacky
470dd58ef01SDimitry Andric verifySlotIndexes();
471dd58ef01SDimitry Andric
47201095a5dSDimitry Andric verifyProperties(MF);
47301095a5dSDimitry Andric
474009b1c42SEd Schouten visitMachineFunctionBefore();
475cfca06d7SDimitry Andric for (const MachineBasicBlock &MBB : MF) {
476cfca06d7SDimitry Andric visitMachineBasicBlockBefore(&MBB);
47758b69754SDimitry Andric // Keep track of the current bundle header.
4785ca98fd9SDimitry Andric const MachineInstr *CurBundle = nullptr;
4794a16efa3SDimitry Andric // Do we expect the next instruction to be part of the same bundle?
4804a16efa3SDimitry Andric bool InBundle = false;
4814a16efa3SDimitry Andric
482cfca06d7SDimitry Andric for (const MachineInstr &MI : MBB.instrs()) {
483cfca06d7SDimitry Andric if (MI.getParent() != &MBB) {
484cfca06d7SDimitry Andric report("Bad instruction parent pointer", &MBB);
485cfca06d7SDimitry Andric errs() << "Instruction: " << MI;
486cf099d11SDimitry Andric continue;
487cf099d11SDimitry Andric }
4884a16efa3SDimitry Andric
4894a16efa3SDimitry Andric // Check for consistent bundle flags.
490cfca06d7SDimitry Andric if (InBundle && !MI.isBundledWithPred())
4914a16efa3SDimitry Andric report("Missing BundledPred flag, "
492dd58ef01SDimitry Andric "BundledSucc was set on predecessor",
493cfca06d7SDimitry Andric &MI);
494cfca06d7SDimitry Andric if (!InBundle && MI.isBundledWithPred())
4954a16efa3SDimitry Andric report("BundledPred flag is set, "
496dd58ef01SDimitry Andric "but BundledSucc not set on predecessor",
497cfca06d7SDimitry Andric &MI);
4984a16efa3SDimitry Andric
49958b69754SDimitry Andric // Is this a bundle header?
500cfca06d7SDimitry Andric if (!MI.isInsideBundle()) {
50158b69754SDimitry Andric if (CurBundle)
50258b69754SDimitry Andric visitMachineBundleAfter(CurBundle);
503cfca06d7SDimitry Andric CurBundle = &MI;
50458b69754SDimitry Andric visitMachineBundleBefore(CurBundle);
50558b69754SDimitry Andric } else if (!CurBundle)
506cfca06d7SDimitry Andric report("No bundle header", &MI);
507cfca06d7SDimitry Andric visitMachineInstrBefore(&MI);
508cfca06d7SDimitry Andric for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) {
5095a5ac124SDimitry Andric const MachineOperand &Op = MI.getOperand(I);
5105a5ac124SDimitry Andric if (Op.getParent() != &MI) {
511145449b1SDimitry Andric // Make sure to use correct addOperand / removeOperand / ChangeTo
5125a5ac124SDimitry Andric // functions when replacing operands of a MachineInstr.
5135a5ac124SDimitry Andric report("Instruction has operand with wrong parent set", &MI);
5145a5ac124SDimitry Andric }
5155a5ac124SDimitry Andric
5165a5ac124SDimitry Andric visitMachineOperand(&Op, I);
5175a5ac124SDimitry Andric }
5185a5ac124SDimitry Andric
5194a16efa3SDimitry Andric // Was this the last bundled instruction?
520cfca06d7SDimitry Andric InBundle = MI.isBundledWithSucc();
521009b1c42SEd Schouten }
52258b69754SDimitry Andric if (CurBundle)
52358b69754SDimitry Andric visitMachineBundleAfter(CurBundle);
5244a16efa3SDimitry Andric if (InBundle)
525cfca06d7SDimitry Andric report("BundledSucc flag set on last instruction in block", &MBB.back());
526cfca06d7SDimitry Andric visitMachineBasicBlockAfter(&MBB);
527009b1c42SEd Schouten }
528009b1c42SEd Schouten visitMachineFunctionAfter();
529009b1c42SEd Schouten
53059850d08SRoman Divacky // Clean up.
53159850d08SRoman Divacky regsLive.clear();
53259850d08SRoman Divacky regsDefined.clear();
53359850d08SRoman Divacky regsDead.clear();
53459850d08SRoman Divacky regsKilled.clear();
53563faed5bSDimitry Andric regMasks.clear();
53659850d08SRoman Divacky MBBInfoMap.clear();
537009b1c42SEd Schouten
53801095a5dSDimitry Andric return foundErrors;
539009b1c42SEd Schouten }
540009b1c42SEd Schouten
report(const char * msg,const MachineFunction * MF)54159850d08SRoman Divacky void MachineVerifier::report(const char *msg, const MachineFunction *MF) {
542009b1c42SEd Schouten assert(MF);
5435a5ac124SDimitry Andric errs() << '\n';
544cf099d11SDimitry Andric if (!foundErrors++) {
545cf099d11SDimitry Andric if (Banner)
5465a5ac124SDimitry Andric errs() << "# " << Banner << '\n';
547dd58ef01SDimitry Andric if (LiveInts != nullptr)
548dd58ef01SDimitry Andric LiveInts->print(errs());
549dd58ef01SDimitry Andric else
5505a5ac124SDimitry Andric MF->print(errs(), Indexes);
551cf099d11SDimitry Andric }
5525a5ac124SDimitry Andric errs() << "*** Bad machine code: " << msg << " ***\n"
553522600a2SDimitry Andric << "- function: " << MF->getName() << "\n";
554009b1c42SEd Schouten }
555009b1c42SEd Schouten
report(const char * msg,const MachineBasicBlock * MBB)55659850d08SRoman Divacky void MachineVerifier::report(const char *msg, const MachineBasicBlock *MBB) {
557009b1c42SEd Schouten assert(MBB);
558009b1c42SEd Schouten report(msg, MBB->getParent());
559044eb2f6SDimitry Andric errs() << "- basic block: " << printMBBReference(*MBB) << ' '
560044eb2f6SDimitry Andric << MBB->getName() << " (" << (const void *)MBB << ')';
561cf099d11SDimitry Andric if (Indexes)
5625a5ac124SDimitry Andric errs() << " [" << Indexes->getMBBStartIdx(MBB)
563cf099d11SDimitry Andric << ';' << Indexes->getMBBEndIdx(MBB) << ')';
5645a5ac124SDimitry Andric errs() << '\n';
565009b1c42SEd Schouten }
566009b1c42SEd Schouten
report(const char * msg,const MachineInstr * MI)56759850d08SRoman Divacky void MachineVerifier::report(const char *msg, const MachineInstr *MI) {
568009b1c42SEd Schouten assert(MI);
569009b1c42SEd Schouten report(msg, MI->getParent());
5705a5ac124SDimitry Andric errs() << "- instruction: ";
57101095a5dSDimitry Andric if (Indexes && Indexes->hasIndex(*MI))
57201095a5dSDimitry Andric errs() << Indexes->getInstructionIndex(*MI) << '\t';
573b60736ecSDimitry Andric MI->print(errs(), /*IsStandalone=*/true);
574009b1c42SEd Schouten }
575009b1c42SEd Schouten
report(const char * msg,const MachineOperand * MO,unsigned MONum,LLT MOVRegType)576eb11fae6SDimitry Andric void MachineVerifier::report(const char *msg, const MachineOperand *MO,
577eb11fae6SDimitry Andric unsigned MONum, LLT MOVRegType) {
578009b1c42SEd Schouten assert(MO);
579009b1c42SEd Schouten report(msg, MO->getParent());
5805a5ac124SDimitry Andric errs() << "- operand " << MONum << ": ";
581eb11fae6SDimitry Andric MO->print(errs(), MOVRegType, TRI);
5825a5ac124SDimitry Andric errs() << "\n";
583009b1c42SEd Schouten }
584009b1c42SEd Schouten
report(const Twine & Msg,const MachineInstr * MI)585344a3780SDimitry Andric void MachineVerifier::report(const Twine &Msg, const MachineInstr *MI) {
586344a3780SDimitry Andric report(Msg.str().c_str(), MI);
587344a3780SDimitry Andric }
588344a3780SDimitry Andric
report_context(SlotIndex Pos) const58901095a5dSDimitry Andric void MachineVerifier::report_context(SlotIndex Pos) const {
59001095a5dSDimitry Andric errs() << "- at: " << Pos << '\n';
59101095a5dSDimitry Andric }
59201095a5dSDimitry Andric
report_context(const LiveInterval & LI) const593dd58ef01SDimitry Andric void MachineVerifier::report_context(const LiveInterval &LI) const {
5945a5ac124SDimitry Andric errs() << "- interval: " << LI << '\n';
59558b69754SDimitry Andric }
59658b69754SDimitry Andric
report_context(const LiveRange & LR,Register VRegUnit,LaneBitmask LaneMask) const597b60736ecSDimitry Andric void MachineVerifier::report_context(const LiveRange &LR, Register VRegUnit,
598dd58ef01SDimitry Andric LaneBitmask LaneMask) const {
59901095a5dSDimitry Andric report_context_liverange(LR);
600b915e9e0SDimitry Andric report_context_vreg_regunit(VRegUnit);
601b915e9e0SDimitry Andric if (LaneMask.any())
60201095a5dSDimitry Andric report_context_lanemask(LaneMask);
603f8af5cf6SDimitry Andric }
604f8af5cf6SDimitry Andric
report_context(const LiveRange::Segment & S) const605dd58ef01SDimitry Andric void MachineVerifier::report_context(const LiveRange::Segment &S) const {
606dd58ef01SDimitry Andric errs() << "- segment: " << S << '\n';
607dd58ef01SDimitry Andric }
608dd58ef01SDimitry Andric
report_context(const VNInfo & VNI) const609dd58ef01SDimitry Andric void MachineVerifier::report_context(const VNInfo &VNI) const {
610dd58ef01SDimitry Andric errs() << "- ValNo: " << VNI.id << " (def " << VNI.def << ")\n";
61158b69754SDimitry Andric }
61258b69754SDimitry Andric
report_context_liverange(const LiveRange & LR) const61301095a5dSDimitry Andric void MachineVerifier::report_context_liverange(const LiveRange &LR) const {
61401095a5dSDimitry Andric errs() << "- liverange: " << LR << '\n';
61501095a5dSDimitry Andric }
61601095a5dSDimitry Andric
report_context(MCPhysReg PReg) const617d8e91e46SDimitry Andric void MachineVerifier::report_context(MCPhysReg PReg) const {
618d8e91e46SDimitry Andric errs() << "- p. register: " << printReg(PReg, TRI) << '\n';
619d8e91e46SDimitry Andric }
620d8e91e46SDimitry Andric
report_context_vreg(Register VReg) const621b60736ecSDimitry Andric void MachineVerifier::report_context_vreg(Register VReg) const {
622044eb2f6SDimitry Andric errs() << "- v. register: " << printReg(VReg, TRI) << '\n';
62301095a5dSDimitry Andric }
62401095a5dSDimitry Andric
report_context_vreg_regunit(Register VRegOrUnit) const625b60736ecSDimitry Andric void MachineVerifier::report_context_vreg_regunit(Register VRegOrUnit) const {
626e3b55780SDimitry Andric if (VRegOrUnit.isVirtual()) {
62701095a5dSDimitry Andric report_context_vreg(VRegOrUnit);
62801095a5dSDimitry Andric } else {
629044eb2f6SDimitry Andric errs() << "- regunit: " << printRegUnit(VRegOrUnit, TRI) << '\n';
63001095a5dSDimitry Andric }
63101095a5dSDimitry Andric }
63201095a5dSDimitry Andric
report_context_lanemask(LaneBitmask LaneMask) const63301095a5dSDimitry Andric void MachineVerifier::report_context_lanemask(LaneBitmask LaneMask) const {
63401095a5dSDimitry Andric errs() << "- lanemask: " << PrintLaneMask(LaneMask) << '\n';
63501095a5dSDimitry Andric }
63601095a5dSDimitry Andric
markReachable(const MachineBasicBlock * MBB)63759850d08SRoman Divacky void MachineVerifier::markReachable(const MachineBasicBlock *MBB) {
638009b1c42SEd Schouten BBInfo &MInfo = MBBInfoMap[MBB];
639009b1c42SEd Schouten if (!MInfo.reachable) {
640009b1c42SEd Schouten MInfo.reachable = true;
641cfca06d7SDimitry Andric for (const MachineBasicBlock *Succ : MBB->successors())
642cfca06d7SDimitry Andric markReachable(Succ);
643009b1c42SEd Schouten }
644009b1c42SEd Schouten }
645009b1c42SEd Schouten
visitMachineFunctionBefore()64659850d08SRoman Divacky void MachineVerifier::visitMachineFunctionBefore() {
647cf099d11SDimitry Andric lastIndex = SlotIndex();
648c46e6a59SDimitry Andric regsReserved = MRI->reservedRegsFrozen() ? MRI->getReservedRegs()
649c46e6a59SDimitry Andric : TRI->getReservedRegs(*MF);
65059850d08SRoman Divacky
65171d5a254SDimitry Andric if (!MF->empty())
652009b1c42SEd Schouten markReachable(&MF->front());
653522600a2SDimitry Andric
654522600a2SDimitry Andric // Build a set of the basic blocks in the function.
655522600a2SDimitry Andric FunctionBlocks.clear();
6565ca98fd9SDimitry Andric for (const auto &MBB : *MF) {
6575ca98fd9SDimitry Andric FunctionBlocks.insert(&MBB);
6585ca98fd9SDimitry Andric BBInfo &MInfo = MBBInfoMap[&MBB];
659522600a2SDimitry Andric
6605ca98fd9SDimitry Andric MInfo.Preds.insert(MBB.pred_begin(), MBB.pred_end());
6615ca98fd9SDimitry Andric if (MInfo.Preds.size() != MBB.pred_size())
6625ca98fd9SDimitry Andric report("MBB has duplicate entries in its predecessor list.", &MBB);
663522600a2SDimitry Andric
6645ca98fd9SDimitry Andric MInfo.Succs.insert(MBB.succ_begin(), MBB.succ_end());
6655ca98fd9SDimitry Andric if (MInfo.Succs.size() != MBB.succ_size())
6665ca98fd9SDimitry Andric report("MBB has duplicate entries in its successor list.", &MBB);
667522600a2SDimitry Andric }
66859d6cff9SDimitry Andric
66959d6cff9SDimitry Andric // Check that the register use lists are sane.
67059d6cff9SDimitry Andric MRI->verifyUseLists();
671f8af5cf6SDimitry Andric
67271d5a254SDimitry Andric if (!MF->empty())
673f8af5cf6SDimitry Andric verifyStackFrame();
674009b1c42SEd Schouten }
675009b1c42SEd Schouten
676907da171SRoman Divacky void
visitMachineBasicBlockBefore(const MachineBasicBlock * MBB)677907da171SRoman Divacky MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
6785ca98fd9SDimitry Andric FirstTerminator = nullptr;
679d8e91e46SDimitry Andric FirstNonPHI = nullptr;
68030815c53SDimitry Andric
681b915e9e0SDimitry Andric if (!MF->getProperties().hasProperty(
6827e7b6700SDimitry Andric MachineFunctionProperties::Property::NoPHIs) && MRI->tracksLiveness()) {
68363faed5bSDimitry Andric // If this block has allocatable physical registers live-in, check that
68463faed5bSDimitry Andric // it is an entry block or landing pad.
685dd58ef01SDimitry Andric for (const auto &LI : MBB->liveins()) {
686dd58ef01SDimitry Andric if (isAllocatable(LI.PhysReg) && !MBB->isEHPad() &&
6877fa27ce4SDimitry Andric MBB->getIterator() != MBB->getParent()->begin() &&
6887fa27ce4SDimitry Andric !MBB->isInlineAsmBrIndirectTarget()) {
6897fa27ce4SDimitry Andric report("MBB has allocatable live-in, but isn't entry, landing-pad, or "
6907fa27ce4SDimitry Andric "inlineasm-br-indirect-target.",
6917fa27ce4SDimitry Andric MBB);
692d8e91e46SDimitry Andric report_context(LI.PhysReg);
69363faed5bSDimitry Andric }
69463faed5bSDimitry Andric }
69563faed5bSDimitry Andric }
69663faed5bSDimitry Andric
697e3b55780SDimitry Andric if (MBB->isIRBlockAddressTaken()) {
698e3b55780SDimitry Andric if (!MBB->getAddressTakenIRBlock()->hasAddressTaken())
699e3b55780SDimitry Andric report("ir-block-address-taken is associated with basic block not used by "
700e3b55780SDimitry Andric "a blockaddress.",
701e3b55780SDimitry Andric MBB);
702e3b55780SDimitry Andric }
703e3b55780SDimitry Andric
704cf099d11SDimitry Andric // Count the number of landing pad successors.
705cfca06d7SDimitry Andric SmallPtrSet<const MachineBasicBlock*, 4> LandingPadSuccs;
706cfca06d7SDimitry Andric for (const auto *succ : MBB->successors()) {
707cfca06d7SDimitry Andric if (succ->isEHPad())
708cfca06d7SDimitry Andric LandingPadSuccs.insert(succ);
709cfca06d7SDimitry Andric if (!FunctionBlocks.count(succ))
710522600a2SDimitry Andric report("MBB has successor that isn't part of the function.", MBB);
711cfca06d7SDimitry Andric if (!MBBInfoMap[succ].Preds.count(MBB)) {
712522600a2SDimitry Andric report("Inconsistent CFG", MBB);
713044eb2f6SDimitry Andric errs() << "MBB is not in the predecessor list of the successor "
714cfca06d7SDimitry Andric << printMBBReference(*succ) << ".\n";
715522600a2SDimitry Andric }
716522600a2SDimitry Andric }
717522600a2SDimitry Andric
718522600a2SDimitry Andric // Check the predecessor list.
719cfca06d7SDimitry Andric for (const MachineBasicBlock *Pred : MBB->predecessors()) {
720cfca06d7SDimitry Andric if (!FunctionBlocks.count(Pred))
721522600a2SDimitry Andric report("MBB has predecessor that isn't part of the function.", MBB);
722cfca06d7SDimitry Andric if (!MBBInfoMap[Pred].Succs.count(MBB)) {
723522600a2SDimitry Andric report("Inconsistent CFG", MBB);
724044eb2f6SDimitry Andric errs() << "MBB is not in the successor list of the predecessor "
725cfca06d7SDimitry Andric << printMBBReference(*Pred) << ".\n";
726522600a2SDimitry Andric }
727cf099d11SDimitry Andric }
72856fe8f14SDimitry Andric
72956fe8f14SDimitry Andric const MCAsmInfo *AsmInfo = TM->getMCAsmInfo();
73056fe8f14SDimitry Andric const BasicBlock *BB = MBB->getBasicBlock();
731044eb2f6SDimitry Andric const Function &F = MF->getFunction();
73256fe8f14SDimitry Andric if (LandingPadSuccs.size() > 1 &&
73356fe8f14SDimitry Andric !(AsmInfo &&
73456fe8f14SDimitry Andric AsmInfo->getExceptionHandlingType() == ExceptionHandling::SjLj &&
735dd58ef01SDimitry Andric BB && isa<SwitchInst>(BB->getTerminator())) &&
736eb11fae6SDimitry Andric !isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
737cf099d11SDimitry Andric report("MBB has more than one landing pad successor", MBB);
738cf099d11SDimitry Andric
739cfca06d7SDimitry Andric // Call analyzeBranch. If it succeeds, there several more conditions to check.
7405ca98fd9SDimitry Andric MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
74159850d08SRoman Divacky SmallVector<MachineOperand, 4> Cond;
74201095a5dSDimitry Andric if (!TII->analyzeBranch(*const_cast<MachineBasicBlock *>(MBB), TBB, FBB,
74301095a5dSDimitry Andric Cond)) {
744cfca06d7SDimitry Andric // Ok, analyzeBranch thinks it knows what's going on with this block. Let's
74559850d08SRoman Divacky // check whether its answers match up with reality.
74659850d08SRoman Divacky if (!TBB && !FBB) {
74759850d08SRoman Divacky // Block falls through to its successor.
7485ca98fd9SDimitry Andric if (!MBB->empty() && MBB->back().isBarrier() &&
74901095a5dSDimitry Andric !TII->isPredicated(MBB->back())) {
75059850d08SRoman Divacky report("MBB exits via unconditional fall-through but ends with a "
75159850d08SRoman Divacky "barrier instruction!", MBB);
75259850d08SRoman Divacky }
75359850d08SRoman Divacky if (!Cond.empty()) {
75459850d08SRoman Divacky report("MBB exits via unconditional fall-through but has a condition!",
75559850d08SRoman Divacky MBB);
75659850d08SRoman Divacky }
75759850d08SRoman Divacky } else if (TBB && !FBB && Cond.empty()) {
75859850d08SRoman Divacky // Block unconditionally branches somewhere.
75959850d08SRoman Divacky if (MBB->empty()) {
76059850d08SRoman Divacky report("MBB exits via unconditional branch but doesn't contain "
76159850d08SRoman Divacky "any instructions!", MBB);
7625ca98fd9SDimitry Andric } else if (!MBB->back().isBarrier()) {
76359850d08SRoman Divacky report("MBB exits via unconditional branch but doesn't end with a "
76459850d08SRoman Divacky "barrier instruction!", MBB);
7655ca98fd9SDimitry Andric } else if (!MBB->back().isTerminator()) {
76659850d08SRoman Divacky report("MBB exits via unconditional branch but the branch isn't a "
76759850d08SRoman Divacky "terminator instruction!", MBB);
76859850d08SRoman Divacky }
76959850d08SRoman Divacky } else if (TBB && !FBB && !Cond.empty()) {
77059850d08SRoman Divacky // Block conditionally branches somewhere, otherwise falls through.
77159850d08SRoman Divacky if (MBB->empty()) {
77259850d08SRoman Divacky report("MBB exits via conditional branch/fall-through but doesn't "
77359850d08SRoman Divacky "contain any instructions!", MBB);
7745ca98fd9SDimitry Andric } else if (MBB->back().isBarrier()) {
77559850d08SRoman Divacky report("MBB exits via conditional branch/fall-through but ends with a "
77659850d08SRoman Divacky "barrier instruction!", MBB);
7775ca98fd9SDimitry Andric } else if (!MBB->back().isTerminator()) {
77859850d08SRoman Divacky report("MBB exits via conditional branch/fall-through but the branch "
77959850d08SRoman Divacky "isn't a terminator instruction!", MBB);
78059850d08SRoman Divacky }
78159850d08SRoman Divacky } else if (TBB && FBB) {
78259850d08SRoman Divacky // Block conditionally branches somewhere, otherwise branches
78359850d08SRoman Divacky // somewhere else.
78459850d08SRoman Divacky if (MBB->empty()) {
78559850d08SRoman Divacky report("MBB exits via conditional branch/branch but doesn't "
78659850d08SRoman Divacky "contain any instructions!", MBB);
7875ca98fd9SDimitry Andric } else if (!MBB->back().isBarrier()) {
78859850d08SRoman Divacky report("MBB exits via conditional branch/branch but doesn't end with a "
78959850d08SRoman Divacky "barrier instruction!", MBB);
7905ca98fd9SDimitry Andric } else if (!MBB->back().isTerminator()) {
79159850d08SRoman Divacky report("MBB exits via conditional branch/branch but the branch "
79259850d08SRoman Divacky "isn't a terminator instruction!", MBB);
79359850d08SRoman Divacky }
79459850d08SRoman Divacky if (Cond.empty()) {
795d8e91e46SDimitry Andric report("MBB exits via conditional branch/branch but there's no "
79659850d08SRoman Divacky "condition!", MBB);
79759850d08SRoman Divacky }
79859850d08SRoman Divacky } else {
799cfca06d7SDimitry Andric report("analyzeBranch returned invalid data!", MBB);
800cfca06d7SDimitry Andric }
801cfca06d7SDimitry Andric
802cfca06d7SDimitry Andric // Now check that the successors match up with the answers reported by
803cfca06d7SDimitry Andric // analyzeBranch.
804cfca06d7SDimitry Andric if (TBB && !MBB->isSuccessor(TBB))
805cfca06d7SDimitry Andric report("MBB exits via jump or conditional branch, but its target isn't a "
806cfca06d7SDimitry Andric "CFG successor!",
807cfca06d7SDimitry Andric MBB);
808cfca06d7SDimitry Andric if (FBB && !MBB->isSuccessor(FBB))
809cfca06d7SDimitry Andric report("MBB exits via conditional branch, but its target isn't a CFG "
810cfca06d7SDimitry Andric "successor!",
811cfca06d7SDimitry Andric MBB);
812cfca06d7SDimitry Andric
813cfca06d7SDimitry Andric // There might be a fallthrough to the next block if there's either no
814cfca06d7SDimitry Andric // unconditional true branch, or if there's a condition, and one of the
815cfca06d7SDimitry Andric // branches is missing.
816cfca06d7SDimitry Andric bool Fallthrough = !TBB || (!Cond.empty() && !FBB);
817cfca06d7SDimitry Andric
818cfca06d7SDimitry Andric // A conditional fallthrough must be an actual CFG successor, not
819cfca06d7SDimitry Andric // unreachable. (Conversely, an unconditional fallthrough might not really
820cfca06d7SDimitry Andric // be a successor, because the block might end in unreachable.)
821cfca06d7SDimitry Andric if (!Cond.empty() && !FBB) {
822cfca06d7SDimitry Andric MachineFunction::const_iterator MBBI = std::next(MBB->getIterator());
823cfca06d7SDimitry Andric if (MBBI == MF->end()) {
824cfca06d7SDimitry Andric report("MBB conditionally falls through out of function!", MBB);
825cfca06d7SDimitry Andric } else if (!MBB->isSuccessor(&*MBBI))
826cfca06d7SDimitry Andric report("MBB exits via conditional branch/fall-through but the CFG "
827cfca06d7SDimitry Andric "successors don't match the actual successors!",
828cfca06d7SDimitry Andric MBB);
829cfca06d7SDimitry Andric }
830cfca06d7SDimitry Andric
831cfca06d7SDimitry Andric // Verify that there aren't any extra un-accounted-for successors.
832cfca06d7SDimitry Andric for (const MachineBasicBlock *SuccMBB : MBB->successors()) {
833cfca06d7SDimitry Andric // If this successor is one of the branch targets, it's okay.
834cfca06d7SDimitry Andric if (SuccMBB == TBB || SuccMBB == FBB)
835cfca06d7SDimitry Andric continue;
836cfca06d7SDimitry Andric // If we might have a fallthrough, and the successor is the fallthrough
837cfca06d7SDimitry Andric // block, that's also ok.
838cfca06d7SDimitry Andric if (Fallthrough && SuccMBB == MBB->getNextNode())
839cfca06d7SDimitry Andric continue;
840cfca06d7SDimitry Andric // Also accept successors which are for exception-handling or might be
841cfca06d7SDimitry Andric // inlineasm_br targets.
842cfca06d7SDimitry Andric if (SuccMBB->isEHPad() || SuccMBB->isInlineAsmBrIndirectTarget())
843cfca06d7SDimitry Andric continue;
844cfca06d7SDimitry Andric report("MBB has unexpected successors which are not branch targets, "
845cfca06d7SDimitry Andric "fallthrough, EHPads, or inlineasm_br targets.",
846cfca06d7SDimitry Andric MBB);
84759850d08SRoman Divacky }
84859850d08SRoman Divacky }
84959850d08SRoman Divacky
850009b1c42SEd Schouten regsLive.clear();
8517e7b6700SDimitry Andric if (MRI->tracksLiveness()) {
852dd58ef01SDimitry Andric for (const auto &LI : MBB->liveins()) {
8531d5ae102SDimitry Andric if (!Register::isPhysicalRegister(LI.PhysReg)) {
854009b1c42SEd Schouten report("MBB live-in list contains non-physical register", MBB);
855009b1c42SEd Schouten continue;
856009b1c42SEd Schouten }
857706b4fc4SDimitry Andric for (const MCPhysReg &SubReg : TRI->subregs_inclusive(LI.PhysReg))
858706b4fc4SDimitry Andric regsLive.insert(SubReg);
859009b1c42SEd Schouten }
8607e7b6700SDimitry Andric }
86159850d08SRoman Divacky
862b915e9e0SDimitry Andric const MachineFrameInfo &MFI = MF->getFrameInfo();
863b915e9e0SDimitry Andric BitVector PR = MFI.getPristineRegs(*MF);
8647af96fb3SDimitry Andric for (unsigned I : PR.set_bits()) {
865706b4fc4SDimitry Andric for (const MCPhysReg &SubReg : TRI->subregs_inclusive(I))
866706b4fc4SDimitry Andric regsLive.insert(SubReg);
867009b1c42SEd Schouten }
868009b1c42SEd Schouten
86959850d08SRoman Divacky regsKilled.clear();
87059850d08SRoman Divacky regsDefined.clear();
871cf099d11SDimitry Andric
872cf099d11SDimitry Andric if (Indexes)
873cf099d11SDimitry Andric lastIndex = Indexes->getMBBStartIdx(MBB);
87459850d08SRoman Divacky }
87559850d08SRoman Divacky
87658b69754SDimitry Andric // This function gets called for all bundle headers, including normal
87758b69754SDimitry Andric // stand-alone unbundled instructions.
visitMachineBundleBefore(const MachineInstr * MI)87858b69754SDimitry Andric void MachineVerifier::visitMachineBundleBefore(const MachineInstr *MI) {
87901095a5dSDimitry Andric if (Indexes && Indexes->hasIndex(*MI)) {
88001095a5dSDimitry Andric SlotIndex idx = Indexes->getInstructionIndex(*MI);
88158b69754SDimitry Andric if (!(idx > lastIndex)) {
88258b69754SDimitry Andric report("Instruction index out of order", MI);
8835a5ac124SDimitry Andric errs() << "Last instruction was at " << lastIndex << '\n';
88458b69754SDimitry Andric }
88558b69754SDimitry Andric lastIndex = idx;
88658b69754SDimitry Andric }
88758b69754SDimitry Andric
88858b69754SDimitry Andric // Ensure non-terminators don't follow terminators.
889b60736ecSDimitry Andric if (MI->isTerminator()) {
89058b69754SDimitry Andric if (!FirstTerminator)
89158b69754SDimitry Andric FirstTerminator = MI;
892cfca06d7SDimitry Andric } else if (FirstTerminator) {
893e3b55780SDimitry Andric // For GlobalISel, G_INVOKE_REGION_START is a terminator that we allow to
894e3b55780SDimitry Andric // precede non-terminators.
895e3b55780SDimitry Andric if (FirstTerminator->getOpcode() != TargetOpcode::G_INVOKE_REGION_START) {
89658b69754SDimitry Andric report("Non-terminator instruction after the first terminator", MI);
8975a5ac124SDimitry Andric errs() << "First terminator was:\t" << *FirstTerminator;
89858b69754SDimitry Andric }
89958b69754SDimitry Andric }
900e3b55780SDimitry Andric }
90158b69754SDimitry Andric
902522600a2SDimitry Andric // The operands on an INLINEASM instruction must follow a template.
903522600a2SDimitry Andric // Verify that the flag operands make sense.
verifyInlineAsm(const MachineInstr * MI)904522600a2SDimitry Andric void MachineVerifier::verifyInlineAsm(const MachineInstr *MI) {
905522600a2SDimitry Andric // The first two operands on INLINEASM are the asm string and global flags.
906522600a2SDimitry Andric if (MI->getNumOperands() < 2) {
907522600a2SDimitry Andric report("Too few operands on inline asm", MI);
908522600a2SDimitry Andric return;
909522600a2SDimitry Andric }
910522600a2SDimitry Andric if (!MI->getOperand(0).isSymbol())
911522600a2SDimitry Andric report("Asm string must be an external symbol", MI);
912522600a2SDimitry Andric if (!MI->getOperand(1).isImm())
913522600a2SDimitry Andric report("Asm flags must be an immediate", MI);
914522600a2SDimitry Andric // Allowed flags are Extra_HasSideEffects = 1, Extra_IsAlignStack = 2,
91501095a5dSDimitry Andric // Extra_AsmDialect = 4, Extra_MayLoad = 8, and Extra_MayStore = 16,
91601095a5dSDimitry Andric // and Extra_IsConvergent = 32.
91701095a5dSDimitry Andric if (!isUInt<6>(MI->getOperand(1).getImm()))
918522600a2SDimitry Andric report("Unknown asm flags", &MI->getOperand(1), 1);
919522600a2SDimitry Andric
9205a5ac124SDimitry Andric static_assert(InlineAsm::MIOp_FirstOperand == 2, "Asm format changed");
921522600a2SDimitry Andric
922522600a2SDimitry Andric unsigned OpNo = InlineAsm::MIOp_FirstOperand;
923522600a2SDimitry Andric unsigned NumOps;
924522600a2SDimitry Andric for (unsigned e = MI->getNumOperands(); OpNo < e; OpNo += NumOps) {
925522600a2SDimitry Andric const MachineOperand &MO = MI->getOperand(OpNo);
926522600a2SDimitry Andric // There may be implicit ops after the fixed operands.
927522600a2SDimitry Andric if (!MO.isImm())
928522600a2SDimitry Andric break;
929b1c73532SDimitry Andric const InlineAsm::Flag F(MO.getImm());
930b1c73532SDimitry Andric NumOps = 1 + F.getNumOperandRegisters();
931522600a2SDimitry Andric }
932522600a2SDimitry Andric
933522600a2SDimitry Andric if (OpNo > MI->getNumOperands())
934522600a2SDimitry Andric report("Missing operands in last group", MI);
935522600a2SDimitry Andric
936522600a2SDimitry Andric // An optional MDNode follows the groups.
937522600a2SDimitry Andric if (OpNo < MI->getNumOperands() && MI->getOperand(OpNo).isMetadata())
938522600a2SDimitry Andric ++OpNo;
939522600a2SDimitry Andric
940522600a2SDimitry Andric // All trailing operands must be implicit registers.
941522600a2SDimitry Andric for (unsigned e = MI->getNumOperands(); OpNo < e; ++OpNo) {
942522600a2SDimitry Andric const MachineOperand &MO = MI->getOperand(OpNo);
943522600a2SDimitry Andric if (!MO.isReg() || !MO.isImplicit())
944522600a2SDimitry Andric report("Expected implicit register after groups", &MO, OpNo);
945522600a2SDimitry Andric }
946e3b55780SDimitry Andric
947e3b55780SDimitry Andric if (MI->getOpcode() == TargetOpcode::INLINEASM_BR) {
948e3b55780SDimitry Andric const MachineBasicBlock *MBB = MI->getParent();
949e3b55780SDimitry Andric
950e3b55780SDimitry Andric for (unsigned i = InlineAsm::MIOp_FirstOperand, e = MI->getNumOperands();
951e3b55780SDimitry Andric i != e; ++i) {
952e3b55780SDimitry Andric const MachineOperand &MO = MI->getOperand(i);
953e3b55780SDimitry Andric
954e3b55780SDimitry Andric if (!MO.isMBB())
955e3b55780SDimitry Andric continue;
956e3b55780SDimitry Andric
957e3b55780SDimitry Andric // Check the successor & predecessor lists look ok, assume they are
958e3b55780SDimitry Andric // not. Find the indirect target without going through the successors.
959e3b55780SDimitry Andric const MachineBasicBlock *IndirectTargetMBB = MO.getMBB();
960e3b55780SDimitry Andric if (!IndirectTargetMBB) {
961e3b55780SDimitry Andric report("INLINEASM_BR indirect target does not exist", &MO, i);
962e3b55780SDimitry Andric break;
963e3b55780SDimitry Andric }
964e3b55780SDimitry Andric
965e3b55780SDimitry Andric if (!MBB->isSuccessor(IndirectTargetMBB))
966e3b55780SDimitry Andric report("INLINEASM_BR indirect target missing from successor list", &MO,
967e3b55780SDimitry Andric i);
968e3b55780SDimitry Andric
969e3b55780SDimitry Andric if (!IndirectTargetMBB->isPredecessor(MBB))
970e3b55780SDimitry Andric report("INLINEASM_BR indirect target predecessor list missing parent",
971e3b55780SDimitry Andric &MO, i);
972e3b55780SDimitry Andric }
973e3b55780SDimitry Andric }
974522600a2SDimitry Andric }
975522600a2SDimitry Andric
verifyAllRegOpsScalar(const MachineInstr & MI,const MachineRegisterInfo & MRI)976c0981da4SDimitry Andric bool MachineVerifier::verifyAllRegOpsScalar(const MachineInstr &MI,
977c0981da4SDimitry Andric const MachineRegisterInfo &MRI) {
978c0981da4SDimitry Andric if (none_of(MI.explicit_operands(), [&MRI](const MachineOperand &Op) {
979c0981da4SDimitry Andric if (!Op.isReg())
980c0981da4SDimitry Andric return false;
981c0981da4SDimitry Andric const auto Reg = Op.getReg();
982c0981da4SDimitry Andric if (Reg.isPhysical())
983c0981da4SDimitry Andric return false;
984c0981da4SDimitry Andric return !MRI.getType(Reg).isScalar();
985c0981da4SDimitry Andric }))
986c0981da4SDimitry Andric return true;
987c0981da4SDimitry Andric report("All register operands must have scalar types", &MI);
988c0981da4SDimitry Andric return false;
989c0981da4SDimitry Andric }
990c0981da4SDimitry Andric
991e6d15924SDimitry Andric /// Check that types are consistent when two operands need to have the same
992e6d15924SDimitry Andric /// number of vector elements.
993e6d15924SDimitry Andric /// \return true if the types are valid.
verifyVectorElementMatch(LLT Ty0,LLT Ty1,const MachineInstr * MI)994e6d15924SDimitry Andric bool MachineVerifier::verifyVectorElementMatch(LLT Ty0, LLT Ty1,
995e6d15924SDimitry Andric const MachineInstr *MI) {
996e6d15924SDimitry Andric if (Ty0.isVector() != Ty1.isVector()) {
997e6d15924SDimitry Andric report("operand types must be all-vector or all-scalar", MI);
998e6d15924SDimitry Andric // Generally we try to report as many issues as possible at once, but in
999e6d15924SDimitry Andric // this case it's not clear what should we be comparing the size of the
1000e6d15924SDimitry Andric // scalar with: the size of the whole vector or its lane. Instead of
1001e6d15924SDimitry Andric // making an arbitrary choice and emitting not so helpful message, let's
1002e6d15924SDimitry Andric // avoid the extra noise and stop here.
1003e6d15924SDimitry Andric return false;
1004e6d15924SDimitry Andric }
1005e6d15924SDimitry Andric
1006b1c73532SDimitry Andric if (Ty0.isVector() && Ty0.getElementCount() != Ty1.getElementCount()) {
1007e6d15924SDimitry Andric report("operand types must preserve number of vector elements", MI);
1008e6d15924SDimitry Andric return false;
1009e6d15924SDimitry Andric }
1010e6d15924SDimitry Andric
1011e6d15924SDimitry Andric return true;
1012e6d15924SDimitry Andric }
1013e6d15924SDimitry Andric
verifyGIntrinsicSideEffects(const MachineInstr * MI)1014b1c73532SDimitry Andric bool MachineVerifier::verifyGIntrinsicSideEffects(const MachineInstr *MI) {
1015b1c73532SDimitry Andric auto Opcode = MI->getOpcode();
1016b1c73532SDimitry Andric bool NoSideEffects = Opcode == TargetOpcode::G_INTRINSIC ||
1017b1c73532SDimitry Andric Opcode == TargetOpcode::G_INTRINSIC_CONVERGENT;
1018b1c73532SDimitry Andric unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
1019b1c73532SDimitry Andric if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
1020b1c73532SDimitry Andric AttributeList Attrs = Intrinsic::getAttributes(
1021b1c73532SDimitry Andric MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
1022b1c73532SDimitry Andric bool DeclHasSideEffects = !Attrs.getMemoryEffects().doesNotAccessMemory();
1023b1c73532SDimitry Andric if (NoSideEffects && DeclHasSideEffects) {
1024b1c73532SDimitry Andric report(Twine(TII->getName(Opcode),
1025b1c73532SDimitry Andric " used with intrinsic that accesses memory"),
1026b1c73532SDimitry Andric MI);
1027b1c73532SDimitry Andric return false;
1028b1c73532SDimitry Andric }
1029b1c73532SDimitry Andric if (!NoSideEffects && !DeclHasSideEffects) {
1030b1c73532SDimitry Andric report(Twine(TII->getName(Opcode), " used with readnone intrinsic"), MI);
1031b1c73532SDimitry Andric return false;
1032b1c73532SDimitry Andric }
1033b1c73532SDimitry Andric }
1034b1c73532SDimitry Andric
1035b1c73532SDimitry Andric return true;
1036b1c73532SDimitry Andric }
1037b1c73532SDimitry Andric
verifyGIntrinsicConvergence(const MachineInstr * MI)1038b1c73532SDimitry Andric bool MachineVerifier::verifyGIntrinsicConvergence(const MachineInstr *MI) {
1039b1c73532SDimitry Andric auto Opcode = MI->getOpcode();
1040b1c73532SDimitry Andric bool NotConvergent = Opcode == TargetOpcode::G_INTRINSIC ||
1041b1c73532SDimitry Andric Opcode == TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS;
1042b1c73532SDimitry Andric unsigned IntrID = cast<GIntrinsic>(MI)->getIntrinsicID();
1043b1c73532SDimitry Andric if (IntrID != 0 && IntrID < Intrinsic::num_intrinsics) {
1044b1c73532SDimitry Andric AttributeList Attrs = Intrinsic::getAttributes(
1045b1c73532SDimitry Andric MF->getFunction().getContext(), static_cast<Intrinsic::ID>(IntrID));
1046b1c73532SDimitry Andric bool DeclIsConvergent = Attrs.hasFnAttr(Attribute::Convergent);
1047b1c73532SDimitry Andric if (NotConvergent && DeclIsConvergent) {
1048b1c73532SDimitry Andric report(Twine(TII->getName(Opcode), " used with a convergent intrinsic"),
1049b1c73532SDimitry Andric MI);
1050b1c73532SDimitry Andric return false;
1051b1c73532SDimitry Andric }
1052b1c73532SDimitry Andric if (!NotConvergent && !DeclIsConvergent) {
1053b1c73532SDimitry Andric report(
1054b1c73532SDimitry Andric Twine(TII->getName(Opcode), " used with a non-convergent intrinsic"),
1055b1c73532SDimitry Andric MI);
1056b1c73532SDimitry Andric return false;
1057b1c73532SDimitry Andric }
1058b1c73532SDimitry Andric }
1059b1c73532SDimitry Andric
1060b1c73532SDimitry Andric return true;
1061b1c73532SDimitry Andric }
1062b1c73532SDimitry Andric
verifyPreISelGenericInstruction(const MachineInstr * MI)1063e6d15924SDimitry Andric void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
1064e6d15924SDimitry Andric if (isFunctionSelected)
1065e6d15924SDimitry Andric report("Unexpected generic instruction in a Selected function", MI);
1066e6d15924SDimitry Andric
1067e6d15924SDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
1068e6d15924SDimitry Andric unsigned NumOps = MI->getNumOperands();
1069e6d15924SDimitry Andric
1070cfca06d7SDimitry Andric // Branches must reference a basic block if they are not indirect
1071cfca06d7SDimitry Andric if (MI->isBranch() && !MI->isIndirectBranch()) {
1072cfca06d7SDimitry Andric bool HasMBB = false;
1073cfca06d7SDimitry Andric for (const MachineOperand &Op : MI->operands()) {
1074cfca06d7SDimitry Andric if (Op.isMBB()) {
1075cfca06d7SDimitry Andric HasMBB = true;
1076cfca06d7SDimitry Andric break;
1077cfca06d7SDimitry Andric }
1078cfca06d7SDimitry Andric }
1079cfca06d7SDimitry Andric
1080cfca06d7SDimitry Andric if (!HasMBB) {
1081cfca06d7SDimitry Andric report("Branch instruction is missing a basic block operand or "
1082cfca06d7SDimitry Andric "isIndirectBranch property",
1083cfca06d7SDimitry Andric MI);
1084cfca06d7SDimitry Andric }
1085cfca06d7SDimitry Andric }
1086cfca06d7SDimitry Andric
1087e6d15924SDimitry Andric // Check types.
1088e6d15924SDimitry Andric SmallVector<LLT, 4> Types;
1089e6d15924SDimitry Andric for (unsigned I = 0, E = std::min(MCID.getNumOperands(), NumOps);
1090e6d15924SDimitry Andric I != E; ++I) {
1091e3b55780SDimitry Andric if (!MCID.operands()[I].isGenericType())
1092e6d15924SDimitry Andric continue;
1093e6d15924SDimitry Andric // Generic instructions specify type equality constraints between some of
1094e6d15924SDimitry Andric // their operands. Make sure these are consistent.
1095e3b55780SDimitry Andric size_t TypeIdx = MCID.operands()[I].getGenericTypeIndex();
1096e6d15924SDimitry Andric Types.resize(std::max(TypeIdx + 1, Types.size()));
1097e6d15924SDimitry Andric
1098e6d15924SDimitry Andric const MachineOperand *MO = &MI->getOperand(I);
1099e6d15924SDimitry Andric if (!MO->isReg()) {
1100e6d15924SDimitry Andric report("generic instruction must use register operands", MI);
1101e6d15924SDimitry Andric continue;
1102e6d15924SDimitry Andric }
1103e6d15924SDimitry Andric
1104e6d15924SDimitry Andric LLT OpTy = MRI->getType(MO->getReg());
1105e6d15924SDimitry Andric // Don't report a type mismatch if there is no actual mismatch, only a
1106e6d15924SDimitry Andric // type missing, to reduce noise:
1107e6d15924SDimitry Andric if (OpTy.isValid()) {
1108e6d15924SDimitry Andric // Only the first valid type for a type index will be printed: don't
1109e6d15924SDimitry Andric // overwrite it later so it's always clear which type was expected:
1110e6d15924SDimitry Andric if (!Types[TypeIdx].isValid())
1111e6d15924SDimitry Andric Types[TypeIdx] = OpTy;
1112e6d15924SDimitry Andric else if (Types[TypeIdx] != OpTy)
1113e6d15924SDimitry Andric report("Type mismatch in generic instruction", MO, I, OpTy);
1114e6d15924SDimitry Andric } else {
1115e6d15924SDimitry Andric // Generic instructions must have types attached to their operands.
1116e6d15924SDimitry Andric report("Generic instruction is missing a virtual register type", MO, I);
1117e6d15924SDimitry Andric }
1118e6d15924SDimitry Andric }
1119e6d15924SDimitry Andric
1120e6d15924SDimitry Andric // Generic opcodes must not have physical register operands.
1121e6d15924SDimitry Andric for (unsigned I = 0; I < MI->getNumOperands(); ++I) {
1122e6d15924SDimitry Andric const MachineOperand *MO = &MI->getOperand(I);
1123e3b55780SDimitry Andric if (MO->isReg() && MO->getReg().isPhysical())
1124e6d15924SDimitry Andric report("Generic instruction cannot have physical register", MO, I);
1125e6d15924SDimitry Andric }
1126e6d15924SDimitry Andric
1127e6d15924SDimitry Andric // Avoid out of bounds in checks below. This was already reported earlier.
1128e6d15924SDimitry Andric if (MI->getNumOperands() < MCID.getNumOperands())
1129e6d15924SDimitry Andric return;
1130e6d15924SDimitry Andric
1131e6d15924SDimitry Andric StringRef ErrorInfo;
1132e6d15924SDimitry Andric if (!TII->verifyInstruction(*MI, ErrorInfo))
1133e6d15924SDimitry Andric report(ErrorInfo.data(), MI);
1134e6d15924SDimitry Andric
1135e6d15924SDimitry Andric // Verify properties of various specific instruction types
1136344a3780SDimitry Andric unsigned Opc = MI->getOpcode();
1137344a3780SDimitry Andric switch (Opc) {
1138344a3780SDimitry Andric case TargetOpcode::G_ASSERT_SEXT:
1139344a3780SDimitry Andric case TargetOpcode::G_ASSERT_ZEXT: {
1140344a3780SDimitry Andric std::string OpcName =
1141344a3780SDimitry Andric Opc == TargetOpcode::G_ASSERT_ZEXT ? "G_ASSERT_ZEXT" : "G_ASSERT_SEXT";
1142344a3780SDimitry Andric if (!MI->getOperand(2).isImm()) {
1143344a3780SDimitry Andric report(Twine(OpcName, " expects an immediate operand #2"), MI);
1144344a3780SDimitry Andric break;
1145344a3780SDimitry Andric }
1146344a3780SDimitry Andric
1147344a3780SDimitry Andric Register Dst = MI->getOperand(0).getReg();
1148344a3780SDimitry Andric Register Src = MI->getOperand(1).getReg();
1149344a3780SDimitry Andric LLT SrcTy = MRI->getType(Src);
1150344a3780SDimitry Andric int64_t Imm = MI->getOperand(2).getImm();
1151344a3780SDimitry Andric if (Imm <= 0) {
1152344a3780SDimitry Andric report(Twine(OpcName, " size must be >= 1"), MI);
1153344a3780SDimitry Andric break;
1154344a3780SDimitry Andric }
1155344a3780SDimitry Andric
1156344a3780SDimitry Andric if (Imm >= SrcTy.getScalarSizeInBits()) {
1157344a3780SDimitry Andric report(Twine(OpcName, " size must be less than source bit width"), MI);
1158344a3780SDimitry Andric break;
1159344a3780SDimitry Andric }
1160344a3780SDimitry Andric
1161145449b1SDimitry Andric const RegisterBank *SrcRB = RBI->getRegBank(Src, *MRI, *TRI);
1162145449b1SDimitry Andric const RegisterBank *DstRB = RBI->getRegBank(Dst, *MRI, *TRI);
1163145449b1SDimitry Andric
1164145449b1SDimitry Andric // Allow only the source bank to be set.
1165145449b1SDimitry Andric if ((SrcRB && DstRB && SrcRB != DstRB) || (DstRB && !SrcRB)) {
1166145449b1SDimitry Andric report(Twine(OpcName, " cannot change register bank"), MI);
1167344a3780SDimitry Andric break;
1168344a3780SDimitry Andric }
1169344a3780SDimitry Andric
1170145449b1SDimitry Andric // Don't allow a class change. Do allow member class->regbank.
1171145449b1SDimitry Andric const TargetRegisterClass *DstRC = MRI->getRegClassOrNull(Dst);
1172145449b1SDimitry Andric if (DstRC && DstRC != MRI->getRegClassOrNull(Src)) {
1173344a3780SDimitry Andric report(
1174344a3780SDimitry Andric Twine(OpcName, " source and destination register classes must match"),
1175344a3780SDimitry Andric MI);
1176145449b1SDimitry Andric break;
1177145449b1SDimitry Andric }
1178344a3780SDimitry Andric
1179344a3780SDimitry Andric break;
1180344a3780SDimitry Andric }
1181344a3780SDimitry Andric
1182e6d15924SDimitry Andric case TargetOpcode::G_CONSTANT:
1183e6d15924SDimitry Andric case TargetOpcode::G_FCONSTANT: {
1184e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1185e6d15924SDimitry Andric if (DstTy.isVector())
1186e6d15924SDimitry Andric report("Instruction cannot use a vector result type", MI);
1187e6d15924SDimitry Andric
1188e6d15924SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_CONSTANT) {
1189e6d15924SDimitry Andric if (!MI->getOperand(1).isCImm()) {
1190e6d15924SDimitry Andric report("G_CONSTANT operand must be cimm", MI);
1191e6d15924SDimitry Andric break;
1192e6d15924SDimitry Andric }
1193e6d15924SDimitry Andric
1194e6d15924SDimitry Andric const ConstantInt *CI = MI->getOperand(1).getCImm();
1195e6d15924SDimitry Andric if (CI->getBitWidth() != DstTy.getSizeInBits())
1196e6d15924SDimitry Andric report("inconsistent constant size", MI);
1197e6d15924SDimitry Andric } else {
1198e6d15924SDimitry Andric if (!MI->getOperand(1).isFPImm()) {
1199e6d15924SDimitry Andric report("G_FCONSTANT operand must be fpimm", MI);
1200e6d15924SDimitry Andric break;
1201e6d15924SDimitry Andric }
1202e6d15924SDimitry Andric const ConstantFP *CF = MI->getOperand(1).getFPImm();
1203e6d15924SDimitry Andric
1204e6d15924SDimitry Andric if (APFloat::getSizeInBits(CF->getValueAPF().getSemantics()) !=
1205e6d15924SDimitry Andric DstTy.getSizeInBits()) {
1206e6d15924SDimitry Andric report("inconsistent constant size", MI);
1207e6d15924SDimitry Andric }
1208e6d15924SDimitry Andric }
1209e6d15924SDimitry Andric
1210e6d15924SDimitry Andric break;
1211e6d15924SDimitry Andric }
1212e6d15924SDimitry Andric case TargetOpcode::G_LOAD:
1213e6d15924SDimitry Andric case TargetOpcode::G_STORE:
1214e6d15924SDimitry Andric case TargetOpcode::G_ZEXTLOAD:
1215e6d15924SDimitry Andric case TargetOpcode::G_SEXTLOAD: {
1216e6d15924SDimitry Andric LLT ValTy = MRI->getType(MI->getOperand(0).getReg());
1217e6d15924SDimitry Andric LLT PtrTy = MRI->getType(MI->getOperand(1).getReg());
1218e6d15924SDimitry Andric if (!PtrTy.isPointer())
1219e6d15924SDimitry Andric report("Generic memory instruction must access a pointer", MI);
1220e6d15924SDimitry Andric
1221e6d15924SDimitry Andric // Generic loads and stores must have a single MachineMemOperand
1222e6d15924SDimitry Andric // describing that access.
1223e6d15924SDimitry Andric if (!MI->hasOneMemOperand()) {
1224e6d15924SDimitry Andric report("Generic instruction accessing memory must have one mem operand",
1225e6d15924SDimitry Andric MI);
1226e6d15924SDimitry Andric } else {
1227e6d15924SDimitry Andric const MachineMemOperand &MMO = **MI->memoperands_begin();
1228e6d15924SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_ZEXTLOAD ||
1229e6d15924SDimitry Andric MI->getOpcode() == TargetOpcode::G_SEXTLOAD) {
1230ac9a064cSDimitry Andric if (TypeSize::isKnownGE(MMO.getSizeInBits().getValue(),
1231ac9a064cSDimitry Andric ValTy.getSizeInBits()))
1232e6d15924SDimitry Andric report("Generic extload must have a narrower memory type", MI);
1233e6d15924SDimitry Andric } else if (MI->getOpcode() == TargetOpcode::G_LOAD) {
1234ac9a064cSDimitry Andric if (TypeSize::isKnownGT(MMO.getSize().getValue(),
1235ac9a064cSDimitry Andric ValTy.getSizeInBytes()))
1236e6d15924SDimitry Andric report("load memory size cannot exceed result size", MI);
1237e6d15924SDimitry Andric } else if (MI->getOpcode() == TargetOpcode::G_STORE) {
1238ac9a064cSDimitry Andric if (TypeSize::isKnownLT(ValTy.getSizeInBytes(),
1239ac9a064cSDimitry Andric MMO.getSize().getValue()))
1240e6d15924SDimitry Andric report("store memory size cannot exceed value size", MI);
1241e6d15924SDimitry Andric }
1242145449b1SDimitry Andric
1243145449b1SDimitry Andric const AtomicOrdering Order = MMO.getSuccessOrdering();
1244145449b1SDimitry Andric if (Opc == TargetOpcode::G_STORE) {
1245145449b1SDimitry Andric if (Order == AtomicOrdering::Acquire ||
1246145449b1SDimitry Andric Order == AtomicOrdering::AcquireRelease)
1247145449b1SDimitry Andric report("atomic store cannot use acquire ordering", MI);
1248145449b1SDimitry Andric
1249145449b1SDimitry Andric } else {
1250145449b1SDimitry Andric if (Order == AtomicOrdering::Release ||
1251145449b1SDimitry Andric Order == AtomicOrdering::AcquireRelease)
1252145449b1SDimitry Andric report("atomic load cannot use release ordering", MI);
1253145449b1SDimitry Andric }
1254e6d15924SDimitry Andric }
1255e6d15924SDimitry Andric
1256e6d15924SDimitry Andric break;
1257e6d15924SDimitry Andric }
1258e6d15924SDimitry Andric case TargetOpcode::G_PHI: {
1259e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1260b60736ecSDimitry Andric if (!DstTy.isValid() || !all_of(drop_begin(MI->operands()),
1261e6d15924SDimitry Andric [this, &DstTy](const MachineOperand &MO) {
1262e6d15924SDimitry Andric if (!MO.isReg())
1263e6d15924SDimitry Andric return true;
1264e6d15924SDimitry Andric LLT Ty = MRI->getType(MO.getReg());
1265e6d15924SDimitry Andric if (!Ty.isValid() || (Ty != DstTy))
1266e6d15924SDimitry Andric return false;
1267e6d15924SDimitry Andric return true;
1268e6d15924SDimitry Andric }))
1269e6d15924SDimitry Andric report("Generic Instruction G_PHI has operands with incompatible/missing "
1270e6d15924SDimitry Andric "types",
1271e6d15924SDimitry Andric MI);
1272e6d15924SDimitry Andric break;
1273e6d15924SDimitry Andric }
1274e6d15924SDimitry Andric case TargetOpcode::G_BITCAST: {
1275e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1276e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1277e6d15924SDimitry Andric if (!DstTy.isValid() || !SrcTy.isValid())
1278e6d15924SDimitry Andric break;
1279e6d15924SDimitry Andric
1280e6d15924SDimitry Andric if (SrcTy.isPointer() != DstTy.isPointer())
1281e6d15924SDimitry Andric report("bitcast cannot convert between pointers and other types", MI);
1282e6d15924SDimitry Andric
1283e6d15924SDimitry Andric if (SrcTy.getSizeInBits() != DstTy.getSizeInBits())
1284e6d15924SDimitry Andric report("bitcast sizes must match", MI);
1285cfca06d7SDimitry Andric
1286cfca06d7SDimitry Andric if (SrcTy == DstTy)
1287cfca06d7SDimitry Andric report("bitcast must change the type", MI);
1288cfca06d7SDimitry Andric
1289e6d15924SDimitry Andric break;
1290e6d15924SDimitry Andric }
1291e6d15924SDimitry Andric case TargetOpcode::G_INTTOPTR:
1292e6d15924SDimitry Andric case TargetOpcode::G_PTRTOINT:
1293e6d15924SDimitry Andric case TargetOpcode::G_ADDRSPACE_CAST: {
1294e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1295e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1296e6d15924SDimitry Andric if (!DstTy.isValid() || !SrcTy.isValid())
1297e6d15924SDimitry Andric break;
1298e6d15924SDimitry Andric
1299e6d15924SDimitry Andric verifyVectorElementMatch(DstTy, SrcTy, MI);
1300e6d15924SDimitry Andric
1301e6d15924SDimitry Andric DstTy = DstTy.getScalarType();
1302e6d15924SDimitry Andric SrcTy = SrcTy.getScalarType();
1303e6d15924SDimitry Andric
1304e6d15924SDimitry Andric if (MI->getOpcode() == TargetOpcode::G_INTTOPTR) {
1305e6d15924SDimitry Andric if (!DstTy.isPointer())
1306e6d15924SDimitry Andric report("inttoptr result type must be a pointer", MI);
1307e6d15924SDimitry Andric if (SrcTy.isPointer())
1308e6d15924SDimitry Andric report("inttoptr source type must not be a pointer", MI);
1309e6d15924SDimitry Andric } else if (MI->getOpcode() == TargetOpcode::G_PTRTOINT) {
1310e6d15924SDimitry Andric if (!SrcTy.isPointer())
1311e6d15924SDimitry Andric report("ptrtoint source type must be a pointer", MI);
1312e6d15924SDimitry Andric if (DstTy.isPointer())
1313e6d15924SDimitry Andric report("ptrtoint result type must not be a pointer", MI);
1314e6d15924SDimitry Andric } else {
1315e6d15924SDimitry Andric assert(MI->getOpcode() == TargetOpcode::G_ADDRSPACE_CAST);
1316e6d15924SDimitry Andric if (!SrcTy.isPointer() || !DstTy.isPointer())
1317e6d15924SDimitry Andric report("addrspacecast types must be pointers", MI);
1318e6d15924SDimitry Andric else {
1319e6d15924SDimitry Andric if (SrcTy.getAddressSpace() == DstTy.getAddressSpace())
1320e6d15924SDimitry Andric report("addrspacecast must convert different address spaces", MI);
1321e6d15924SDimitry Andric }
1322e6d15924SDimitry Andric }
1323e6d15924SDimitry Andric
1324e6d15924SDimitry Andric break;
1325e6d15924SDimitry Andric }
1326706b4fc4SDimitry Andric case TargetOpcode::G_PTR_ADD: {
1327e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1328e6d15924SDimitry Andric LLT PtrTy = MRI->getType(MI->getOperand(1).getReg());
1329e6d15924SDimitry Andric LLT OffsetTy = MRI->getType(MI->getOperand(2).getReg());
1330e6d15924SDimitry Andric if (!DstTy.isValid() || !PtrTy.isValid() || !OffsetTy.isValid())
1331e6d15924SDimitry Andric break;
1332e6d15924SDimitry Andric
1333ac9a064cSDimitry Andric if (!PtrTy.isPointerOrPointerVector())
1334e6d15924SDimitry Andric report("gep first operand must be a pointer", MI);
1335e6d15924SDimitry Andric
1336ac9a064cSDimitry Andric if (OffsetTy.isPointerOrPointerVector())
1337e6d15924SDimitry Andric report("gep offset operand must not be a pointer", MI);
1338e6d15924SDimitry Andric
1339ac9a064cSDimitry Andric if (PtrTy.isPointerOrPointerVector()) {
1340ac9a064cSDimitry Andric const DataLayout &DL = MF->getDataLayout();
1341ac9a064cSDimitry Andric unsigned AS = PtrTy.getAddressSpace();
1342ac9a064cSDimitry Andric unsigned IndexSizeInBits = DL.getIndexSize(AS) * 8;
1343ac9a064cSDimitry Andric if (OffsetTy.getScalarSizeInBits() != IndexSizeInBits) {
1344ac9a064cSDimitry Andric report("gep offset operand must match index size for address space",
1345ac9a064cSDimitry Andric MI);
1346ac9a064cSDimitry Andric }
1347ac9a064cSDimitry Andric }
1348ac9a064cSDimitry Andric
1349e6d15924SDimitry Andric // TODO: Is the offset allowed to be a scalar with a vector?
1350e6d15924SDimitry Andric break;
1351e6d15924SDimitry Andric }
1352cfca06d7SDimitry Andric case TargetOpcode::G_PTRMASK: {
1353cfca06d7SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1354cfca06d7SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1355cfca06d7SDimitry Andric LLT MaskTy = MRI->getType(MI->getOperand(2).getReg());
1356cfca06d7SDimitry Andric if (!DstTy.isValid() || !SrcTy.isValid() || !MaskTy.isValid())
1357cfca06d7SDimitry Andric break;
1358cfca06d7SDimitry Andric
1359ac9a064cSDimitry Andric if (!DstTy.isPointerOrPointerVector())
1360cfca06d7SDimitry Andric report("ptrmask result type must be a pointer", MI);
1361cfca06d7SDimitry Andric
1362cfca06d7SDimitry Andric if (!MaskTy.getScalarType().isScalar())
1363cfca06d7SDimitry Andric report("ptrmask mask type must be an integer", MI);
1364cfca06d7SDimitry Andric
1365cfca06d7SDimitry Andric verifyVectorElementMatch(DstTy, MaskTy, MI);
1366cfca06d7SDimitry Andric break;
1367cfca06d7SDimitry Andric }
1368e6d15924SDimitry Andric case TargetOpcode::G_SEXT:
1369e6d15924SDimitry Andric case TargetOpcode::G_ZEXT:
1370e6d15924SDimitry Andric case TargetOpcode::G_ANYEXT:
1371e6d15924SDimitry Andric case TargetOpcode::G_TRUNC:
1372e6d15924SDimitry Andric case TargetOpcode::G_FPEXT:
1373e6d15924SDimitry Andric case TargetOpcode::G_FPTRUNC: {
1374e6d15924SDimitry Andric // Number of operands and presense of types is already checked (and
1375e6d15924SDimitry Andric // reported in case of any issues), so no need to report them again. As
1376e6d15924SDimitry Andric // we're trying to report as many issues as possible at once, however, the
1377e6d15924SDimitry Andric // instructions aren't guaranteed to have the right number of operands or
1378e6d15924SDimitry Andric // types attached to them at this point
1379e6d15924SDimitry Andric assert(MCID.getNumOperands() == 2 && "Expected 2 operands G_*{EXT,TRUNC}");
1380e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1381e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1382e6d15924SDimitry Andric if (!DstTy.isValid() || !SrcTy.isValid())
1383e6d15924SDimitry Andric break;
1384e6d15924SDimitry Andric
1385ac9a064cSDimitry Andric if (DstTy.isPointerOrPointerVector() || SrcTy.isPointerOrPointerVector())
1386e6d15924SDimitry Andric report("Generic extend/truncate can not operate on pointers", MI);
1387e6d15924SDimitry Andric
1388e6d15924SDimitry Andric verifyVectorElementMatch(DstTy, SrcTy, MI);
1389e6d15924SDimitry Andric
1390ac9a064cSDimitry Andric unsigned DstSize = DstTy.getScalarSizeInBits();
1391ac9a064cSDimitry Andric unsigned SrcSize = SrcTy.getScalarSizeInBits();
1392e6d15924SDimitry Andric switch (MI->getOpcode()) {
1393e6d15924SDimitry Andric default:
1394e6d15924SDimitry Andric if (DstSize <= SrcSize)
1395e6d15924SDimitry Andric report("Generic extend has destination type no larger than source", MI);
1396e6d15924SDimitry Andric break;
1397e6d15924SDimitry Andric case TargetOpcode::G_TRUNC:
1398e6d15924SDimitry Andric case TargetOpcode::G_FPTRUNC:
1399e6d15924SDimitry Andric if (DstSize >= SrcSize)
1400e6d15924SDimitry Andric report("Generic truncate has destination type no smaller than source",
1401e6d15924SDimitry Andric MI);
1402e6d15924SDimitry Andric break;
1403e6d15924SDimitry Andric }
1404e6d15924SDimitry Andric break;
1405e6d15924SDimitry Andric }
1406e6d15924SDimitry Andric case TargetOpcode::G_SELECT: {
1407e6d15924SDimitry Andric LLT SelTy = MRI->getType(MI->getOperand(0).getReg());
1408e6d15924SDimitry Andric LLT CondTy = MRI->getType(MI->getOperand(1).getReg());
1409e6d15924SDimitry Andric if (!SelTy.isValid() || !CondTy.isValid())
1410e6d15924SDimitry Andric break;
1411e6d15924SDimitry Andric
1412e6d15924SDimitry Andric // Scalar condition select on a vector is valid.
1413e6d15924SDimitry Andric if (CondTy.isVector())
1414e6d15924SDimitry Andric verifyVectorElementMatch(SelTy, CondTy, MI);
1415e6d15924SDimitry Andric break;
1416e6d15924SDimitry Andric }
1417e6d15924SDimitry Andric case TargetOpcode::G_MERGE_VALUES: {
1418e6d15924SDimitry Andric // G_MERGE_VALUES should only be used to merge scalars into a larger scalar,
1419e6d15924SDimitry Andric // e.g. s2N = MERGE sN, sN
1420e6d15924SDimitry Andric // Merging multiple scalars into a vector is not allowed, should use
1421e6d15924SDimitry Andric // G_BUILD_VECTOR for that.
1422e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1423e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1424e6d15924SDimitry Andric if (DstTy.isVector() || SrcTy.isVector())
1425e6d15924SDimitry Andric report("G_MERGE_VALUES cannot operate on vectors", MI);
1426e6d15924SDimitry Andric
1427e6d15924SDimitry Andric const unsigned NumOps = MI->getNumOperands();
1428e6d15924SDimitry Andric if (DstTy.getSizeInBits() != SrcTy.getSizeInBits() * (NumOps - 1))
1429e6d15924SDimitry Andric report("G_MERGE_VALUES result size is inconsistent", MI);
1430e6d15924SDimitry Andric
1431e6d15924SDimitry Andric for (unsigned I = 2; I != NumOps; ++I) {
1432e6d15924SDimitry Andric if (MRI->getType(MI->getOperand(I).getReg()) != SrcTy)
1433e6d15924SDimitry Andric report("G_MERGE_VALUES source types do not match", MI);
1434e6d15924SDimitry Andric }
1435e6d15924SDimitry Andric
1436e6d15924SDimitry Andric break;
1437e6d15924SDimitry Andric }
1438e6d15924SDimitry Andric case TargetOpcode::G_UNMERGE_VALUES: {
1439e3b55780SDimitry Andric unsigned NumDsts = MI->getNumOperands() - 1;
1440e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1441e3b55780SDimitry Andric for (unsigned i = 1; i < NumDsts; ++i) {
1442e3b55780SDimitry Andric if (MRI->getType(MI->getOperand(i).getReg()) != DstTy) {
1443e6d15924SDimitry Andric report("G_UNMERGE_VALUES destination types do not match", MI);
1444e3b55780SDimitry Andric break;
1445e6d15924SDimitry Andric }
1446e3b55780SDimitry Andric }
1447e3b55780SDimitry Andric
1448e3b55780SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(NumDsts).getReg());
1449e3b55780SDimitry Andric if (DstTy.isVector()) {
1450e3b55780SDimitry Andric // This case is the converse of G_CONCAT_VECTORS.
1451e3b55780SDimitry Andric if (!SrcTy.isVector() || SrcTy.getScalarType() != DstTy.getScalarType() ||
1452ac9a064cSDimitry Andric SrcTy.isScalableVector() != DstTy.isScalableVector() ||
1453ac9a064cSDimitry Andric SrcTy.getSizeInBits() != NumDsts * DstTy.getSizeInBits())
1454e3b55780SDimitry Andric report("G_UNMERGE_VALUES source operand does not match vector "
1455e3b55780SDimitry Andric "destination operands",
1456e6d15924SDimitry Andric MI);
1457e3b55780SDimitry Andric } else if (SrcTy.isVector()) {
1458e3b55780SDimitry Andric // This case is the converse of G_BUILD_VECTOR, but relaxed to allow
1459e3b55780SDimitry Andric // mismatched types as long as the total size matches:
1460e3b55780SDimitry Andric // %0:_(s64), %1:_(s64) = G_UNMERGE_VALUES %2:_(<4 x s32>)
1461e3b55780SDimitry Andric if (SrcTy.getSizeInBits() != NumDsts * DstTy.getSizeInBits())
1462e3b55780SDimitry Andric report("G_UNMERGE_VALUES vector source operand does not match scalar "
1463e3b55780SDimitry Andric "destination operands",
1464e3b55780SDimitry Andric MI);
1465e3b55780SDimitry Andric } else {
1466e3b55780SDimitry Andric // This case is the converse of G_MERGE_VALUES.
1467e3b55780SDimitry Andric if (SrcTy.getSizeInBits() != NumDsts * DstTy.getSizeInBits()) {
1468e3b55780SDimitry Andric report("G_UNMERGE_VALUES scalar source operand does not match scalar "
1469e3b55780SDimitry Andric "destination operands",
1470e3b55780SDimitry Andric MI);
1471e3b55780SDimitry Andric }
1472e6d15924SDimitry Andric }
1473e6d15924SDimitry Andric break;
1474e6d15924SDimitry Andric }
1475e6d15924SDimitry Andric case TargetOpcode::G_BUILD_VECTOR: {
1476e6d15924SDimitry Andric // Source types must be scalars, dest type a vector. Total size of scalars
1477e6d15924SDimitry Andric // must match the dest vector size.
1478e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1479e6d15924SDimitry Andric LLT SrcEltTy = MRI->getType(MI->getOperand(1).getReg());
1480e6d15924SDimitry Andric if (!DstTy.isVector() || SrcEltTy.isVector()) {
1481e6d15924SDimitry Andric report("G_BUILD_VECTOR must produce a vector from scalar operands", MI);
1482e6d15924SDimitry Andric break;
1483e6d15924SDimitry Andric }
1484e6d15924SDimitry Andric
1485e6d15924SDimitry Andric if (DstTy.getElementType() != SrcEltTy)
1486e6d15924SDimitry Andric report("G_BUILD_VECTOR result element type must match source type", MI);
1487e6d15924SDimitry Andric
1488e6d15924SDimitry Andric if (DstTy.getNumElements() != MI->getNumOperands() - 1)
1489e6d15924SDimitry Andric report("G_BUILD_VECTOR must have an operand for each elemement", MI);
1490e6d15924SDimitry Andric
1491f65dcba8SDimitry Andric for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
1492f65dcba8SDimitry Andric if (MRI->getType(MI->getOperand(1).getReg()) != MRI->getType(MO.getReg()))
1493e6d15924SDimitry Andric report("G_BUILD_VECTOR source operand types are not homogeneous", MI);
1494e6d15924SDimitry Andric
1495e6d15924SDimitry Andric break;
1496e6d15924SDimitry Andric }
1497e6d15924SDimitry Andric case TargetOpcode::G_BUILD_VECTOR_TRUNC: {
1498e6d15924SDimitry Andric // Source types must be scalars, dest type a vector. Scalar types must be
1499e6d15924SDimitry Andric // larger than the dest vector elt type, as this is a truncating operation.
1500e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1501e6d15924SDimitry Andric LLT SrcEltTy = MRI->getType(MI->getOperand(1).getReg());
1502e6d15924SDimitry Andric if (!DstTy.isVector() || SrcEltTy.isVector())
1503e6d15924SDimitry Andric report("G_BUILD_VECTOR_TRUNC must produce a vector from scalar operands",
1504e6d15924SDimitry Andric MI);
1505f65dcba8SDimitry Andric for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
1506f65dcba8SDimitry Andric if (MRI->getType(MI->getOperand(1).getReg()) != MRI->getType(MO.getReg()))
1507e6d15924SDimitry Andric report("G_BUILD_VECTOR_TRUNC source operand types are not homogeneous",
1508e6d15924SDimitry Andric MI);
1509e6d15924SDimitry Andric if (SrcEltTy.getSizeInBits() <= DstTy.getElementType().getSizeInBits())
1510e6d15924SDimitry Andric report("G_BUILD_VECTOR_TRUNC source operand types are not larger than "
1511e6d15924SDimitry Andric "dest elt type",
1512e6d15924SDimitry Andric MI);
1513e6d15924SDimitry Andric break;
1514e6d15924SDimitry Andric }
1515e6d15924SDimitry Andric case TargetOpcode::G_CONCAT_VECTORS: {
1516e6d15924SDimitry Andric // Source types should be vectors, and total size should match the dest
1517e6d15924SDimitry Andric // vector size.
1518e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1519e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1520e6d15924SDimitry Andric if (!DstTy.isVector() || !SrcTy.isVector())
1521e6d15924SDimitry Andric report("G_CONCAT_VECTOR requires vector source and destination operands",
1522e6d15924SDimitry Andric MI);
1523344a3780SDimitry Andric
1524344a3780SDimitry Andric if (MI->getNumOperands() < 3)
1525344a3780SDimitry Andric report("G_CONCAT_VECTOR requires at least 2 source operands", MI);
1526344a3780SDimitry Andric
1527f65dcba8SDimitry Andric for (const MachineOperand &MO : llvm::drop_begin(MI->operands(), 2))
1528f65dcba8SDimitry Andric if (MRI->getType(MI->getOperand(1).getReg()) != MRI->getType(MO.getReg()))
1529e6d15924SDimitry Andric report("G_CONCAT_VECTOR source operand types are not homogeneous", MI);
1530ac9a064cSDimitry Andric if (DstTy.getElementCount() !=
1531ac9a064cSDimitry Andric SrcTy.getElementCount() * (MI->getNumOperands() - 1))
1532e6d15924SDimitry Andric report("G_CONCAT_VECTOR num dest and source elements should match", MI);
1533e6d15924SDimitry Andric break;
1534e6d15924SDimitry Andric }
1535e6d15924SDimitry Andric case TargetOpcode::G_ICMP:
1536e6d15924SDimitry Andric case TargetOpcode::G_FCMP: {
1537e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1538e6d15924SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(2).getReg());
1539e6d15924SDimitry Andric
1540e6d15924SDimitry Andric if ((DstTy.isVector() != SrcTy.isVector()) ||
1541ac9a064cSDimitry Andric (DstTy.isVector() &&
1542ac9a064cSDimitry Andric DstTy.getElementCount() != SrcTy.getElementCount()))
1543e6d15924SDimitry Andric report("Generic vector icmp/fcmp must preserve number of lanes", MI);
1544e6d15924SDimitry Andric
1545e6d15924SDimitry Andric break;
1546e6d15924SDimitry Andric }
1547ac9a064cSDimitry Andric case TargetOpcode::G_SCMP:
1548ac9a064cSDimitry Andric case TargetOpcode::G_UCMP: {
1549ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1550ac9a064cSDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1551ac9a064cSDimitry Andric LLT SrcTy2 = MRI->getType(MI->getOperand(2).getReg());
1552ac9a064cSDimitry Andric
1553ac9a064cSDimitry Andric if (SrcTy.isPointerOrPointerVector() || SrcTy2.isPointerOrPointerVector()) {
1554ac9a064cSDimitry Andric report("Generic scmp/ucmp does not support pointers as operands", MI);
1555ac9a064cSDimitry Andric break;
1556ac9a064cSDimitry Andric }
1557ac9a064cSDimitry Andric
1558ac9a064cSDimitry Andric if (DstTy.isPointerOrPointerVector()) {
1559ac9a064cSDimitry Andric report("Generic scmp/ucmp does not support pointers as a result", MI);
1560ac9a064cSDimitry Andric break;
1561ac9a064cSDimitry Andric }
1562ac9a064cSDimitry Andric
1563ac9a064cSDimitry Andric if ((DstTy.isVector() != SrcTy.isVector()) ||
1564ac9a064cSDimitry Andric (DstTy.isVector() &&
1565ac9a064cSDimitry Andric DstTy.getElementCount() != SrcTy.getElementCount())) {
1566ac9a064cSDimitry Andric report("Generic vector scmp/ucmp must preserve number of lanes", MI);
1567ac9a064cSDimitry Andric break;
1568ac9a064cSDimitry Andric }
1569ac9a064cSDimitry Andric
1570ac9a064cSDimitry Andric if (SrcTy != SrcTy2) {
1571ac9a064cSDimitry Andric report("Generic scmp/ucmp must have same input types", MI);
1572ac9a064cSDimitry Andric break;
1573ac9a064cSDimitry Andric }
1574ac9a064cSDimitry Andric
1575ac9a064cSDimitry Andric break;
1576ac9a064cSDimitry Andric }
1577e6d15924SDimitry Andric case TargetOpcode::G_EXTRACT: {
1578e6d15924SDimitry Andric const MachineOperand &SrcOp = MI->getOperand(1);
1579e6d15924SDimitry Andric if (!SrcOp.isReg()) {
1580e6d15924SDimitry Andric report("extract source must be a register", MI);
1581e6d15924SDimitry Andric break;
1582e6d15924SDimitry Andric }
1583e6d15924SDimitry Andric
1584e6d15924SDimitry Andric const MachineOperand &OffsetOp = MI->getOperand(2);
1585e6d15924SDimitry Andric if (!OffsetOp.isImm()) {
1586e6d15924SDimitry Andric report("extract offset must be a constant", MI);
1587e6d15924SDimitry Andric break;
1588e6d15924SDimitry Andric }
1589e6d15924SDimitry Andric
1590e6d15924SDimitry Andric unsigned DstSize = MRI->getType(MI->getOperand(0).getReg()).getSizeInBits();
1591e6d15924SDimitry Andric unsigned SrcSize = MRI->getType(SrcOp.getReg()).getSizeInBits();
1592e6d15924SDimitry Andric if (SrcSize == DstSize)
1593e6d15924SDimitry Andric report("extract source must be larger than result", MI);
1594e6d15924SDimitry Andric
1595e6d15924SDimitry Andric if (DstSize + OffsetOp.getImm() > SrcSize)
1596e6d15924SDimitry Andric report("extract reads past end of register", MI);
1597e6d15924SDimitry Andric break;
1598e6d15924SDimitry Andric }
1599e6d15924SDimitry Andric case TargetOpcode::G_INSERT: {
1600e6d15924SDimitry Andric const MachineOperand &SrcOp = MI->getOperand(2);
1601e6d15924SDimitry Andric if (!SrcOp.isReg()) {
1602e6d15924SDimitry Andric report("insert source must be a register", MI);
1603e6d15924SDimitry Andric break;
1604e6d15924SDimitry Andric }
1605e6d15924SDimitry Andric
1606e6d15924SDimitry Andric const MachineOperand &OffsetOp = MI->getOperand(3);
1607e6d15924SDimitry Andric if (!OffsetOp.isImm()) {
1608e6d15924SDimitry Andric report("insert offset must be a constant", MI);
1609e6d15924SDimitry Andric break;
1610e6d15924SDimitry Andric }
1611e6d15924SDimitry Andric
1612e6d15924SDimitry Andric unsigned DstSize = MRI->getType(MI->getOperand(0).getReg()).getSizeInBits();
1613e6d15924SDimitry Andric unsigned SrcSize = MRI->getType(SrcOp.getReg()).getSizeInBits();
1614e6d15924SDimitry Andric
1615e6d15924SDimitry Andric if (DstSize <= SrcSize)
1616e6d15924SDimitry Andric report("inserted size must be smaller than total register", MI);
1617e6d15924SDimitry Andric
1618e6d15924SDimitry Andric if (SrcSize + OffsetOp.getImm() > DstSize)
1619e6d15924SDimitry Andric report("insert writes past end of register", MI);
1620e6d15924SDimitry Andric
1621e6d15924SDimitry Andric break;
1622e6d15924SDimitry Andric }
1623e6d15924SDimitry Andric case TargetOpcode::G_JUMP_TABLE: {
1624e6d15924SDimitry Andric if (!MI->getOperand(1).isJTI())
1625e6d15924SDimitry Andric report("G_JUMP_TABLE source operand must be a jump table index", MI);
1626e6d15924SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1627e6d15924SDimitry Andric if (!DstTy.isPointer())
1628e6d15924SDimitry Andric report("G_JUMP_TABLE dest operand must have a pointer type", MI);
1629e6d15924SDimitry Andric break;
1630e6d15924SDimitry Andric }
1631e6d15924SDimitry Andric case TargetOpcode::G_BRJT: {
1632e6d15924SDimitry Andric if (!MRI->getType(MI->getOperand(0).getReg()).isPointer())
1633e6d15924SDimitry Andric report("G_BRJT src operand 0 must be a pointer type", MI);
1634e6d15924SDimitry Andric
1635e6d15924SDimitry Andric if (!MI->getOperand(1).isJTI())
1636e6d15924SDimitry Andric report("G_BRJT src operand 1 must be a jump table index", MI);
1637e6d15924SDimitry Andric
1638e6d15924SDimitry Andric const auto &IdxOp = MI->getOperand(2);
1639e6d15924SDimitry Andric if (!IdxOp.isReg() || MRI->getType(IdxOp.getReg()).isPointer())
1640e6d15924SDimitry Andric report("G_BRJT src operand 2 must be a scalar reg type", MI);
1641e6d15924SDimitry Andric break;
1642e6d15924SDimitry Andric }
1643e6d15924SDimitry Andric case TargetOpcode::G_INTRINSIC:
1644b1c73532SDimitry Andric case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
1645b1c73532SDimitry Andric case TargetOpcode::G_INTRINSIC_CONVERGENT:
1646b1c73532SDimitry Andric case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS: {
1647e6d15924SDimitry Andric // TODO: Should verify number of def and use operands, but the current
1648e6d15924SDimitry Andric // interface requires passing in IR types for mangling.
1649e6d15924SDimitry Andric const MachineOperand &IntrIDOp = MI->getOperand(MI->getNumExplicitDefs());
1650e6d15924SDimitry Andric if (!IntrIDOp.isIntrinsicID()) {
1651e6d15924SDimitry Andric report("G_INTRINSIC first src operand must be an intrinsic ID", MI);
1652e6d15924SDimitry Andric break;
1653e6d15924SDimitry Andric }
1654e6d15924SDimitry Andric
1655b1c73532SDimitry Andric if (!verifyGIntrinsicSideEffects(MI))
1656e6d15924SDimitry Andric break;
1657b1c73532SDimitry Andric if (!verifyGIntrinsicConvergence(MI))
1658e6d15924SDimitry Andric break;
1659b60736ecSDimitry Andric
16601d5ae102SDimitry Andric break;
16611d5ae102SDimitry Andric }
16621d5ae102SDimitry Andric case TargetOpcode::G_SEXT_INREG: {
16631d5ae102SDimitry Andric if (!MI->getOperand(2).isImm()) {
16641d5ae102SDimitry Andric report("G_SEXT_INREG expects an immediate operand #2", MI);
16651d5ae102SDimitry Andric break;
16661d5ae102SDimitry Andric }
1667e6d15924SDimitry Andric
16681d5ae102SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
16691d5ae102SDimitry Andric int64_t Imm = MI->getOperand(2).getImm();
16701d5ae102SDimitry Andric if (Imm <= 0)
16711d5ae102SDimitry Andric report("G_SEXT_INREG size must be >= 1", MI);
16721d5ae102SDimitry Andric if (Imm >= SrcTy.getScalarSizeInBits())
16731d5ae102SDimitry Andric report("G_SEXT_INREG size must be less than source bit width", MI);
16741d5ae102SDimitry Andric break;
16751d5ae102SDimitry Andric }
1676b1c73532SDimitry Andric case TargetOpcode::G_BSWAP: {
1677b1c73532SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1678b1c73532SDimitry Andric if (DstTy.getScalarSizeInBits() % 16 != 0)
1679b1c73532SDimitry Andric report("G_BSWAP size must be a multiple of 16 bits", MI);
1680b1c73532SDimitry Andric break;
1681b1c73532SDimitry Andric }
1682ac9a064cSDimitry Andric case TargetOpcode::G_VSCALE: {
1683ac9a064cSDimitry Andric if (!MI->getOperand(1).isCImm()) {
1684ac9a064cSDimitry Andric report("G_VSCALE operand must be cimm", MI);
1685ac9a064cSDimitry Andric break;
1686ac9a064cSDimitry Andric }
1687ac9a064cSDimitry Andric if (MI->getOperand(1).getCImm()->isZero()) {
1688ac9a064cSDimitry Andric report("G_VSCALE immediate cannot be zero", MI);
1689ac9a064cSDimitry Andric break;
1690ac9a064cSDimitry Andric }
1691ac9a064cSDimitry Andric break;
1692ac9a064cSDimitry Andric }
1693ac9a064cSDimitry Andric case TargetOpcode::G_INSERT_SUBVECTOR: {
1694ac9a064cSDimitry Andric const MachineOperand &Src0Op = MI->getOperand(1);
1695ac9a064cSDimitry Andric if (!Src0Op.isReg()) {
1696ac9a064cSDimitry Andric report("G_INSERT_SUBVECTOR first source must be a register", MI);
1697ac9a064cSDimitry Andric break;
1698ac9a064cSDimitry Andric }
1699ac9a064cSDimitry Andric
1700ac9a064cSDimitry Andric const MachineOperand &Src1Op = MI->getOperand(2);
1701ac9a064cSDimitry Andric if (!Src1Op.isReg()) {
1702ac9a064cSDimitry Andric report("G_INSERT_SUBVECTOR second source must be a register", MI);
1703ac9a064cSDimitry Andric break;
1704ac9a064cSDimitry Andric }
1705ac9a064cSDimitry Andric
1706ac9a064cSDimitry Andric const MachineOperand &IndexOp = MI->getOperand(3);
1707ac9a064cSDimitry Andric if (!IndexOp.isImm()) {
1708ac9a064cSDimitry Andric report("G_INSERT_SUBVECTOR index must be an immediate", MI);
1709ac9a064cSDimitry Andric break;
1710ac9a064cSDimitry Andric }
1711ac9a064cSDimitry Andric
1712ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1713ac9a064cSDimitry Andric LLT Src0Ty = MRI->getType(Src0Op.getReg());
1714ac9a064cSDimitry Andric LLT Src1Ty = MRI->getType(Src1Op.getReg());
1715ac9a064cSDimitry Andric
1716ac9a064cSDimitry Andric if (!DstTy.isVector()) {
1717ac9a064cSDimitry Andric report("Destination type must be a vector", MI);
1718ac9a064cSDimitry Andric break;
1719ac9a064cSDimitry Andric }
1720ac9a064cSDimitry Andric
1721ac9a064cSDimitry Andric if (!Src0Ty.isVector()) {
1722ac9a064cSDimitry Andric report("First source must be a vector", MI);
1723ac9a064cSDimitry Andric break;
1724ac9a064cSDimitry Andric }
1725ac9a064cSDimitry Andric
1726ac9a064cSDimitry Andric if (!Src1Ty.isVector()) {
1727ac9a064cSDimitry Andric report("Second source must be a vector", MI);
1728ac9a064cSDimitry Andric break;
1729ac9a064cSDimitry Andric }
1730ac9a064cSDimitry Andric
1731ac9a064cSDimitry Andric if (DstTy != Src0Ty) {
1732ac9a064cSDimitry Andric report("Destination type must match the first source vector type", MI);
1733ac9a064cSDimitry Andric break;
1734ac9a064cSDimitry Andric }
1735ac9a064cSDimitry Andric
1736ac9a064cSDimitry Andric if (Src0Ty.getElementType() != Src1Ty.getElementType()) {
1737ac9a064cSDimitry Andric report("Element type of source vectors must be the same", MI);
1738ac9a064cSDimitry Andric break;
1739ac9a064cSDimitry Andric }
1740ac9a064cSDimitry Andric
1741ac9a064cSDimitry Andric if (IndexOp.getImm() != 0 &&
1742ac9a064cSDimitry Andric Src1Ty.getElementCount().getKnownMinValue() % IndexOp.getImm() != 0) {
1743ac9a064cSDimitry Andric report("Index must be a multiple of the second source vector's "
1744ac9a064cSDimitry Andric "minimum vector length",
1745ac9a064cSDimitry Andric MI);
1746ac9a064cSDimitry Andric break;
1747ac9a064cSDimitry Andric }
1748ac9a064cSDimitry Andric break;
1749ac9a064cSDimitry Andric }
1750ac9a064cSDimitry Andric case TargetOpcode::G_EXTRACT_SUBVECTOR: {
1751ac9a064cSDimitry Andric const MachineOperand &SrcOp = MI->getOperand(1);
1752ac9a064cSDimitry Andric if (!SrcOp.isReg()) {
1753ac9a064cSDimitry Andric report("G_EXTRACT_SUBVECTOR first source must be a register", MI);
1754ac9a064cSDimitry Andric break;
1755ac9a064cSDimitry Andric }
1756ac9a064cSDimitry Andric
1757ac9a064cSDimitry Andric const MachineOperand &IndexOp = MI->getOperand(2);
1758ac9a064cSDimitry Andric if (!IndexOp.isImm()) {
1759ac9a064cSDimitry Andric report("G_EXTRACT_SUBVECTOR index must be an immediate", MI);
1760ac9a064cSDimitry Andric break;
1761ac9a064cSDimitry Andric }
1762ac9a064cSDimitry Andric
1763ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1764ac9a064cSDimitry Andric LLT SrcTy = MRI->getType(SrcOp.getReg());
1765ac9a064cSDimitry Andric
1766ac9a064cSDimitry Andric if (!DstTy.isVector()) {
1767ac9a064cSDimitry Andric report("Destination type must be a vector", MI);
1768ac9a064cSDimitry Andric break;
1769ac9a064cSDimitry Andric }
1770ac9a064cSDimitry Andric
1771ac9a064cSDimitry Andric if (!SrcTy.isVector()) {
1772ac9a064cSDimitry Andric report("First source must be a vector", MI);
1773ac9a064cSDimitry Andric break;
1774ac9a064cSDimitry Andric }
1775ac9a064cSDimitry Andric
1776ac9a064cSDimitry Andric if (DstTy.getElementType() != SrcTy.getElementType()) {
1777ac9a064cSDimitry Andric report("Element type of vectors must be the same", MI);
1778ac9a064cSDimitry Andric break;
1779ac9a064cSDimitry Andric }
1780ac9a064cSDimitry Andric
1781ac9a064cSDimitry Andric if (IndexOp.getImm() != 0 &&
1782ac9a064cSDimitry Andric SrcTy.getElementCount().getKnownMinValue() % IndexOp.getImm() != 0) {
1783ac9a064cSDimitry Andric report("Index must be a multiple of the source vector's minimum vector "
1784ac9a064cSDimitry Andric "length",
1785ac9a064cSDimitry Andric MI);
1786ac9a064cSDimitry Andric break;
1787ac9a064cSDimitry Andric }
1788ac9a064cSDimitry Andric
1789ac9a064cSDimitry Andric break;
1790ac9a064cSDimitry Andric }
17911d5ae102SDimitry Andric case TargetOpcode::G_SHUFFLE_VECTOR: {
17921d5ae102SDimitry Andric const MachineOperand &MaskOp = MI->getOperand(3);
17931d5ae102SDimitry Andric if (!MaskOp.isShuffleMask()) {
17941d5ae102SDimitry Andric report("Incorrect mask operand type for G_SHUFFLE_VECTOR", MI);
17951d5ae102SDimitry Andric break;
17961d5ae102SDimitry Andric }
17971d5ae102SDimitry Andric
17981d5ae102SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
17991d5ae102SDimitry Andric LLT Src0Ty = MRI->getType(MI->getOperand(1).getReg());
18001d5ae102SDimitry Andric LLT Src1Ty = MRI->getType(MI->getOperand(2).getReg());
18011d5ae102SDimitry Andric
18021d5ae102SDimitry Andric if (Src0Ty != Src1Ty)
18031d5ae102SDimitry Andric report("Source operands must be the same type", MI);
18041d5ae102SDimitry Andric
18051d5ae102SDimitry Andric if (Src0Ty.getScalarType() != DstTy.getScalarType())
18061d5ae102SDimitry Andric report("G_SHUFFLE_VECTOR cannot change element type", MI);
18071d5ae102SDimitry Andric
18081d5ae102SDimitry Andric // Don't check that all operands are vector because scalars are used in
18091d5ae102SDimitry Andric // place of 1 element vectors.
18101d5ae102SDimitry Andric int SrcNumElts = Src0Ty.isVector() ? Src0Ty.getNumElements() : 1;
18111d5ae102SDimitry Andric int DstNumElts = DstTy.isVector() ? DstTy.getNumElements() : 1;
18121d5ae102SDimitry Andric
1813706b4fc4SDimitry Andric ArrayRef<int> MaskIdxes = MaskOp.getShuffleMask();
18141d5ae102SDimitry Andric
18151d5ae102SDimitry Andric if (static_cast<int>(MaskIdxes.size()) != DstNumElts)
18161d5ae102SDimitry Andric report("Wrong result type for shufflemask", MI);
18171d5ae102SDimitry Andric
18181d5ae102SDimitry Andric for (int Idx : MaskIdxes) {
18191d5ae102SDimitry Andric if (Idx < 0)
18201d5ae102SDimitry Andric continue;
18211d5ae102SDimitry Andric
18221d5ae102SDimitry Andric if (Idx >= 2 * SrcNumElts)
18231d5ae102SDimitry Andric report("Out of bounds shuffle index", MI);
18241d5ae102SDimitry Andric }
18251d5ae102SDimitry Andric
18261d5ae102SDimitry Andric break;
18271d5ae102SDimitry Andric }
1828ac9a064cSDimitry Andric
1829ac9a064cSDimitry Andric case TargetOpcode::G_SPLAT_VECTOR: {
1830ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1831ac9a064cSDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1832ac9a064cSDimitry Andric
1833ac9a064cSDimitry Andric if (!DstTy.isScalableVector()) {
1834ac9a064cSDimitry Andric report("Destination type must be a scalable vector", MI);
1835ac9a064cSDimitry Andric break;
1836ac9a064cSDimitry Andric }
1837ac9a064cSDimitry Andric
1838ac9a064cSDimitry Andric if (!SrcTy.isScalar()) {
1839ac9a064cSDimitry Andric report("Source type must be a scalar", MI);
1840ac9a064cSDimitry Andric break;
1841ac9a064cSDimitry Andric }
1842ac9a064cSDimitry Andric
1843ac9a064cSDimitry Andric if (TypeSize::isKnownGT(DstTy.getElementType().getSizeInBits(),
1844ac9a064cSDimitry Andric SrcTy.getSizeInBits())) {
1845ac9a064cSDimitry Andric report("Element type of the destination must be the same size or smaller "
1846ac9a064cSDimitry Andric "than the source type",
1847ac9a064cSDimitry Andric MI);
1848ac9a064cSDimitry Andric break;
1849ac9a064cSDimitry Andric }
1850ac9a064cSDimitry Andric
1851ac9a064cSDimitry Andric break;
1852ac9a064cSDimitry Andric }
1853ac9a064cSDimitry Andric case TargetOpcode::G_EXTRACT_VECTOR_ELT: {
1854ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1855ac9a064cSDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
1856ac9a064cSDimitry Andric LLT IdxTy = MRI->getType(MI->getOperand(2).getReg());
1857ac9a064cSDimitry Andric
1858ac9a064cSDimitry Andric if (!DstTy.isScalar() && !DstTy.isPointer()) {
1859ac9a064cSDimitry Andric report("Destination type must be a scalar or pointer", MI);
1860ac9a064cSDimitry Andric break;
1861ac9a064cSDimitry Andric }
1862ac9a064cSDimitry Andric
1863ac9a064cSDimitry Andric if (!SrcTy.isVector()) {
1864ac9a064cSDimitry Andric report("First source must be a vector", MI);
1865ac9a064cSDimitry Andric break;
1866ac9a064cSDimitry Andric }
1867ac9a064cSDimitry Andric
1868ac9a064cSDimitry Andric auto TLI = MF->getSubtarget().getTargetLowering();
1869ac9a064cSDimitry Andric if (IdxTy.getSizeInBits() !=
1870ac9a064cSDimitry Andric TLI->getVectorIdxTy(MF->getDataLayout()).getFixedSizeInBits()) {
1871ac9a064cSDimitry Andric report("Index type must match VectorIdxTy", MI);
1872ac9a064cSDimitry Andric break;
1873ac9a064cSDimitry Andric }
1874ac9a064cSDimitry Andric
1875ac9a064cSDimitry Andric break;
1876ac9a064cSDimitry Andric }
1877ac9a064cSDimitry Andric case TargetOpcode::G_INSERT_VECTOR_ELT: {
1878ac9a064cSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
1879ac9a064cSDimitry Andric LLT VecTy = MRI->getType(MI->getOperand(1).getReg());
1880ac9a064cSDimitry Andric LLT ScaTy = MRI->getType(MI->getOperand(2).getReg());
1881ac9a064cSDimitry Andric LLT IdxTy = MRI->getType(MI->getOperand(3).getReg());
1882ac9a064cSDimitry Andric
1883ac9a064cSDimitry Andric if (!DstTy.isVector()) {
1884ac9a064cSDimitry Andric report("Destination type must be a vector", MI);
1885ac9a064cSDimitry Andric break;
1886ac9a064cSDimitry Andric }
1887ac9a064cSDimitry Andric
1888ac9a064cSDimitry Andric if (VecTy != DstTy) {
1889ac9a064cSDimitry Andric report("Destination type and vector type must match", MI);
1890ac9a064cSDimitry Andric break;
1891ac9a064cSDimitry Andric }
1892ac9a064cSDimitry Andric
1893ac9a064cSDimitry Andric if (!ScaTy.isScalar() && !ScaTy.isPointer()) {
1894ac9a064cSDimitry Andric report("Inserted element must be a scalar or pointer", MI);
1895ac9a064cSDimitry Andric break;
1896ac9a064cSDimitry Andric }
1897ac9a064cSDimitry Andric
1898ac9a064cSDimitry Andric auto TLI = MF->getSubtarget().getTargetLowering();
1899ac9a064cSDimitry Andric if (IdxTy.getSizeInBits() !=
1900ac9a064cSDimitry Andric TLI->getVectorIdxTy(MF->getDataLayout()).getFixedSizeInBits()) {
1901ac9a064cSDimitry Andric report("Index type must match VectorIdxTy", MI);
1902ac9a064cSDimitry Andric break;
1903ac9a064cSDimitry Andric }
1904ac9a064cSDimitry Andric
1905ac9a064cSDimitry Andric break;
1906ac9a064cSDimitry Andric }
19071d5ae102SDimitry Andric case TargetOpcode::G_DYN_STACKALLOC: {
19081d5ae102SDimitry Andric const MachineOperand &DstOp = MI->getOperand(0);
19091d5ae102SDimitry Andric const MachineOperand &AllocOp = MI->getOperand(1);
19101d5ae102SDimitry Andric const MachineOperand &AlignOp = MI->getOperand(2);
19111d5ae102SDimitry Andric
19121d5ae102SDimitry Andric if (!DstOp.isReg() || !MRI->getType(DstOp.getReg()).isPointer()) {
19131d5ae102SDimitry Andric report("dst operand 0 must be a pointer type", MI);
19141d5ae102SDimitry Andric break;
19151d5ae102SDimitry Andric }
19161d5ae102SDimitry Andric
19171d5ae102SDimitry Andric if (!AllocOp.isReg() || !MRI->getType(AllocOp.getReg()).isScalar()) {
19181d5ae102SDimitry Andric report("src operand 1 must be a scalar reg type", MI);
19191d5ae102SDimitry Andric break;
19201d5ae102SDimitry Andric }
19211d5ae102SDimitry Andric
19221d5ae102SDimitry Andric if (!AlignOp.isImm()) {
19231d5ae102SDimitry Andric report("src operand 2 must be an immediate type", MI);
19241d5ae102SDimitry Andric break;
19251d5ae102SDimitry Andric }
1926e6d15924SDimitry Andric break;
1927e6d15924SDimitry Andric }
1928344a3780SDimitry Andric case TargetOpcode::G_MEMCPY_INLINE:
1929b60736ecSDimitry Andric case TargetOpcode::G_MEMCPY:
1930b60736ecSDimitry Andric case TargetOpcode::G_MEMMOVE: {
1931b60736ecSDimitry Andric ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
1932b60736ecSDimitry Andric if (MMOs.size() != 2) {
1933b60736ecSDimitry Andric report("memcpy/memmove must have 2 memory operands", MI);
1934b60736ecSDimitry Andric break;
1935b60736ecSDimitry Andric }
1936b60736ecSDimitry Andric
1937b60736ecSDimitry Andric if ((!MMOs[0]->isStore() || MMOs[0]->isLoad()) ||
1938b60736ecSDimitry Andric (MMOs[1]->isStore() || !MMOs[1]->isLoad())) {
1939b60736ecSDimitry Andric report("wrong memory operand types", MI);
1940b60736ecSDimitry Andric break;
1941b60736ecSDimitry Andric }
1942b60736ecSDimitry Andric
1943b60736ecSDimitry Andric if (MMOs[0]->getSize() != MMOs[1]->getSize())
1944b60736ecSDimitry Andric report("inconsistent memory operand sizes", MI);
1945b60736ecSDimitry Andric
1946b60736ecSDimitry Andric LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
1947b60736ecSDimitry Andric LLT SrcPtrTy = MRI->getType(MI->getOperand(1).getReg());
1948b60736ecSDimitry Andric
1949b60736ecSDimitry Andric if (!DstPtrTy.isPointer() || !SrcPtrTy.isPointer()) {
1950b60736ecSDimitry Andric report("memory instruction operand must be a pointer", MI);
1951b60736ecSDimitry Andric break;
1952b60736ecSDimitry Andric }
1953b60736ecSDimitry Andric
1954b60736ecSDimitry Andric if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
1955b60736ecSDimitry Andric report("inconsistent store address space", MI);
1956b60736ecSDimitry Andric if (SrcPtrTy.getAddressSpace() != MMOs[1]->getAddrSpace())
1957b60736ecSDimitry Andric report("inconsistent load address space", MI);
1958b60736ecSDimitry Andric
1959344a3780SDimitry Andric if (Opc != TargetOpcode::G_MEMCPY_INLINE)
1960344a3780SDimitry Andric if (!MI->getOperand(3).isImm() || (MI->getOperand(3).getImm() & ~1LL))
1961344a3780SDimitry Andric report("'tail' flag (operand 3) must be an immediate 0 or 1", MI);
1962344a3780SDimitry Andric
1963b60736ecSDimitry Andric break;
1964b60736ecSDimitry Andric }
1965344a3780SDimitry Andric case TargetOpcode::G_BZERO:
1966b60736ecSDimitry Andric case TargetOpcode::G_MEMSET: {
1967b60736ecSDimitry Andric ArrayRef<MachineMemOperand *> MMOs = MI->memoperands();
1968344a3780SDimitry Andric std::string Name = Opc == TargetOpcode::G_MEMSET ? "memset" : "bzero";
1969b60736ecSDimitry Andric if (MMOs.size() != 1) {
1970344a3780SDimitry Andric report(Twine(Name, " must have 1 memory operand"), MI);
1971b60736ecSDimitry Andric break;
1972b60736ecSDimitry Andric }
1973b60736ecSDimitry Andric
1974b60736ecSDimitry Andric if ((!MMOs[0]->isStore() || MMOs[0]->isLoad())) {
1975344a3780SDimitry Andric report(Twine(Name, " memory operand must be a store"), MI);
1976b60736ecSDimitry Andric break;
1977b60736ecSDimitry Andric }
1978b60736ecSDimitry Andric
1979b60736ecSDimitry Andric LLT DstPtrTy = MRI->getType(MI->getOperand(0).getReg());
1980b60736ecSDimitry Andric if (!DstPtrTy.isPointer()) {
1981344a3780SDimitry Andric report(Twine(Name, " operand must be a pointer"), MI);
1982b60736ecSDimitry Andric break;
1983b60736ecSDimitry Andric }
1984b60736ecSDimitry Andric
1985b60736ecSDimitry Andric if (DstPtrTy.getAddressSpace() != MMOs[0]->getAddrSpace())
1986344a3780SDimitry Andric report("inconsistent " + Twine(Name, " address space"), MI);
1987344a3780SDimitry Andric
1988344a3780SDimitry Andric if (!MI->getOperand(MI->getNumOperands() - 1).isImm() ||
1989344a3780SDimitry Andric (MI->getOperand(MI->getNumOperands() - 1).getImm() & ~1LL))
1990344a3780SDimitry Andric report("'tail' flag (last operand) must be an immediate 0 or 1", MI);
1991b60736ecSDimitry Andric
1992b60736ecSDimitry Andric break;
1993b60736ecSDimitry Andric }
1994ac9a064cSDimitry Andric case TargetOpcode::G_UBSANTRAP: {
1995ac9a064cSDimitry Andric const MachineOperand &KindOp = MI->getOperand(0);
1996ac9a064cSDimitry Andric if (!MI->getOperand(0).isImm()) {
1997ac9a064cSDimitry Andric report("Crash kind must be an immediate", &KindOp, 0);
1998ac9a064cSDimitry Andric break;
1999ac9a064cSDimitry Andric }
2000ac9a064cSDimitry Andric int64_t Kind = MI->getOperand(0).getImm();
2001ac9a064cSDimitry Andric if (!isInt<8>(Kind))
2002ac9a064cSDimitry Andric report("Crash kind must be 8 bit wide", &KindOp, 0);
2003ac9a064cSDimitry Andric break;
2004ac9a064cSDimitry Andric }
2005b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_SEQ_FADD:
2006b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_SEQ_FMUL: {
2007b60736ecSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
2008b60736ecSDimitry Andric LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
2009b60736ecSDimitry Andric LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
2010b60736ecSDimitry Andric if (!DstTy.isScalar())
2011b60736ecSDimitry Andric report("Vector reduction requires a scalar destination type", MI);
2012b60736ecSDimitry Andric if (!Src1Ty.isScalar())
2013b60736ecSDimitry Andric report("Sequential FADD/FMUL vector reduction requires a scalar 1st operand", MI);
2014b60736ecSDimitry Andric if (!Src2Ty.isVector())
2015b60736ecSDimitry Andric report("Sequential FADD/FMUL vector reduction must have a vector 2nd operand", MI);
2016b60736ecSDimitry Andric break;
2017b60736ecSDimitry Andric }
2018b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_FADD:
2019b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_FMUL:
2020b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_FMAX:
2021b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_FMIN:
2022b1c73532SDimitry Andric case TargetOpcode::G_VECREDUCE_FMAXIMUM:
2023b1c73532SDimitry Andric case TargetOpcode::G_VECREDUCE_FMINIMUM:
2024b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_ADD:
2025b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_MUL:
2026b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_AND:
2027b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_OR:
2028b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_XOR:
2029b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_SMAX:
2030b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_SMIN:
2031b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_UMAX:
2032b60736ecSDimitry Andric case TargetOpcode::G_VECREDUCE_UMIN: {
2033b60736ecSDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
2034b60736ecSDimitry Andric if (!DstTy.isScalar())
2035b60736ecSDimitry Andric report("Vector reduction requires a scalar destination type", MI);
2036b60736ecSDimitry Andric break;
2037b60736ecSDimitry Andric }
2038344a3780SDimitry Andric
2039344a3780SDimitry Andric case TargetOpcode::G_SBFX:
2040344a3780SDimitry Andric case TargetOpcode::G_UBFX: {
2041344a3780SDimitry Andric LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
2042344a3780SDimitry Andric if (DstTy.isVector()) {
2043344a3780SDimitry Andric report("Bitfield extraction is not supported on vectors", MI);
2044344a3780SDimitry Andric break;
2045344a3780SDimitry Andric }
2046344a3780SDimitry Andric break;
2047344a3780SDimitry Andric }
204877fc4c14SDimitry Andric case TargetOpcode::G_SHL:
204977fc4c14SDimitry Andric case TargetOpcode::G_LSHR:
205077fc4c14SDimitry Andric case TargetOpcode::G_ASHR:
2051344a3780SDimitry Andric case TargetOpcode::G_ROTR:
2052344a3780SDimitry Andric case TargetOpcode::G_ROTL: {
2053344a3780SDimitry Andric LLT Src1Ty = MRI->getType(MI->getOperand(1).getReg());
2054344a3780SDimitry Andric LLT Src2Ty = MRI->getType(MI->getOperand(2).getReg());
2055344a3780SDimitry Andric if (Src1Ty.isVector() != Src2Ty.isVector()) {
205677fc4c14SDimitry Andric report("Shifts and rotates require operands to be either all scalars or "
205777fc4c14SDimitry Andric "all vectors",
2058344a3780SDimitry Andric MI);
2059344a3780SDimitry Andric break;
2060344a3780SDimitry Andric }
2061344a3780SDimitry Andric break;
2062344a3780SDimitry Andric }
2063c0981da4SDimitry Andric case TargetOpcode::G_LLROUND:
2064c0981da4SDimitry Andric case TargetOpcode::G_LROUND: {
2065c0981da4SDimitry Andric verifyAllRegOpsScalar(*MI, *MRI);
2066c0981da4SDimitry Andric break;
2067c0981da4SDimitry Andric }
2068145449b1SDimitry Andric case TargetOpcode::G_IS_FPCLASS: {
2069145449b1SDimitry Andric LLT DestTy = MRI->getType(MI->getOperand(0).getReg());
2070145449b1SDimitry Andric LLT DestEltTy = DestTy.getScalarType();
2071145449b1SDimitry Andric if (!DestEltTy.isScalar()) {
2072145449b1SDimitry Andric report("Destination must be a scalar or vector of scalars", MI);
2073145449b1SDimitry Andric break;
2074145449b1SDimitry Andric }
2075145449b1SDimitry Andric LLT SrcTy = MRI->getType(MI->getOperand(1).getReg());
2076145449b1SDimitry Andric LLT SrcEltTy = SrcTy.getScalarType();
2077145449b1SDimitry Andric if (!SrcEltTy.isScalar()) {
2078145449b1SDimitry Andric report("Source must be a scalar or vector of scalars", MI);
2079145449b1SDimitry Andric break;
2080145449b1SDimitry Andric }
2081145449b1SDimitry Andric if (!verifyVectorElementMatch(DestTy, SrcTy, MI))
2082145449b1SDimitry Andric break;
2083145449b1SDimitry Andric const MachineOperand &TestMO = MI->getOperand(2);
2084145449b1SDimitry Andric if (!TestMO.isImm()) {
2085145449b1SDimitry Andric report("floating-point class set (operand 2) must be an immediate", MI);
2086145449b1SDimitry Andric break;
2087145449b1SDimitry Andric }
2088145449b1SDimitry Andric int64_t Test = TestMO.getImm();
2089145449b1SDimitry Andric if (Test < 0 || Test > fcAllFlags) {
2090145449b1SDimitry Andric report("Incorrect floating-point class set (operand 2)", MI);
2091145449b1SDimitry Andric break;
2092145449b1SDimitry Andric }
2093145449b1SDimitry Andric break;
2094145449b1SDimitry Andric }
2095312c0ed1SDimitry Andric case TargetOpcode::G_PREFETCH: {
2096312c0ed1SDimitry Andric const MachineOperand &AddrOp = MI->getOperand(0);
2097312c0ed1SDimitry Andric if (!AddrOp.isReg() || !MRI->getType(AddrOp.getReg()).isPointer()) {
2098312c0ed1SDimitry Andric report("addr operand must be a pointer", &AddrOp, 0);
2099312c0ed1SDimitry Andric break;
2100312c0ed1SDimitry Andric }
2101312c0ed1SDimitry Andric const MachineOperand &RWOp = MI->getOperand(1);
2102312c0ed1SDimitry Andric if (!RWOp.isImm() || (uint64_t)RWOp.getImm() >= 2) {
2103312c0ed1SDimitry Andric report("rw operand must be an immediate 0-1", &RWOp, 1);
2104312c0ed1SDimitry Andric break;
2105312c0ed1SDimitry Andric }
2106312c0ed1SDimitry Andric const MachineOperand &LocalityOp = MI->getOperand(2);
2107312c0ed1SDimitry Andric if (!LocalityOp.isImm() || (uint64_t)LocalityOp.getImm() >= 4) {
2108312c0ed1SDimitry Andric report("locality operand must be an immediate 0-3", &LocalityOp, 2);
2109312c0ed1SDimitry Andric break;
2110312c0ed1SDimitry Andric }
2111312c0ed1SDimitry Andric const MachineOperand &CacheTypeOp = MI->getOperand(3);
2112312c0ed1SDimitry Andric if (!CacheTypeOp.isImm() || (uint64_t)CacheTypeOp.getImm() >= 2) {
2113312c0ed1SDimitry Andric report("cache type operand must be an immediate 0-1", &CacheTypeOp, 3);
2114312c0ed1SDimitry Andric break;
2115312c0ed1SDimitry Andric }
2116312c0ed1SDimitry Andric break;
2117312c0ed1SDimitry Andric }
2118e3b55780SDimitry Andric case TargetOpcode::G_ASSERT_ALIGN: {
2119e3b55780SDimitry Andric if (MI->getOperand(2).getImm() < 1)
2120e3b55780SDimitry Andric report("alignment immediate must be >= 1", MI);
2121145449b1SDimitry Andric break;
2122145449b1SDimitry Andric }
21237fa27ce4SDimitry Andric case TargetOpcode::G_CONSTANT_POOL: {
21247fa27ce4SDimitry Andric if (!MI->getOperand(1).isCPI())
21257fa27ce4SDimitry Andric report("Src operand 1 must be a constant pool index", MI);
21267fa27ce4SDimitry Andric if (!MRI->getType(MI->getOperand(0).getReg()).isPointer())
21277fa27ce4SDimitry Andric report("Dst operand 0 must be a pointer", MI);
21287fa27ce4SDimitry Andric break;
21297fa27ce4SDimitry Andric }
2130ac9a064cSDimitry Andric case TargetOpcode::G_PTRAUTH_GLOBAL_VALUE: {
2131ac9a064cSDimitry Andric const MachineOperand &AddrOp = MI->getOperand(1);
2132ac9a064cSDimitry Andric if (!AddrOp.isReg() || !MRI->getType(AddrOp.getReg()).isPointer())
2133ac9a064cSDimitry Andric report("addr operand must be a pointer", &AddrOp, 1);
2134ac9a064cSDimitry Andric break;
2135ac9a064cSDimitry Andric }
2136e6d15924SDimitry Andric default:
2137e6d15924SDimitry Andric break;
2138e6d15924SDimitry Andric }
2139e6d15924SDimitry Andric }
2140e6d15924SDimitry Andric
visitMachineInstrBefore(const MachineInstr * MI)214159850d08SRoman Divacky void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
2142411bd29eSDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
2143411bd29eSDimitry Andric if (MI->getNumOperands() < MCID.getNumOperands()) {
2144009b1c42SEd Schouten report("Too few operands", MI);
21455a5ac124SDimitry Andric errs() << MCID.getNumOperands() << " operands expected, but "
2146f8af5cf6SDimitry Andric << MI->getNumOperands() << " given.\n";
2147009b1c42SEd Schouten }
214859850d08SRoman Divacky
2149b1c73532SDimitry Andric if (MI->getFlag(MachineInstr::NoConvergent) && !MCID.isConvergent())
2150b1c73532SDimitry Andric report("NoConvergent flag expected only on convergent instructions.", MI);
2151b1c73532SDimitry Andric
2152d8e91e46SDimitry Andric if (MI->isPHI()) {
2153d8e91e46SDimitry Andric if (MF->getProperties().hasProperty(
2154b915e9e0SDimitry Andric MachineFunctionProperties::Property::NoPHIs))
2155b915e9e0SDimitry Andric report("Found PHI instruction with NoPHIs property set", MI);
2156b915e9e0SDimitry Andric
2157d8e91e46SDimitry Andric if (FirstNonPHI)
2158d8e91e46SDimitry Andric report("Found PHI instruction after non-PHI", MI);
2159d8e91e46SDimitry Andric } else if (FirstNonPHI == nullptr)
2160d8e91e46SDimitry Andric FirstNonPHI = MI;
2161d8e91e46SDimitry Andric
2162522600a2SDimitry Andric // Check the tied operands.
2163522600a2SDimitry Andric if (MI->isInlineAsm())
2164522600a2SDimitry Andric verifyInlineAsm(MI);
2165522600a2SDimitry Andric
2166b60736ecSDimitry Andric // Check that unspillable terminators define a reg and have at most one use.
2167b60736ecSDimitry Andric if (TII->isUnspillableTerminator(MI)) {
2168b60736ecSDimitry Andric if (!MI->getOperand(0).isReg() || !MI->getOperand(0).isDef())
2169b60736ecSDimitry Andric report("Unspillable Terminator does not define a reg", MI);
2170b60736ecSDimitry Andric Register Def = MI->getOperand(0).getReg();
2171b60736ecSDimitry Andric if (Def.isVirtual() &&
2172c0981da4SDimitry Andric !MF->getProperties().hasProperty(
2173c0981da4SDimitry Andric MachineFunctionProperties::Property::NoPHIs) &&
2174b60736ecSDimitry Andric std::distance(MRI->use_nodbg_begin(Def), MRI->use_nodbg_end()) > 1)
2175b60736ecSDimitry Andric report("Unspillable Terminator expected to have at most one use!", MI);
2176b60736ecSDimitry Andric }
2177b60736ecSDimitry Andric
2178cfca06d7SDimitry Andric // A fully-formed DBG_VALUE must have a location. Ignore partially formed
2179cfca06d7SDimitry Andric // DBG_VALUEs: these are convenient to use in tests, but should never get
2180cfca06d7SDimitry Andric // generated.
2181cfca06d7SDimitry Andric if (MI->isDebugValue() && MI->getNumOperands() == 4)
2182cfca06d7SDimitry Andric if (!MI->getDebugLoc())
2183cfca06d7SDimitry Andric report("Missing DebugLoc for debug instruction", MI);
2184cfca06d7SDimitry Andric
2185b60736ecSDimitry Andric // Meta instructions should never be the subject of debug value tracking,
2186b60736ecSDimitry Andric // they don't create a value in the output program at all.
2187b60736ecSDimitry Andric if (MI->isMetaInstruction() && MI->peekDebugInstrNum())
2188b60736ecSDimitry Andric report("Metadata instruction should not have a value tracking number", MI);
2189b60736ecSDimitry Andric
219059850d08SRoman Divacky // Check the MachineMemOperands for basic consistency.
2191cfca06d7SDimitry Andric for (MachineMemOperand *Op : MI->memoperands()) {
2192cfca06d7SDimitry Andric if (Op->isLoad() && !MI->mayLoad())
219359850d08SRoman Divacky report("Missing mayLoad flag", MI);
2194cfca06d7SDimitry Andric if (Op->isStore() && !MI->mayStore())
219559850d08SRoman Divacky report("Missing mayStore flag", MI);
2196009b1c42SEd Schouten }
2197d39c594dSDimitry Andric
2198d39c594dSDimitry Andric // Debug values must not have a slot index.
219963faed5bSDimitry Andric // Other instructions must have one, unless they are inside a bundle.
2200d39c594dSDimitry Andric if (LiveInts) {
220101095a5dSDimitry Andric bool mapped = !LiveInts->isNotInMIMap(*MI);
2202344a3780SDimitry Andric if (MI->isDebugOrPseudoInstr()) {
2203d39c594dSDimitry Andric if (mapped)
2204d39c594dSDimitry Andric report("Debug instruction has a slot index", MI);
220563faed5bSDimitry Andric } else if (MI->isInsideBundle()) {
220663faed5bSDimitry Andric if (mapped)
220763faed5bSDimitry Andric report("Instruction inside bundle has a slot index", MI);
2208d39c594dSDimitry Andric } else {
2209d39c594dSDimitry Andric if (!mapped)
2210d39c594dSDimitry Andric report("Missing slot index", MI);
2211d39c594dSDimitry Andric }
2212d39c594dSDimitry Andric }
2213d39c594dSDimitry Andric
2214344a3780SDimitry Andric unsigned Opc = MCID.getOpcode();
2215344a3780SDimitry Andric if (isPreISelGenericOpcode(Opc) || isPreISelGenericOptimizationHint(Opc)) {
2216e6d15924SDimitry Andric verifyPreISelGenericInstruction(MI);
2217e6d15924SDimitry Andric return;
2218b915e9e0SDimitry Andric }
2219b915e9e0SDimitry Andric
222030815c53SDimitry Andric StringRef ErrorInfo;
222101095a5dSDimitry Andric if (!TII->verifyInstruction(*MI, ErrorInfo))
222230815c53SDimitry Andric report(ErrorInfo.data(), MI);
2223d288ef4cSDimitry Andric
2224d288ef4cSDimitry Andric // Verify properties of various specific instruction types
2225d288ef4cSDimitry Andric switch (MI->getOpcode()) {
2226eb11fae6SDimitry Andric case TargetOpcode::COPY: {
2227eb11fae6SDimitry Andric const MachineOperand &DstOp = MI->getOperand(0);
2228eb11fae6SDimitry Andric const MachineOperand &SrcOp = MI->getOperand(1);
2229344a3780SDimitry Andric const Register SrcReg = SrcOp.getReg();
2230344a3780SDimitry Andric const Register DstReg = DstOp.getReg();
2231344a3780SDimitry Andric
2232344a3780SDimitry Andric LLT DstTy = MRI->getType(DstReg);
2233344a3780SDimitry Andric LLT SrcTy = MRI->getType(SrcReg);
2234eb11fae6SDimitry Andric if (SrcTy.isValid() && DstTy.isValid()) {
2235eb11fae6SDimitry Andric // If both types are valid, check that the types are the same.
2236eb11fae6SDimitry Andric if (SrcTy != DstTy) {
2237eb11fae6SDimitry Andric report("Copy Instruction is illegal with mismatching types", MI);
2238eb11fae6SDimitry Andric errs() << "Def = " << DstTy << ", Src = " << SrcTy << "\n";
2239eb11fae6SDimitry Andric }
2240344a3780SDimitry Andric
2241344a3780SDimitry Andric break;
2242eb11fae6SDimitry Andric }
2243344a3780SDimitry Andric
2244344a3780SDimitry Andric if (!SrcTy.isValid() && !DstTy.isValid())
2245344a3780SDimitry Andric break;
2246344a3780SDimitry Andric
2247344a3780SDimitry Andric // If we have only one valid type, this is likely a copy between a virtual
2248344a3780SDimitry Andric // and physical register.
2249b1c73532SDimitry Andric TypeSize SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
2250b1c73532SDimitry Andric TypeSize DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
2251344a3780SDimitry Andric if (SrcReg.isPhysical() && DstTy.isValid()) {
2252344a3780SDimitry Andric const TargetRegisterClass *SrcRC =
2253344a3780SDimitry Andric TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy);
2254344a3780SDimitry Andric if (SrcRC)
2255344a3780SDimitry Andric SrcSize = TRI->getRegSizeInBits(*SrcRC);
2256344a3780SDimitry Andric }
2257344a3780SDimitry Andric
2258344a3780SDimitry Andric if (DstReg.isPhysical() && SrcTy.isValid()) {
2259344a3780SDimitry Andric const TargetRegisterClass *DstRC =
2260344a3780SDimitry Andric TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
2261344a3780SDimitry Andric if (DstRC)
2262344a3780SDimitry Andric DstSize = TRI->getRegSizeInBits(*DstRC);
2263344a3780SDimitry Andric }
2264344a3780SDimitry Andric
2265b1c73532SDimitry Andric // The next two checks allow COPY between physical and virtual registers,
2266b1c73532SDimitry Andric // when the virtual register has a scalable size and the physical register
2267b1c73532SDimitry Andric // has a fixed size. These checks allow COPY between *potentialy* mismatched
2268b1c73532SDimitry Andric // sizes. However, once RegisterBankSelection occurs, MachineVerifier should
2269b1c73532SDimitry Andric // be able to resolve a fixed size for the scalable vector, and at that
2270b1c73532SDimitry Andric // point this function will know for sure whether the sizes are mismatched
2271b1c73532SDimitry Andric // and correctly report a size mismatch.
2272b1c73532SDimitry Andric if (SrcReg.isPhysical() && DstReg.isVirtual() && DstSize.isScalable() &&
2273b1c73532SDimitry Andric !SrcSize.isScalable())
2274b1c73532SDimitry Andric break;
2275b1c73532SDimitry Andric if (SrcReg.isVirtual() && DstReg.isPhysical() && SrcSize.isScalable() &&
2276b1c73532SDimitry Andric !DstSize.isScalable())
2277b1c73532SDimitry Andric break;
2278344a3780SDimitry Andric
2279b1c73532SDimitry Andric if (SrcSize.isNonZero() && DstSize.isNonZero() && SrcSize != DstSize) {
2280eb11fae6SDimitry Andric if (!DstOp.getSubReg() && !SrcOp.getSubReg()) {
2281eb11fae6SDimitry Andric report("Copy Instruction is illegal with mismatching sizes", MI);
2282eb11fae6SDimitry Andric errs() << "Def Size = " << DstSize << ", Src Size = " << SrcSize
2283eb11fae6SDimitry Andric << "\n";
2284eb11fae6SDimitry Andric }
2285eb11fae6SDimitry Andric }
2286eb11fae6SDimitry Andric break;
2287eb11fae6SDimitry Andric }
2288cfca06d7SDimitry Andric case TargetOpcode::STATEPOINT: {
2289cfca06d7SDimitry Andric StatepointOpers SO(MI);
2290cfca06d7SDimitry Andric if (!MI->getOperand(SO.getIDPos()).isImm() ||
2291cfca06d7SDimitry Andric !MI->getOperand(SO.getNBytesPos()).isImm() ||
2292cfca06d7SDimitry Andric !MI->getOperand(SO.getNCallArgsPos()).isImm()) {
2293d288ef4cSDimitry Andric report("meta operands to STATEPOINT not constant!", MI);
2294d288ef4cSDimitry Andric break;
2295cfca06d7SDimitry Andric }
2296d288ef4cSDimitry Andric
2297d288ef4cSDimitry Andric auto VerifyStackMapConstant = [&](unsigned Offset) {
2298b60736ecSDimitry Andric if (Offset >= MI->getNumOperands()) {
2299b60736ecSDimitry Andric report("stack map constant to STATEPOINT is out of range!", MI);
2300b60736ecSDimitry Andric return;
2301b60736ecSDimitry Andric }
2302cfca06d7SDimitry Andric if (!MI->getOperand(Offset - 1).isImm() ||
2303cfca06d7SDimitry Andric MI->getOperand(Offset - 1).getImm() != StackMaps::ConstantOp ||
2304cfca06d7SDimitry Andric !MI->getOperand(Offset).isImm())
2305d288ef4cSDimitry Andric report("stack map constant to STATEPOINT not well formed!", MI);
2306d288ef4cSDimitry Andric };
2307cfca06d7SDimitry Andric VerifyStackMapConstant(SO.getCCIdx());
2308cfca06d7SDimitry Andric VerifyStackMapConstant(SO.getFlagsIdx());
2309cfca06d7SDimitry Andric VerifyStackMapConstant(SO.getNumDeoptArgsIdx());
2310b60736ecSDimitry Andric VerifyStackMapConstant(SO.getNumGCPtrIdx());
2311b60736ecSDimitry Andric VerifyStackMapConstant(SO.getNumAllocaIdx());
2312b60736ecSDimitry Andric VerifyStackMapConstant(SO.getNumGcMapEntriesIdx());
2313b60736ecSDimitry Andric
2314b60736ecSDimitry Andric // Verify that all explicit statepoint defs are tied to gc operands as
2315b60736ecSDimitry Andric // they are expected to be a relocation of gc operands.
2316b60736ecSDimitry Andric unsigned FirstGCPtrIdx = SO.getFirstGCPtrIdx();
2317b60736ecSDimitry Andric unsigned LastGCPtrIdx = SO.getNumAllocaIdx() - 2;
2318b60736ecSDimitry Andric for (unsigned Idx = 0; Idx < MI->getNumDefs(); Idx++) {
2319b60736ecSDimitry Andric unsigned UseOpIdx;
2320b60736ecSDimitry Andric if (!MI->isRegTiedToUseOperand(Idx, &UseOpIdx)) {
2321b60736ecSDimitry Andric report("STATEPOINT defs expected to be tied", MI);
2322b60736ecSDimitry Andric break;
2323b60736ecSDimitry Andric }
2324b60736ecSDimitry Andric if (UseOpIdx < FirstGCPtrIdx || UseOpIdx > LastGCPtrIdx) {
2325b60736ecSDimitry Andric report("STATEPOINT def tied to non-gc operand", MI);
2326b60736ecSDimitry Andric break;
2327b60736ecSDimitry Andric }
2328b60736ecSDimitry Andric }
2329d288ef4cSDimitry Andric
2330d288ef4cSDimitry Andric // TODO: verify we have properly encoded deopt arguments
2331cfca06d7SDimitry Andric } break;
2332344a3780SDimitry Andric case TargetOpcode::INSERT_SUBREG: {
2333344a3780SDimitry Andric unsigned InsertedSize;
2334344a3780SDimitry Andric if (unsigned SubIdx = MI->getOperand(2).getSubReg())
2335344a3780SDimitry Andric InsertedSize = TRI->getSubRegIdxSize(SubIdx);
2336344a3780SDimitry Andric else
2337344a3780SDimitry Andric InsertedSize = TRI->getRegSizeInBits(MI->getOperand(2).getReg(), *MRI);
2338344a3780SDimitry Andric unsigned SubRegSize = TRI->getSubRegIdxSize(MI->getOperand(3).getImm());
2339344a3780SDimitry Andric if (SubRegSize < InsertedSize) {
2340344a3780SDimitry Andric report("INSERT_SUBREG expected inserted value to have equal or lesser "
2341344a3780SDimitry Andric "size than the subreg it was inserted into", MI);
2342344a3780SDimitry Andric break;
2343344a3780SDimitry Andric }
2344344a3780SDimitry Andric } break;
2345e3b55780SDimitry Andric case TargetOpcode::REG_SEQUENCE: {
2346e3b55780SDimitry Andric unsigned NumOps = MI->getNumOperands();
2347e3b55780SDimitry Andric if (!(NumOps & 1)) {
2348e3b55780SDimitry Andric report("Invalid number of operands for REG_SEQUENCE", MI);
2349e3b55780SDimitry Andric break;
2350e3b55780SDimitry Andric }
2351e3b55780SDimitry Andric
2352e3b55780SDimitry Andric for (unsigned I = 1; I != NumOps; I += 2) {
2353e3b55780SDimitry Andric const MachineOperand &RegOp = MI->getOperand(I);
2354e3b55780SDimitry Andric const MachineOperand &SubRegOp = MI->getOperand(I + 1);
2355e3b55780SDimitry Andric
2356e3b55780SDimitry Andric if (!RegOp.isReg())
2357e3b55780SDimitry Andric report("Invalid register operand for REG_SEQUENCE", &RegOp, I);
2358e3b55780SDimitry Andric
2359e3b55780SDimitry Andric if (!SubRegOp.isImm() || SubRegOp.getImm() == 0 ||
2360e3b55780SDimitry Andric SubRegOp.getImm() >= TRI->getNumSubRegIndices()) {
2361e3b55780SDimitry Andric report("Invalid subregister index operand for REG_SEQUENCE",
2362e3b55780SDimitry Andric &SubRegOp, I + 1);
2363e3b55780SDimitry Andric }
2364e3b55780SDimitry Andric }
2365e3b55780SDimitry Andric
2366e3b55780SDimitry Andric Register DstReg = MI->getOperand(0).getReg();
2367e3b55780SDimitry Andric if (DstReg.isPhysical())
2368e3b55780SDimitry Andric report("REG_SEQUENCE does not support physical register results", MI);
2369e3b55780SDimitry Andric
2370e3b55780SDimitry Andric if (MI->getOperand(0).getSubReg())
2371e3b55780SDimitry Andric report("Invalid subreg result for REG_SEQUENCE", MI);
2372e3b55780SDimitry Andric
2373e3b55780SDimitry Andric break;
2374e3b55780SDimitry Andric }
2375e6d15924SDimitry Andric }
2376009b1c42SEd Schouten }
2377009b1c42SEd Schouten
2378009b1c42SEd Schouten void
visitMachineOperand(const MachineOperand * MO,unsigned MONum)237959850d08SRoman Divacky MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
2380009b1c42SEd Schouten const MachineInstr *MI = MO->getParent();
2381411bd29eSDimitry Andric const MCInstrDesc &MCID = MI->getDesc();
2382dd58ef01SDimitry Andric unsigned NumDefs = MCID.getNumDefs();
2383dd58ef01SDimitry Andric if (MCID.getOpcode() == TargetOpcode::PATCHPOINT)
2384dd58ef01SDimitry Andric NumDefs = (MONum == 0 && MO->isReg()) ? NumDefs : 0;
2385009b1c42SEd Schouten
2386411bd29eSDimitry Andric // The first MCID.NumDefs operands must be explicit register defines
2387dd58ef01SDimitry Andric if (MONum < NumDefs) {
2388e3b55780SDimitry Andric const MCOperandInfo &MCOI = MCID.operands()[MONum];
2389009b1c42SEd Schouten if (!MO->isReg())
2390009b1c42SEd Schouten report("Explicit definition must be a register", MO, MONum);
239158b69754SDimitry Andric else if (!MO->isDef() && !MCOI.isOptionalDef())
2392009b1c42SEd Schouten report("Explicit definition marked as use", MO, MONum);
2393009b1c42SEd Schouten else if (MO->isImplicit())
2394009b1c42SEd Schouten report("Explicit definition marked as implicit", MO, MONum);
2395411bd29eSDimitry Andric } else if (MONum < MCID.getNumOperands()) {
2396e3b55780SDimitry Andric const MCOperandInfo &MCOI = MCID.operands()[MONum];
2397cf099d11SDimitry Andric // Don't check if it's the last operand in a variadic instruction. See,
2398706b4fc4SDimitry Andric // e.g., LDM_RET in the arm back end. Check non-variadic operands only.
2399706b4fc4SDimitry Andric bool IsOptional = MI->isVariadic() && MONum == MCID.getNumOperands() - 1;
2400706b4fc4SDimitry Andric if (!IsOptional) {
2401706b4fc4SDimitry Andric if (MO->isReg()) {
2402cfca06d7SDimitry Andric if (MO->isDef() && !MCOI.isOptionalDef() && !MCID.variadicOpsAreDefs())
240359850d08SRoman Divacky report("Explicit operand marked as def", MO, MONum);
240459850d08SRoman Divacky if (MO->isImplicit())
240559850d08SRoman Divacky report("Explicit operand marked as implicit", MO, MONum);
240659850d08SRoman Divacky }
2407522600a2SDimitry Andric
2408706b4fc4SDimitry Andric // Check that an instruction has register operands only as expected.
2409706b4fc4SDimitry Andric if (MCOI.OperandType == MCOI::OPERAND_REGISTER &&
2410706b4fc4SDimitry Andric !MO->isReg() && !MO->isFI())
2411706b4fc4SDimitry Andric report("Expected a register operand.", MO, MONum);
2412344a3780SDimitry Andric if (MO->isReg()) {
2413344a3780SDimitry Andric if (MCOI.OperandType == MCOI::OPERAND_IMMEDIATE ||
2414344a3780SDimitry Andric (MCOI.OperandType == MCOI::OPERAND_PCREL &&
2415344a3780SDimitry Andric !TII->isPCRelRegisterOperandLegal(*MO)))
2416706b4fc4SDimitry Andric report("Expected a non-register operand.", MO, MONum);
2417706b4fc4SDimitry Andric }
2418344a3780SDimitry Andric }
2419706b4fc4SDimitry Andric
2420522600a2SDimitry Andric int TiedTo = MCID.getOperandConstraint(MONum, MCOI::TIED_TO);
2421522600a2SDimitry Andric if (TiedTo != -1) {
2422522600a2SDimitry Andric if (!MO->isReg())
2423522600a2SDimitry Andric report("Tied use must be a register", MO, MONum);
2424522600a2SDimitry Andric else if (!MO->isTied())
2425522600a2SDimitry Andric report("Operand should be tied", MO, MONum);
2426522600a2SDimitry Andric else if (unsigned(TiedTo) != MI->findTiedOperandIdx(MONum))
2427522600a2SDimitry Andric report("Tied def doesn't match MCInstrDesc", MO, MONum);
2428e3b55780SDimitry Andric else if (MO->getReg().isPhysical()) {
2429ca089b24SDimitry Andric const MachineOperand &MOTied = MI->getOperand(TiedTo);
2430ca089b24SDimitry Andric if (!MOTied.isReg())
2431ca089b24SDimitry Andric report("Tied counterpart must be a register", &MOTied, TiedTo);
2432e3b55780SDimitry Andric else if (MOTied.getReg().isPhysical() &&
2433ca089b24SDimitry Andric MO->getReg() != MOTied.getReg())
2434ca089b24SDimitry Andric report("Tied physical registers must match.", &MOTied, TiedTo);
2435ca089b24SDimitry Andric }
2436522600a2SDimitry Andric } else if (MO->isReg() && MO->isTied())
2437522600a2SDimitry Andric report("Explicit operand should not be tied", MO, MONum);
2438b1c73532SDimitry Andric } else if (!MI->isVariadic()) {
24391e7804dbSRoman Divacky // ARM adds %reg0 operands to indicate predicates. We'll allow that.
2440b1c73532SDimitry Andric if (!MO->isValidExcessOperand())
244159850d08SRoman Divacky report("Extra explicit operand on non-variadic instruction", MO, MONum);
2442009b1c42SEd Schouten }
2443009b1c42SEd Schouten
2444009b1c42SEd Schouten switch (MO->getType()) {
2445009b1c42SEd Schouten case MachineOperand::MO_Register: {
2446c0981da4SDimitry Andric // Verify debug flag on debug instructions. Check this first because reg0
2447c0981da4SDimitry Andric // indicates an undefined debug value.
2448c0981da4SDimitry Andric if (MI->isDebugInstr() && MO->isUse()) {
2449c0981da4SDimitry Andric if (!MO->isDebug())
2450c0981da4SDimitry Andric report("Register operand must be marked debug", MO, MONum);
2451c0981da4SDimitry Andric } else if (MO->isDebug()) {
2452c0981da4SDimitry Andric report("Register operand must not be marked debug", MO, MONum);
2453c0981da4SDimitry Andric }
2454c0981da4SDimitry Andric
24551d5ae102SDimitry Andric const Register Reg = MO->getReg();
2456009b1c42SEd Schouten if (!Reg)
2457009b1c42SEd Schouten return;
2458ecbca9f5SDimitry Andric if (MRI->tracksLiveness() && !MI->isDebugInstr())
245963faed5bSDimitry Andric checkLiveness(MO, MONum);
2460009b1c42SEd Schouten
2461145449b1SDimitry Andric if (MO->isDef() && MO->isUndef() && !MO->getSubReg() &&
2462145449b1SDimitry Andric MO->getReg().isVirtual()) // TODO: Apply to physregs too
2463145449b1SDimitry Andric report("Undef virtual register def operands require a subregister", MO, MONum);
2464145449b1SDimitry Andric
2465522600a2SDimitry Andric // Verify the consistency of tied operands.
2466522600a2SDimitry Andric if (MO->isTied()) {
2467522600a2SDimitry Andric unsigned OtherIdx = MI->findTiedOperandIdx(MONum);
2468522600a2SDimitry Andric const MachineOperand &OtherMO = MI->getOperand(OtherIdx);
2469522600a2SDimitry Andric if (!OtherMO.isReg())
2470522600a2SDimitry Andric report("Must be tied to a register", MO, MONum);
2471522600a2SDimitry Andric if (!OtherMO.isTied())
2472522600a2SDimitry Andric report("Missing tie flags on tied operand", MO, MONum);
2473522600a2SDimitry Andric if (MI->findTiedOperandIdx(OtherIdx) != MONum)
2474522600a2SDimitry Andric report("Inconsistent tie links", MO, MONum);
2475522600a2SDimitry Andric if (MONum < MCID.getNumDefs()) {
2476522600a2SDimitry Andric if (OtherIdx < MCID.getNumOperands()) {
2477522600a2SDimitry Andric if (-1 == MCID.getOperandConstraint(OtherIdx, MCOI::TIED_TO))
2478522600a2SDimitry Andric report("Explicit def tied to explicit use without tie constraint",
2479522600a2SDimitry Andric MO, MONum);
2480522600a2SDimitry Andric } else {
2481522600a2SDimitry Andric if (!OtherMO.isImplicit())
2482522600a2SDimitry Andric report("Explicit def should be tied to implicit use", MO, MONum);
2483522600a2SDimitry Andric }
2484522600a2SDimitry Andric }
2485522600a2SDimitry Andric }
2486522600a2SDimitry Andric
2487cfca06d7SDimitry Andric // Verify two-address constraints after the twoaddressinstruction pass.
2488cfca06d7SDimitry Andric // Both twoaddressinstruction pass and phi-node-elimination pass call
2489b1c73532SDimitry Andric // MRI->leaveSSA() to set MF as not IsSSA, we should do the verification
2490b1c73532SDimitry Andric // after twoaddressinstruction pass not after phi-node-elimination pass. So
2491b1c73532SDimitry Andric // we shouldn't use the IsSSA as the condition, we should based on
2492cfca06d7SDimitry Andric // TiedOpsRewritten property to verify two-address constraints, this
2493cfca06d7SDimitry Andric // property will be set in twoaddressinstruction pass.
249458b69754SDimitry Andric unsigned DefIdx;
2495cfca06d7SDimitry Andric if (MF->getProperties().hasProperty(
2496cfca06d7SDimitry Andric MachineFunctionProperties::Property::TiedOpsRewritten) &&
2497cfca06d7SDimitry Andric MO->isUse() && MI->isRegTiedToDefOperand(MONum, &DefIdx) &&
249858b69754SDimitry Andric Reg != MI->getOperand(DefIdx).getReg())
249958b69754SDimitry Andric report("Two-address instruction operands must be identical", MO, MONum);
2500009b1c42SEd Schouten
2501009b1c42SEd Schouten // Check register classes.
2502009b1c42SEd Schouten unsigned SubIdx = MO->getSubReg();
2503009b1c42SEd Schouten
2504e3b55780SDimitry Andric if (Reg.isPhysical()) {
2505009b1c42SEd Schouten if (SubIdx) {
250630815c53SDimitry Andric report("Illegal subregister index for physical register", MO, MONum);
2507009b1c42SEd Schouten return;
2508009b1c42SEd Schouten }
2509044eb2f6SDimitry Andric if (MONum < MCID.getNumOperands()) {
251058b69754SDimitry Andric if (const TargetRegisterClass *DRC =
251158b69754SDimitry Andric TII->getRegClass(MCID, MONum, TRI, *MF)) {
251230815c53SDimitry Andric if (!DRC->contains(Reg)) {
2513009b1c42SEd Schouten report("Illegal physical register for instruction", MO, MONum);
2514044eb2f6SDimitry Andric errs() << printReg(Reg, TRI) << " is not a "
251567c32a98SDimitry Andric << TRI->getRegClassName(DRC) << " register.\n";
2516009b1c42SEd Schouten }
2517009b1c42SEd Schouten }
2518044eb2f6SDimitry Andric }
2519eb11fae6SDimitry Andric if (MO->isRenamable()) {
2520eb11fae6SDimitry Andric if (MRI->isReserved(Reg)) {
2521eb11fae6SDimitry Andric report("isRenamable set on reserved register", MO, MONum);
2522eb11fae6SDimitry Andric return;
2523eb11fae6SDimitry Andric }
2524eb11fae6SDimitry Andric }
2525009b1c42SEd Schouten } else {
2526009b1c42SEd Schouten // Virtual register.
252701095a5dSDimitry Andric const TargetRegisterClass *RC = MRI->getRegClassOrNull(Reg);
252801095a5dSDimitry Andric if (!RC) {
252901095a5dSDimitry Andric // This is a generic virtual register.
2530b915e9e0SDimitry Andric
2531cfca06d7SDimitry Andric // Do not allow undef uses for generic virtual registers. This ensures
2532cfca06d7SDimitry Andric // getVRegDef can never fail and return null on a generic register.
2533cfca06d7SDimitry Andric //
2534cfca06d7SDimitry Andric // FIXME: This restriction should probably be broadened to all SSA
2535cfca06d7SDimitry Andric // MIR. However, DetectDeadLanes/ProcessImplicitDefs technically still
2536cfca06d7SDimitry Andric // run on the SSA function just before phi elimination.
2537cfca06d7SDimitry Andric if (MO->isUndef())
2538cfca06d7SDimitry Andric report("Generic virtual register use cannot be undef", MO, MONum);
2539cfca06d7SDimitry Andric
254077fc4c14SDimitry Andric // Debug value instruction is permitted to use undefined vregs.
254177fc4c14SDimitry Andric // This is a performance measure to skip the overhead of immediately
254277fc4c14SDimitry Andric // pruning unused debug operands. The final undef substitution occurs
254377fc4c14SDimitry Andric // when debug values are allocated in LDVImpl::handleDebugValue, so
254477fc4c14SDimitry Andric // these verifications always apply after this pass.
254577fc4c14SDimitry Andric if (isFunctionTracksDebugUserValues || !MO->isUse() ||
254677fc4c14SDimitry Andric !MI->isDebugValue() || !MRI->def_empty(Reg)) {
2547b915e9e0SDimitry Andric // If we're post-Select, we can't have gvregs anymore.
2548b915e9e0SDimitry Andric if (isFunctionSelected) {
2549b915e9e0SDimitry Andric report("Generic virtual register invalid in a Selected function",
2550b915e9e0SDimitry Andric MO, MONum);
255101095a5dSDimitry Andric return;
255201095a5dSDimitry Andric }
2553b915e9e0SDimitry Andric
2554b915e9e0SDimitry Andric // The gvreg must have a type and it must not have a SubIdx.
2555b915e9e0SDimitry Andric LLT Ty = MRI->getType(Reg);
2556b915e9e0SDimitry Andric if (!Ty.isValid()) {
2557b915e9e0SDimitry Andric report("Generic virtual register must have a valid type", MO,
2558b915e9e0SDimitry Andric MONum);
2559b915e9e0SDimitry Andric return;
2560b915e9e0SDimitry Andric }
2561b915e9e0SDimitry Andric
256201095a5dSDimitry Andric const RegisterBank *RegBank = MRI->getRegBankOrNull(Reg);
25637fa27ce4SDimitry Andric const RegisterBankInfo *RBI = MF->getSubtarget().getRegBankInfo();
2564b915e9e0SDimitry Andric
2565b915e9e0SDimitry Andric // If we're post-RegBankSelect, the gvreg must have a bank.
2566b915e9e0SDimitry Andric if (!RegBank && isFunctionRegBankSelected) {
2567b915e9e0SDimitry Andric report("Generic virtual register must have a bank in a "
2568b915e9e0SDimitry Andric "RegBankSelected function",
2569b915e9e0SDimitry Andric MO, MONum);
2570b915e9e0SDimitry Andric return;
2571b915e9e0SDimitry Andric }
2572b915e9e0SDimitry Andric
2573b915e9e0SDimitry Andric // Make sure the register fits into its register bank if any.
2574b1c73532SDimitry Andric if (RegBank && Ty.isValid() && !Ty.isScalableVector() &&
25757fa27ce4SDimitry Andric RBI->getMaximumSize(RegBank->getID()) < Ty.getSizeInBits()) {
257601095a5dSDimitry Andric report("Register bank is too small for virtual register", MO,
257701095a5dSDimitry Andric MONum);
257801095a5dSDimitry Andric errs() << "Register bank " << RegBank->getName() << " too small("
25797fa27ce4SDimitry Andric << RBI->getMaximumSize(RegBank->getID()) << ") to fit "
25807fa27ce4SDimitry Andric << Ty.getSizeInBits() << "-bits\n";
258101095a5dSDimitry Andric return;
258201095a5dSDimitry Andric }
258377fc4c14SDimitry Andric }
258477fc4c14SDimitry Andric
258501095a5dSDimitry Andric if (SubIdx) {
2586e6d15924SDimitry Andric report("Generic virtual register does not allow subregister index", MO,
2587b915e9e0SDimitry Andric MONum);
258801095a5dSDimitry Andric return;
258901095a5dSDimitry Andric }
2590b915e9e0SDimitry Andric
2591b915e9e0SDimitry Andric // If this is a target specific instruction and this operand
2592b915e9e0SDimitry Andric // has register class constraint, the virtual register must
2593b915e9e0SDimitry Andric // comply to it.
2594b915e9e0SDimitry Andric if (!isPreISelGenericOpcode(MCID.getOpcode()) &&
2595044eb2f6SDimitry Andric MONum < MCID.getNumOperands() &&
2596b915e9e0SDimitry Andric TII->getRegClass(MCID, MONum, TRI, *MF)) {
2597b915e9e0SDimitry Andric report("Virtual register does not match instruction constraint", MO,
2598b915e9e0SDimitry Andric MONum);
2599b915e9e0SDimitry Andric errs() << "Expect register class "
2600b915e9e0SDimitry Andric << TRI->getRegClassName(
2601b915e9e0SDimitry Andric TII->getRegClass(MCID, MONum, TRI, *MF))
2602b915e9e0SDimitry Andric << " but got nothing\n";
2603b915e9e0SDimitry Andric return;
2604b915e9e0SDimitry Andric }
2605b915e9e0SDimitry Andric
260601095a5dSDimitry Andric break;
260701095a5dSDimitry Andric }
2608009b1c42SEd Schouten if (SubIdx) {
260930815c53SDimitry Andric const TargetRegisterClass *SRC =
261030815c53SDimitry Andric TRI->getSubClassWithSubReg(RC, SubIdx);
2611abdf259dSRoman Divacky if (!SRC) {
2612009b1c42SEd Schouten report("Invalid subregister index for virtual register", MO, MONum);
26135a5ac124SDimitry Andric errs() << "Register class " << TRI->getRegClassName(RC)
2614abdf259dSRoman Divacky << " does not support subreg index " << SubIdx << "\n";
2615009b1c42SEd Schouten return;
2616009b1c42SEd Schouten }
261730815c53SDimitry Andric if (RC != SRC) {
261830815c53SDimitry Andric report("Invalid register class for subregister index", MO, MONum);
26195a5ac124SDimitry Andric errs() << "Register class " << TRI->getRegClassName(RC)
262030815c53SDimitry Andric << " does not fully support subreg index " << SubIdx << "\n";
262130815c53SDimitry Andric return;
262230815c53SDimitry Andric }
2623009b1c42SEd Schouten }
2624044eb2f6SDimitry Andric if (MONum < MCID.getNumOperands()) {
262558b69754SDimitry Andric if (const TargetRegisterClass *DRC =
262658b69754SDimitry Andric TII->getRegClass(MCID, MONum, TRI, *MF)) {
262730815c53SDimitry Andric if (SubIdx) {
262830815c53SDimitry Andric const TargetRegisterClass *SuperRC =
26295a5ac124SDimitry Andric TRI->getLargestLegalSuperClass(RC, *MF);
263030815c53SDimitry Andric if (!SuperRC) {
263130815c53SDimitry Andric report("No largest legal super class exists.", MO, MONum);
263230815c53SDimitry Andric return;
263330815c53SDimitry Andric }
263430815c53SDimitry Andric DRC = TRI->getMatchingSuperRegClass(SuperRC, DRC, SubIdx);
263530815c53SDimitry Andric if (!DRC) {
263630815c53SDimitry Andric report("No matching super-reg register class.", MO, MONum);
263730815c53SDimitry Andric return;
263830815c53SDimitry Andric }
263930815c53SDimitry Andric }
264056fe8f14SDimitry Andric if (!RC->hasSuperClassEq(DRC)) {
2641009b1c42SEd Schouten report("Illegal virtual register for instruction", MO, MONum);
26425a5ac124SDimitry Andric errs() << "Expected a " << TRI->getRegClassName(DRC)
264367c32a98SDimitry Andric << " register, but got a " << TRI->getRegClassName(RC)
264467c32a98SDimitry Andric << " register\n";
2645009b1c42SEd Schouten }
2646009b1c42SEd Schouten }
2647009b1c42SEd Schouten }
2648009b1c42SEd Schouten }
2649009b1c42SEd Schouten break;
2650009b1c42SEd Schouten }
265159850d08SRoman Divacky
265263faed5bSDimitry Andric case MachineOperand::MO_RegisterMask:
265363faed5bSDimitry Andric regMasks.push_back(MO->getRegMask());
265463faed5bSDimitry Andric break;
265563faed5bSDimitry Andric
265659850d08SRoman Divacky case MachineOperand::MO_MachineBasicBlock:
26576fe5c7aaSRoman Divacky if (MI->isPHI() && !MO->getMBB()->isSuccessor(MI->getParent()))
265859850d08SRoman Divacky report("PHI operand is not in the CFG", MO, MONum);
265959850d08SRoman Divacky break;
266059850d08SRoman Divacky
2661cf099d11SDimitry Andric case MachineOperand::MO_FrameIndex:
2662cf099d11SDimitry Andric if (LiveStks && LiveStks->hasInterval(MO->getIndex()) &&
266301095a5dSDimitry Andric LiveInts && !LiveInts->isNotInMIMap(*MI)) {
2664dd58ef01SDimitry Andric int FI = MO->getIndex();
2665dd58ef01SDimitry Andric LiveInterval &LI = LiveStks->getInterval(FI);
266601095a5dSDimitry Andric SlotIndex Idx = LiveInts->getInstructionIndex(*MI);
2667dd58ef01SDimitry Andric
2668dd58ef01SDimitry Andric bool stores = MI->mayStore();
2669dd58ef01SDimitry Andric bool loads = MI->mayLoad();
2670dd58ef01SDimitry Andric // For a memory-to-memory move, we need to check if the frame
2671dd58ef01SDimitry Andric // index is used for storing or loading, by inspecting the
2672dd58ef01SDimitry Andric // memory operands.
2673dd58ef01SDimitry Andric if (stores && loads) {
2674dd58ef01SDimitry Andric for (auto *MMO : MI->memoperands()) {
2675dd58ef01SDimitry Andric const PseudoSourceValue *PSV = MMO->getPseudoValue();
2676dd58ef01SDimitry Andric if (PSV == nullptr) continue;
2677dd58ef01SDimitry Andric const FixedStackPseudoSourceValue *Value =
2678dd58ef01SDimitry Andric dyn_cast<FixedStackPseudoSourceValue>(PSV);
2679dd58ef01SDimitry Andric if (Value == nullptr) continue;
2680dd58ef01SDimitry Andric if (Value->getFrameIndex() != FI) continue;
2681dd58ef01SDimitry Andric
2682dd58ef01SDimitry Andric if (MMO->isStore())
2683dd58ef01SDimitry Andric loads = false;
2684dd58ef01SDimitry Andric else
2685dd58ef01SDimitry Andric stores = false;
2686dd58ef01SDimitry Andric break;
2687dd58ef01SDimitry Andric }
2688dd58ef01SDimitry Andric if (loads == stores)
2689dd58ef01SDimitry Andric report("Missing fixed stack memoperand.", MI);
2690dd58ef01SDimitry Andric }
2691dd58ef01SDimitry Andric if (loads && !LI.liveAt(Idx.getRegSlot(true))) {
2692cf099d11SDimitry Andric report("Instruction loads from dead spill slot", MO, MONum);
26935a5ac124SDimitry Andric errs() << "Live stack: " << LI << '\n';
2694cf099d11SDimitry Andric }
2695dd58ef01SDimitry Andric if (stores && !LI.liveAt(Idx.getRegSlot())) {
2696cf099d11SDimitry Andric report("Instruction stores to dead spill slot", MO, MONum);
26975a5ac124SDimitry Andric errs() << "Live stack: " << LI << '\n';
2698cf099d11SDimitry Andric }
2699cf099d11SDimitry Andric }
2700cf099d11SDimitry Andric break;
2701cf099d11SDimitry Andric
2702145449b1SDimitry Andric case MachineOperand::MO_CFIIndex:
2703145449b1SDimitry Andric if (MO->getCFIIndex() >= MF->getFrameInstructions().size())
2704145449b1SDimitry Andric report("CFI instruction has invalid index", MO, MONum);
2705145449b1SDimitry Andric break;
2706145449b1SDimitry Andric
2707009b1c42SEd Schouten default:
2708009b1c42SEd Schouten break;
2709009b1c42SEd Schouten }
2710009b1c42SEd Schouten }
2711009b1c42SEd Schouten
checkLivenessAtUse(const MachineOperand * MO,unsigned MONum,SlotIndex UseIdx,const LiveRange & LR,Register VRegOrUnit,LaneBitmask LaneMask)271201095a5dSDimitry Andric void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
2713b60736ecSDimitry Andric unsigned MONum, SlotIndex UseIdx,
2714b60736ecSDimitry Andric const LiveRange &LR,
2715b60736ecSDimitry Andric Register VRegOrUnit,
271601095a5dSDimitry Andric LaneBitmask LaneMask) {
2717b1c73532SDimitry Andric const MachineInstr *MI = MO->getParent();
271801095a5dSDimitry Andric LiveQueryResult LRQ = LR.Query(UseIdx);
2719b1c73532SDimitry Andric bool HasValue = LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut());
272001095a5dSDimitry Andric // Check if we have a segment at the use, note however that we only need one
272101095a5dSDimitry Andric // live subregister range, the others may be dead.
2722b1c73532SDimitry Andric if (!HasValue && LaneMask.none()) {
272301095a5dSDimitry Andric report("No live segment at use", MO, MONum);
272401095a5dSDimitry Andric report_context_liverange(LR);
272501095a5dSDimitry Andric report_context_vreg_regunit(VRegOrUnit);
272601095a5dSDimitry Andric report_context(UseIdx);
272701095a5dSDimitry Andric }
272801095a5dSDimitry Andric if (MO->isKill() && !LRQ.isKill()) {
272901095a5dSDimitry Andric report("Live range continues after kill flag", MO, MONum);
273001095a5dSDimitry Andric report_context_liverange(LR);
273101095a5dSDimitry Andric report_context_vreg_regunit(VRegOrUnit);
2732b915e9e0SDimitry Andric if (LaneMask.any())
273301095a5dSDimitry Andric report_context_lanemask(LaneMask);
273401095a5dSDimitry Andric report_context(UseIdx);
273501095a5dSDimitry Andric }
273601095a5dSDimitry Andric }
273701095a5dSDimitry Andric
checkLivenessAtDef(const MachineOperand * MO,unsigned MONum,SlotIndex DefIdx,const LiveRange & LR,Register VRegOrUnit,bool SubRangeCheck,LaneBitmask LaneMask)273801095a5dSDimitry Andric void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
2739b60736ecSDimitry Andric unsigned MONum, SlotIndex DefIdx,
2740b60736ecSDimitry Andric const LiveRange &LR,
2741b60736ecSDimitry Andric Register VRegOrUnit,
2742b60736ecSDimitry Andric bool SubRangeCheck,
2743b60736ecSDimitry Andric LaneBitmask LaneMask) {
274401095a5dSDimitry Andric if (const VNInfo *VNI = LR.getVNInfoAt(DefIdx)) {
2745e3b55780SDimitry Andric // The LR can correspond to the whole reg and its def slot is not obliged
2746e3b55780SDimitry Andric // to be the same as the MO' def slot. E.g. when we check here "normal"
2747e3b55780SDimitry Andric // subreg MO but there is other EC subreg MO in the same instruction so the
2748e3b55780SDimitry Andric // whole reg has EC def slot and differs from the currently checked MO' def
2749e3b55780SDimitry Andric // slot. For example:
2750e3b55780SDimitry Andric // %0 [16e,32r:0) 0@16e L..3 [16e,32r:0) 0@16e L..C [16r,32r:0) 0@16r
2751e3b55780SDimitry Andric // Check that there is an early-clobber def of the same superregister
2752e3b55780SDimitry Andric // somewhere is performed in visitMachineFunctionAfter()
2753e3b55780SDimitry Andric if (((SubRangeCheck || MO->getSubReg() == 0) && VNI->def != DefIdx) ||
2754e3b55780SDimitry Andric !SlotIndex::isSameInstr(VNI->def, DefIdx) ||
2755e3b55780SDimitry Andric (VNI->def != DefIdx &&
2756e3b55780SDimitry Andric (!VNI->def.isEarlyClobber() || !DefIdx.isRegister()))) {
275701095a5dSDimitry Andric report("Inconsistent valno->def", MO, MONum);
275801095a5dSDimitry Andric report_context_liverange(LR);
275901095a5dSDimitry Andric report_context_vreg_regunit(VRegOrUnit);
2760b915e9e0SDimitry Andric if (LaneMask.any())
276101095a5dSDimitry Andric report_context_lanemask(LaneMask);
276201095a5dSDimitry Andric report_context(*VNI);
276301095a5dSDimitry Andric report_context(DefIdx);
276401095a5dSDimitry Andric }
276501095a5dSDimitry Andric } else {
276601095a5dSDimitry Andric report("No live segment at def", MO, MONum);
276701095a5dSDimitry Andric report_context_liverange(LR);
276801095a5dSDimitry Andric report_context_vreg_regunit(VRegOrUnit);
2769b915e9e0SDimitry Andric if (LaneMask.any())
277001095a5dSDimitry Andric report_context_lanemask(LaneMask);
277101095a5dSDimitry Andric report_context(DefIdx);
277201095a5dSDimitry Andric }
277301095a5dSDimitry Andric // Check that, if the dead def flag is present, LiveInts agree.
277401095a5dSDimitry Andric if (MO->isDead()) {
277501095a5dSDimitry Andric LiveQueryResult LRQ = LR.Query(DefIdx);
277601095a5dSDimitry Andric if (!LRQ.isDeadDef()) {
2777e3b55780SDimitry Andric assert(VRegOrUnit.isVirtual() && "Expecting a virtual register.");
2778d8e91e46SDimitry Andric // A dead subreg def only tells us that the specific subreg is dead. There
2779d8e91e46SDimitry Andric // could be other non-dead defs of other subregs, or we could have other
2780d8e91e46SDimitry Andric // parts of the register being live through the instruction. So unless we
2781d8e91e46SDimitry Andric // are checking liveness for a subrange it is ok for the live range to
2782d8e91e46SDimitry Andric // continue, given that we have a dead def of a subregister.
2783d8e91e46SDimitry Andric if (SubRangeCheck || MO->getSubReg() == 0) {
278401095a5dSDimitry Andric report("Live range continues after dead def flag", MO, MONum);
278501095a5dSDimitry Andric report_context_liverange(LR);
278601095a5dSDimitry Andric report_context_vreg_regunit(VRegOrUnit);
2787b915e9e0SDimitry Andric if (LaneMask.any())
278801095a5dSDimitry Andric report_context_lanemask(LaneMask);
278901095a5dSDimitry Andric }
279001095a5dSDimitry Andric }
279101095a5dSDimitry Andric }
279201095a5dSDimitry Andric }
279301095a5dSDimitry Andric
checkLiveness(const MachineOperand * MO,unsigned MONum)279463faed5bSDimitry Andric void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
279563faed5bSDimitry Andric const MachineInstr *MI = MO->getParent();
2796b60736ecSDimitry Andric const Register Reg = MO->getReg();
2797c0981da4SDimitry Andric const unsigned SubRegIdx = MO->getSubReg();
2798c0981da4SDimitry Andric
2799c0981da4SDimitry Andric const LiveInterval *LI = nullptr;
2800c0981da4SDimitry Andric if (LiveInts && Reg.isVirtual()) {
2801c0981da4SDimitry Andric if (LiveInts->hasInterval(Reg)) {
2802c0981da4SDimitry Andric LI = &LiveInts->getInterval(Reg);
280377fc4c14SDimitry Andric if (SubRegIdx != 0 && (MO->isDef() || !MO->isUndef()) && !LI->empty() &&
280477fc4c14SDimitry Andric !LI->hasSubRanges() && MRI->shouldTrackSubRegLiveness(Reg))
2805c0981da4SDimitry Andric report("Live interval for subreg operand has no subranges", MO, MONum);
2806c0981da4SDimitry Andric } else {
2807c0981da4SDimitry Andric report("Virtual register has no live interval", MO, MONum);
2808c0981da4SDimitry Andric }
2809c0981da4SDimitry Andric }
281063faed5bSDimitry Andric
281163faed5bSDimitry Andric // Both use and def operands can read a register.
281263faed5bSDimitry Andric if (MO->readsReg()) {
281358b69754SDimitry Andric if (MO->isKill())
281463faed5bSDimitry Andric addRegWithSubRegs(regsKilled, Reg);
281563faed5bSDimitry Andric
2816c0981da4SDimitry Andric // Check that LiveVars knows this kill (unless we are inside a bundle, in
2817c0981da4SDimitry Andric // which case we have already checked that LiveVars knows any kills on the
2818c0981da4SDimitry Andric // bundle header instead).
2819c0981da4SDimitry Andric if (LiveVars && Reg.isVirtual() && MO->isKill() &&
2820c0981da4SDimitry Andric !MI->isBundledWithPred()) {
282163faed5bSDimitry Andric LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
2822b915e9e0SDimitry Andric if (!is_contained(VI.Kills, MI))
282363faed5bSDimitry Andric report("Kill missing from LiveVariables", MO, MONum);
282463faed5bSDimitry Andric }
282563faed5bSDimitry Andric
282663faed5bSDimitry Andric // Check LiveInts liveness and kill.
282701095a5dSDimitry Andric if (LiveInts && !LiveInts->isNotInMIMap(*MI)) {
2828b1c73532SDimitry Andric SlotIndex UseIdx;
2829b1c73532SDimitry Andric if (MI->isPHI()) {
2830b1c73532SDimitry Andric // PHI use occurs on the edge, so check for live out here instead.
2831b1c73532SDimitry Andric UseIdx = LiveInts->getMBBEndIdx(
2832b1c73532SDimitry Andric MI->getOperand(MONum + 1).getMBB()).getPrevSlot();
2833b1c73532SDimitry Andric } else {
2834b1c73532SDimitry Andric UseIdx = LiveInts->getInstructionIndex(*MI);
2835b1c73532SDimitry Andric }
283658b69754SDimitry Andric // Check the cached regunit intervals.
2837b60736ecSDimitry Andric if (Reg.isPhysical() && !isReserved(Reg)) {
28387fa27ce4SDimitry Andric for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg())) {
28397fa27ce4SDimitry Andric if (MRI->isReservedRegUnit(Unit))
2840edad5bcbSDimitry Andric continue;
28417fa27ce4SDimitry Andric if (const LiveRange *LR = LiveInts->getCachedRegUnit(Unit))
28427fa27ce4SDimitry Andric checkLivenessAtUse(MO, MONum, UseIdx, *LR, Unit);
284358b69754SDimitry Andric }
284458b69754SDimitry Andric }
284558b69754SDimitry Andric
2846c0981da4SDimitry Andric if (Reg.isVirtual()) {
284758b69754SDimitry Andric // This is a virtual register interval.
2848c0981da4SDimitry Andric checkLivenessAtUse(MO, MONum, UseIdx, *LI, Reg);
284901095a5dSDimitry Andric
2850c0981da4SDimitry Andric if (LI->hasSubRanges() && !MO->isDef()) {
285101095a5dSDimitry Andric LaneBitmask MOMask = SubRegIdx != 0
285201095a5dSDimitry Andric ? TRI->getSubRegIndexLaneMask(SubRegIdx)
285301095a5dSDimitry Andric : MRI->getMaxLaneMaskForVReg(Reg);
2854b915e9e0SDimitry Andric LaneBitmask LiveInMask;
2855c0981da4SDimitry Andric for (const LiveInterval::SubRange &SR : LI->subranges()) {
2856b915e9e0SDimitry Andric if ((MOMask & SR.LaneMask).none())
285701095a5dSDimitry Andric continue;
285801095a5dSDimitry Andric checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask);
285901095a5dSDimitry Andric LiveQueryResult LRQ = SR.Query(UseIdx);
2860b1c73532SDimitry Andric if (LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut()))
286101095a5dSDimitry Andric LiveInMask |= SR.LaneMask;
286263faed5bSDimitry Andric }
286301095a5dSDimitry Andric // At least parts of the register has to be live at the use.
2864b915e9e0SDimitry Andric if ((LiveInMask & MOMask).none()) {
286501095a5dSDimitry Andric report("No live subrange at use", MO, MONum);
2866c0981da4SDimitry Andric report_context(*LI);
286701095a5dSDimitry Andric report_context(UseIdx);
286801095a5dSDimitry Andric }
2869b1c73532SDimitry Andric // For PHIs all lanes should be live
2870b1c73532SDimitry Andric if (MI->isPHI() && LiveInMask != MOMask) {
2871b1c73532SDimitry Andric report("Not all lanes of PHI source live at use", MO, MONum);
2872b1c73532SDimitry Andric report_context(*LI);
2873b1c73532SDimitry Andric report_context(UseIdx);
2874b1c73532SDimitry Andric }
287563faed5bSDimitry Andric }
287663faed5bSDimitry Andric }
287763faed5bSDimitry Andric }
287863faed5bSDimitry Andric
287963faed5bSDimitry Andric // Use of a dead register.
288063faed5bSDimitry Andric if (!regsLive.count(Reg)) {
2881c0981da4SDimitry Andric if (Reg.isPhysical()) {
288263faed5bSDimitry Andric // Reserved registers may be used even when 'dead'.
288367c32a98SDimitry Andric bool Bad = !isReserved(Reg);
288467c32a98SDimitry Andric // We are fine if just any subregister has a defined value.
288567c32a98SDimitry Andric if (Bad) {
2886706b4fc4SDimitry Andric
2887706b4fc4SDimitry Andric for (const MCPhysReg &SubReg : TRI->subregs(Reg)) {
2888706b4fc4SDimitry Andric if (regsLive.count(SubReg)) {
288967c32a98SDimitry Andric Bad = false;
289067c32a98SDimitry Andric break;
289167c32a98SDimitry Andric }
289267c32a98SDimitry Andric }
289367c32a98SDimitry Andric }
28945a5ac124SDimitry Andric // If there is an additional implicit-use of a super register we stop
28955a5ac124SDimitry Andric // here. By definition we are fine if the super register is not
28965a5ac124SDimitry Andric // (completely) dead, if the complete super register is dead we will
28975a5ac124SDimitry Andric // get a report for its operand.
28985a5ac124SDimitry Andric if (Bad) {
28995a5ac124SDimitry Andric for (const MachineOperand &MOP : MI->uses()) {
2900d8e91e46SDimitry Andric if (!MOP.isReg() || !MOP.isImplicit())
29015a5ac124SDimitry Andric continue;
2902d8e91e46SDimitry Andric
2903c0981da4SDimitry Andric if (!MOP.getReg().isPhysical())
29045a5ac124SDimitry Andric continue;
2905d8e91e46SDimitry Andric
2906344a3780SDimitry Andric if (llvm::is_contained(TRI->subregs(MOP.getReg()), Reg))
29075a5ac124SDimitry Andric Bad = false;
29085a5ac124SDimitry Andric }
29095a5ac124SDimitry Andric }
291067c32a98SDimitry Andric if (Bad)
291163faed5bSDimitry Andric report("Using an undefined physical register", MO, MONum);
291258b69754SDimitry Andric } else if (MRI->def_empty(Reg)) {
291358b69754SDimitry Andric report("Reading virtual register without a def", MO, MONum);
291463faed5bSDimitry Andric } else {
291563faed5bSDimitry Andric BBInfo &MInfo = MBBInfoMap[MI->getParent()];
291663faed5bSDimitry Andric // We don't know which virtual registers are live in, so only complain
291763faed5bSDimitry Andric // if vreg was killed in this MBB. Otherwise keep track of vregs that
291863faed5bSDimitry Andric // must be live in. PHI instructions are handled separately.
291963faed5bSDimitry Andric if (MInfo.regsKilled.count(Reg))
292063faed5bSDimitry Andric report("Using a killed virtual register", MO, MONum);
292163faed5bSDimitry Andric else if (!MI->isPHI())
292263faed5bSDimitry Andric MInfo.vregsLiveIn.insert(std::make_pair(Reg, MI));
292363faed5bSDimitry Andric }
292463faed5bSDimitry Andric }
292563faed5bSDimitry Andric }
292663faed5bSDimitry Andric
292763faed5bSDimitry Andric if (MO->isDef()) {
292863faed5bSDimitry Andric // Register defined.
292963faed5bSDimitry Andric // TODO: verify that earlyclobber ops are not used.
293063faed5bSDimitry Andric if (MO->isDead())
293163faed5bSDimitry Andric addRegWithSubRegs(regsDead, Reg);
293263faed5bSDimitry Andric else
293363faed5bSDimitry Andric addRegWithSubRegs(regsDefined, Reg);
293463faed5bSDimitry Andric
293563faed5bSDimitry Andric // Verify SSA form.
2936c0981da4SDimitry Andric if (MRI->isSSA() && Reg.isVirtual() &&
29375ca98fd9SDimitry Andric std::next(MRI->def_begin(Reg)) != MRI->def_end())
293863faed5bSDimitry Andric report("Multiple virtual register defs in SSA form", MO, MONum);
293963faed5bSDimitry Andric
2940f8af5cf6SDimitry Andric // Check LiveInts for a live segment, but only for virtual registers.
294101095a5dSDimitry Andric if (LiveInts && !LiveInts->isNotInMIMap(*MI)) {
294201095a5dSDimitry Andric SlotIndex DefIdx = LiveInts->getInstructionIndex(*MI);
294358b69754SDimitry Andric DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber());
294401095a5dSDimitry Andric
2945c0981da4SDimitry Andric if (Reg.isVirtual()) {
2946c0981da4SDimitry Andric checkLivenessAtDef(MO, MONum, DefIdx, *LI, Reg);
294701095a5dSDimitry Andric
2948c0981da4SDimitry Andric if (LI->hasSubRanges()) {
294901095a5dSDimitry Andric LaneBitmask MOMask = SubRegIdx != 0
295001095a5dSDimitry Andric ? TRI->getSubRegIndexLaneMask(SubRegIdx)
295101095a5dSDimitry Andric : MRI->getMaxLaneMaskForVReg(Reg);
2952c0981da4SDimitry Andric for (const LiveInterval::SubRange &SR : LI->subranges()) {
2953b915e9e0SDimitry Andric if ((SR.LaneMask & MOMask).none())
295401095a5dSDimitry Andric continue;
2955d8e91e46SDimitry Andric checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask);
2956f8af5cf6SDimitry Andric }
2957f8af5cf6SDimitry Andric }
295863faed5bSDimitry Andric }
295963faed5bSDimitry Andric }
296063faed5bSDimitry Andric }
296101095a5dSDimitry Andric }
296263faed5bSDimitry Andric
296358b69754SDimitry Andric // This function gets called after visiting all instructions in a bundle. The
296458b69754SDimitry Andric // argument points to the bundle header.
296558b69754SDimitry Andric // Normal stand-alone instructions are also considered 'bundles', and this
296658b69754SDimitry Andric // function is called for all of them.
visitMachineBundleAfter(const MachineInstr * MI)296758b69754SDimitry Andric void MachineVerifier::visitMachineBundleAfter(const MachineInstr *MI) {
2968009b1c42SEd Schouten BBInfo &MInfo = MBBInfoMap[MI->getParent()];
2969009b1c42SEd Schouten set_union(MInfo.regsKilled, regsKilled);
2970d39c594dSDimitry Andric set_subtract(regsLive, regsKilled); regsKilled.clear();
297163faed5bSDimitry Andric // Kill any masked registers.
297263faed5bSDimitry Andric while (!regMasks.empty()) {
297363faed5bSDimitry Andric const uint32_t *Mask = regMasks.pop_back_val();
2974b60736ecSDimitry Andric for (Register Reg : regsLive)
2975b60736ecSDimitry Andric if (Reg.isPhysical() &&
2976b60736ecSDimitry Andric MachineOperand::clobbersPhysReg(Mask, Reg.asMCReg()))
2977cfca06d7SDimitry Andric regsDead.push_back(Reg);
297863faed5bSDimitry Andric }
2979009b1c42SEd Schouten set_subtract(regsLive, regsDead); regsDead.clear();
298059850d08SRoman Divacky set_union(regsLive, regsDefined); regsDefined.clear();
2981009b1c42SEd Schouten }
2982009b1c42SEd Schouten
2983009b1c42SEd Schouten void
visitMachineBasicBlockAfter(const MachineBasicBlock * MBB)298459850d08SRoman Divacky MachineVerifier::visitMachineBasicBlockAfter(const MachineBasicBlock *MBB) {
2985009b1c42SEd Schouten MBBInfoMap[MBB].regsLiveOut = regsLive;
2986009b1c42SEd Schouten regsLive.clear();
2987cf099d11SDimitry Andric
2988cf099d11SDimitry Andric if (Indexes) {
2989cf099d11SDimitry Andric SlotIndex stop = Indexes->getMBBEndIdx(MBB);
2990cf099d11SDimitry Andric if (!(stop > lastIndex)) {
2991cf099d11SDimitry Andric report("Block ends before last instruction index", MBB);
29925a5ac124SDimitry Andric errs() << "Block ends at " << stop
2993cf099d11SDimitry Andric << " last instruction was at " << lastIndex << '\n';
2994cf099d11SDimitry Andric }
2995cf099d11SDimitry Andric lastIndex = stop;
2996cf099d11SDimitry Andric }
2997009b1c42SEd Schouten }
2998009b1c42SEd Schouten
2999cfca06d7SDimitry Andric namespace {
3000cfca06d7SDimitry Andric // This implements a set of registers that serves as a filter: can filter other
3001cfca06d7SDimitry Andric // sets by passing through elements not in the filter and blocking those that
3002cfca06d7SDimitry Andric // are. Any filter implicitly includes the full set of physical registers upon
3003cfca06d7SDimitry Andric // creation, thus filtering them all out. The filter itself as a set only grows,
3004cfca06d7SDimitry Andric // and needs to be as efficient as possible.
3005cfca06d7SDimitry Andric struct VRegFilter {
3006cfca06d7SDimitry Andric // Add elements to the filter itself. \pre Input set \p FromRegSet must have
3007cfca06d7SDimitry Andric // no duplicates. Both virtual and physical registers are fine.
add__anon3a9898fa0511::VRegFilter3008cfca06d7SDimitry Andric template <typename RegSetT> void add(const RegSetT &FromRegSet) {
3009b60736ecSDimitry Andric SmallVector<Register, 0> VRegsBuffer;
3010cfca06d7SDimitry Andric filterAndAdd(FromRegSet, VRegsBuffer);
3011cfca06d7SDimitry Andric }
3012cfca06d7SDimitry Andric // Filter \p FromRegSet through the filter and append passed elements into \p
3013cfca06d7SDimitry Andric // ToVRegs. All elements appended are then added to the filter itself.
3014cfca06d7SDimitry Andric // \returns true if anything changed.
3015cfca06d7SDimitry Andric template <typename RegSetT>
filterAndAdd__anon3a9898fa0511::VRegFilter3016cfca06d7SDimitry Andric bool filterAndAdd(const RegSetT &FromRegSet,
3017b60736ecSDimitry Andric SmallVectorImpl<Register> &ToVRegs) {
3018cfca06d7SDimitry Andric unsigned SparseUniverse = Sparse.size();
3019cfca06d7SDimitry Andric unsigned NewSparseUniverse = SparseUniverse;
3020cfca06d7SDimitry Andric unsigned NewDenseSize = Dense.size();
3021cfca06d7SDimitry Andric size_t Begin = ToVRegs.size();
3022b60736ecSDimitry Andric for (Register Reg : FromRegSet) {
3023b60736ecSDimitry Andric if (!Reg.isVirtual())
3024cfca06d7SDimitry Andric continue;
3025cfca06d7SDimitry Andric unsigned Index = Register::virtReg2Index(Reg);
3026cfca06d7SDimitry Andric if (Index < SparseUniverseMax) {
3027cfca06d7SDimitry Andric if (Index < SparseUniverse && Sparse.test(Index))
3028cfca06d7SDimitry Andric continue;
3029cfca06d7SDimitry Andric NewSparseUniverse = std::max(NewSparseUniverse, Index + 1);
3030cfca06d7SDimitry Andric } else {
3031cfca06d7SDimitry Andric if (Dense.count(Reg))
3032cfca06d7SDimitry Andric continue;
3033cfca06d7SDimitry Andric ++NewDenseSize;
3034cfca06d7SDimitry Andric }
3035cfca06d7SDimitry Andric ToVRegs.push_back(Reg);
3036cfca06d7SDimitry Andric }
3037cfca06d7SDimitry Andric size_t End = ToVRegs.size();
3038cfca06d7SDimitry Andric if (Begin == End)
3039cfca06d7SDimitry Andric return false;
3040cfca06d7SDimitry Andric // Reserving space in sets once performs better than doing so continuously
3041cfca06d7SDimitry Andric // and pays easily for double look-ups (even in Dense with SparseUniverseMax
3042cfca06d7SDimitry Andric // tuned all the way down) and double iteration (the second one is over a
3043cfca06d7SDimitry Andric // SmallVector, which is a lot cheaper compared to DenseSet or BitVector).
3044cfca06d7SDimitry Andric Sparse.resize(NewSparseUniverse);
3045cfca06d7SDimitry Andric Dense.reserve(NewDenseSize);
3046cfca06d7SDimitry Andric for (unsigned I = Begin; I < End; ++I) {
3047b60736ecSDimitry Andric Register Reg = ToVRegs[I];
3048cfca06d7SDimitry Andric unsigned Index = Register::virtReg2Index(Reg);
3049cfca06d7SDimitry Andric if (Index < SparseUniverseMax)
3050cfca06d7SDimitry Andric Sparse.set(Index);
3051cfca06d7SDimitry Andric else
3052cfca06d7SDimitry Andric Dense.insert(Reg);
3053cfca06d7SDimitry Andric }
3054cfca06d7SDimitry Andric return true;
3055cfca06d7SDimitry Andric }
3056cfca06d7SDimitry Andric
3057cfca06d7SDimitry Andric private:
3058cfca06d7SDimitry Andric static constexpr unsigned SparseUniverseMax = 10 * 1024 * 8;
3059cfca06d7SDimitry Andric // VRegs indexed within SparseUniverseMax are tracked by Sparse, those beyound
3060cfca06d7SDimitry Andric // are tracked by Dense. The only purpose of the threashold and the Dense set
3061cfca06d7SDimitry Andric // is to have a reasonably growing memory usage in pathological cases (large
3062cfca06d7SDimitry Andric // number of very sparse VRegFilter instances live at the same time). In
3063cfca06d7SDimitry Andric // practice even in the worst-by-execution time cases having all elements
3064cfca06d7SDimitry Andric // tracked by Sparse (very large SparseUniverseMax scenario) tends to be more
3065cfca06d7SDimitry Andric // space efficient than if tracked by Dense. The threashold is set to keep the
3066cfca06d7SDimitry Andric // worst-case memory usage within 2x of figures determined empirically for
3067cfca06d7SDimitry Andric // "all Dense" scenario in such worst-by-execution-time cases.
3068cfca06d7SDimitry Andric BitVector Sparse;
3069cfca06d7SDimitry Andric DenseSet<unsigned> Dense;
3070cfca06d7SDimitry Andric };
3071cfca06d7SDimitry Andric
3072cfca06d7SDimitry Andric // Implements both a transfer function and a (binary, in-place) join operator
3073cfca06d7SDimitry Andric // for a dataflow over register sets with set union join and filtering transfer
3074cfca06d7SDimitry Andric // (out_b = in_b \ filter_b). filter_b is expected to be set-up ahead of time.
3075cfca06d7SDimitry Andric // Maintains out_b as its state, allowing for O(n) iteration over it at any
3076cfca06d7SDimitry Andric // time, where n is the size of the set (as opposed to O(U) where U is the
3077cfca06d7SDimitry Andric // universe). filter_b implicitly contains all physical registers at all times.
3078cfca06d7SDimitry Andric class FilteringVRegSet {
3079cfca06d7SDimitry Andric VRegFilter Filter;
3080b60736ecSDimitry Andric SmallVector<Register, 0> VRegs;
3081cfca06d7SDimitry Andric
3082cfca06d7SDimitry Andric public:
3083cfca06d7SDimitry Andric // Set-up the filter_b. \pre Input register set \p RS must have no duplicates.
3084cfca06d7SDimitry Andric // Both virtual and physical registers are fine.
addToFilter(const RegSetT & RS)3085cfca06d7SDimitry Andric template <typename RegSetT> void addToFilter(const RegSetT &RS) {
3086cfca06d7SDimitry Andric Filter.add(RS);
3087cfca06d7SDimitry Andric }
3088cfca06d7SDimitry Andric // Passes \p RS through the filter_b (transfer function) and adds what's left
3089cfca06d7SDimitry Andric // to itself (out_b).
add(const RegSetT & RS)3090cfca06d7SDimitry Andric template <typename RegSetT> bool add(const RegSetT &RS) {
3091cfca06d7SDimitry Andric // Double-duty the Filter: to maintain VRegs a set (and the join operation
3092cfca06d7SDimitry Andric // a set union) just add everything being added here to the Filter as well.
3093cfca06d7SDimitry Andric return Filter.filterAndAdd(RS, VRegs);
3094cfca06d7SDimitry Andric }
3095cfca06d7SDimitry Andric using const_iterator = decltype(VRegs)::const_iterator;
begin() const3096cfca06d7SDimitry Andric const_iterator begin() const { return VRegs.begin(); }
end() const3097cfca06d7SDimitry Andric const_iterator end() const { return VRegs.end(); }
size() const3098cfca06d7SDimitry Andric size_t size() const { return VRegs.size(); }
3099cfca06d7SDimitry Andric };
3100cfca06d7SDimitry Andric } // namespace
3101cfca06d7SDimitry Andric
3102009b1c42SEd Schouten // Calculate the largest possible vregsPassed sets. These are the registers that
3103009b1c42SEd Schouten // can pass through an MBB live, but may not be live every time. It is assumed
3104009b1c42SEd Schouten // that all vregsPassed sets are empty before the call.
calcRegsPassed()3105829000e0SRoman Divacky void MachineVerifier::calcRegsPassed() {
3106b60736ecSDimitry Andric if (MF->empty())
3107cfca06d7SDimitry Andric // ReversePostOrderTraversal doesn't handle empty functions.
3108cfca06d7SDimitry Andric return;
3109009b1c42SEd Schouten
3110b60736ecSDimitry Andric for (const MachineBasicBlock *MB :
3111b60736ecSDimitry Andric ReversePostOrderTraversal<const MachineFunction *>(MF)) {
3112b60736ecSDimitry Andric FilteringVRegSet VRegs;
3113b60736ecSDimitry Andric BBInfo &Info = MBBInfoMap[MB];
3114b60736ecSDimitry Andric assert(Info.reachable);
3115b60736ecSDimitry Andric
3116b60736ecSDimitry Andric VRegs.addToFilter(Info.regsKilled);
3117b60736ecSDimitry Andric VRegs.addToFilter(Info.regsLiveOut);
3118b60736ecSDimitry Andric for (const MachineBasicBlock *Pred : MB->predecessors()) {
3119b60736ecSDimitry Andric const BBInfo &PredInfo = MBBInfoMap[Pred];
3120b60736ecSDimitry Andric if (!PredInfo.reachable)
3121009b1c42SEd Schouten continue;
3122b60736ecSDimitry Andric
3123b60736ecSDimitry Andric VRegs.add(PredInfo.regsLiveOut);
3124b60736ecSDimitry Andric VRegs.add(PredInfo.vregsPassed);
3125009b1c42SEd Schouten }
3126b60736ecSDimitry Andric Info.vregsPassed.reserve(VRegs.size());
3127b60736ecSDimitry Andric Info.vregsPassed.insert(VRegs.begin(), VRegs.end());
3128cfca06d7SDimitry Andric }
3129009b1c42SEd Schouten }
3130009b1c42SEd Schouten
31317d453863SRoman Divacky // Calculate the set of virtual registers that must be passed through each basic
31327d453863SRoman Divacky // block in order to satisfy the requirements of successor blocks. This is very
3133829000e0SRoman Divacky // similar to calcRegsPassed, only backwards.
calcRegsRequired()31347d453863SRoman Divacky void MachineVerifier::calcRegsRequired() {
31357d453863SRoman Divacky // First push live-in regs to predecessors' vregsRequired.
313663faed5bSDimitry Andric SmallPtrSet<const MachineBasicBlock*, 8> todo;
31375ca98fd9SDimitry Andric for (const auto &MBB : *MF) {
31387d453863SRoman Divacky BBInfo &MInfo = MBBInfoMap[&MBB];
3139cfca06d7SDimitry Andric for (const MachineBasicBlock *Pred : MBB.predecessors()) {
3140cfca06d7SDimitry Andric BBInfo &PInfo = MBBInfoMap[Pred];
31417d453863SRoman Divacky if (PInfo.addRequired(MInfo.vregsLiveIn))
3142cfca06d7SDimitry Andric todo.insert(Pred);
31437d453863SRoman Divacky }
3144b60736ecSDimitry Andric
3145b60736ecSDimitry Andric // Handle the PHI node.
3146b60736ecSDimitry Andric for (const MachineInstr &MI : MBB.phis()) {
3147b60736ecSDimitry Andric for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {
3148b60736ecSDimitry Andric // Skip those Operands which are undef regs or not regs.
3149b60736ecSDimitry Andric if (!MI.getOperand(i).isReg() || !MI.getOperand(i).readsReg())
3150b60736ecSDimitry Andric continue;
3151b60736ecSDimitry Andric
3152b60736ecSDimitry Andric // Get register and predecessor for one PHI edge.
3153b60736ecSDimitry Andric Register Reg = MI.getOperand(i).getReg();
3154b60736ecSDimitry Andric const MachineBasicBlock *Pred = MI.getOperand(i + 1).getMBB();
3155b60736ecSDimitry Andric
3156b60736ecSDimitry Andric BBInfo &PInfo = MBBInfoMap[Pred];
3157b60736ecSDimitry Andric if (PInfo.addRequired(Reg))
3158b60736ecSDimitry Andric todo.insert(Pred);
3159b60736ecSDimitry Andric }
3160b60736ecSDimitry Andric }
31617d453863SRoman Divacky }
31627d453863SRoman Divacky
31637d453863SRoman Divacky // Iteratively push vregsRequired to predecessors. This will converge to the
31647d453863SRoman Divacky // same final state regardless of DenseSet iteration order.
31657d453863SRoman Divacky while (!todo.empty()) {
31667d453863SRoman Divacky const MachineBasicBlock *MBB = *todo.begin();
31677d453863SRoman Divacky todo.erase(MBB);
31687d453863SRoman Divacky BBInfo &MInfo = MBBInfoMap[MBB];
3169cfca06d7SDimitry Andric for (const MachineBasicBlock *Pred : MBB->predecessors()) {
3170cfca06d7SDimitry Andric if (Pred == MBB)
31717d453863SRoman Divacky continue;
3172cfca06d7SDimitry Andric BBInfo &SInfo = MBBInfoMap[Pred];
31737d453863SRoman Divacky if (SInfo.addRequired(MInfo.vregsRequired))
3174cfca06d7SDimitry Andric todo.insert(Pred);
31757d453863SRoman Divacky }
31767d453863SRoman Divacky }
31777d453863SRoman Divacky }
31787d453863SRoman Divacky
3179009b1c42SEd Schouten // Check PHI instructions at the beginning of MBB. It is assumed that
3180829000e0SRoman Divacky // calcRegsPassed has been run so BBInfo::isLiveOut is valid.
checkPHIOps(const MachineBasicBlock & MBB)3181044eb2f6SDimitry Andric void MachineVerifier::checkPHIOps(const MachineBasicBlock &MBB) {
3182044eb2f6SDimitry Andric BBInfo &MInfo = MBBInfoMap[&MBB];
3183044eb2f6SDimitry Andric
318463faed5bSDimitry Andric SmallPtrSet<const MachineBasicBlock*, 8> seen;
3185044eb2f6SDimitry Andric for (const MachineInstr &Phi : MBB) {
3186044eb2f6SDimitry Andric if (!Phi.isPHI())
31875ca98fd9SDimitry Andric break;
318863faed5bSDimitry Andric seen.clear();
3189009b1c42SEd Schouten
3190044eb2f6SDimitry Andric const MachineOperand &MODef = Phi.getOperand(0);
3191044eb2f6SDimitry Andric if (!MODef.isReg() || !MODef.isDef()) {
3192044eb2f6SDimitry Andric report("Expected first PHI operand to be a register def", &MODef, 0);
3193009b1c42SEd Schouten continue;
3194044eb2f6SDimitry Andric }
3195044eb2f6SDimitry Andric if (MODef.isTied() || MODef.isImplicit() || MODef.isInternalRead() ||
3196044eb2f6SDimitry Andric MODef.isEarlyClobber() || MODef.isDebug())
3197044eb2f6SDimitry Andric report("Unexpected flag on PHI operand", &MODef, 0);
31981d5ae102SDimitry Andric Register DefReg = MODef.getReg();
3199e3b55780SDimitry Andric if (!DefReg.isVirtual())
3200044eb2f6SDimitry Andric report("Expected first PHI operand to be a virtual register", &MODef, 0);
3201044eb2f6SDimitry Andric
3202044eb2f6SDimitry Andric for (unsigned I = 1, E = Phi.getNumOperands(); I != E; I += 2) {
3203044eb2f6SDimitry Andric const MachineOperand &MO0 = Phi.getOperand(I);
3204044eb2f6SDimitry Andric if (!MO0.isReg()) {
3205044eb2f6SDimitry Andric report("Expected PHI operand to be a register", &MO0, I);
3206044eb2f6SDimitry Andric continue;
3207044eb2f6SDimitry Andric }
3208044eb2f6SDimitry Andric if (MO0.isImplicit() || MO0.isInternalRead() || MO0.isEarlyClobber() ||
3209044eb2f6SDimitry Andric MO0.isDebug() || MO0.isTied())
3210044eb2f6SDimitry Andric report("Unexpected flag on PHI operand", &MO0, I);
3211044eb2f6SDimitry Andric
3212044eb2f6SDimitry Andric const MachineOperand &MO1 = Phi.getOperand(I + 1);
3213044eb2f6SDimitry Andric if (!MO1.isMBB()) {
3214044eb2f6SDimitry Andric report("Expected PHI operand to be a basic block", &MO1, I + 1);
3215044eb2f6SDimitry Andric continue;
3216044eb2f6SDimitry Andric }
3217044eb2f6SDimitry Andric
3218044eb2f6SDimitry Andric const MachineBasicBlock &Pre = *MO1.getMBB();
3219044eb2f6SDimitry Andric if (!Pre.isSuccessor(&MBB)) {
3220044eb2f6SDimitry Andric report("PHI input is not a predecessor block", &MO1, I + 1);
3221044eb2f6SDimitry Andric continue;
3222044eb2f6SDimitry Andric }
3223044eb2f6SDimitry Andric
3224044eb2f6SDimitry Andric if (MInfo.reachable) {
3225044eb2f6SDimitry Andric seen.insert(&Pre);
3226044eb2f6SDimitry Andric BBInfo &PrInfo = MBBInfoMap[&Pre];
3227044eb2f6SDimitry Andric if (!MO0.isUndef() && PrInfo.reachable &&
3228044eb2f6SDimitry Andric !PrInfo.isLiveOut(MO0.getReg()))
3229044eb2f6SDimitry Andric report("PHI operand is not live-out from predecessor", &MO0, I);
3230044eb2f6SDimitry Andric }
3231009b1c42SEd Schouten }
3232009b1c42SEd Schouten
3233009b1c42SEd Schouten // Did we see all predecessors?
3234044eb2f6SDimitry Andric if (MInfo.reachable) {
3235044eb2f6SDimitry Andric for (MachineBasicBlock *Pred : MBB.predecessors()) {
3236044eb2f6SDimitry Andric if (!seen.count(Pred)) {
3237044eb2f6SDimitry Andric report("Missing PHI operand", &Phi);
3238044eb2f6SDimitry Andric errs() << printMBBReference(*Pred)
3239009b1c42SEd Schouten << " is a predecessor according to the CFG.\n";
3240009b1c42SEd Schouten }
3241009b1c42SEd Schouten }
3242009b1c42SEd Schouten }
3243009b1c42SEd Schouten }
3244044eb2f6SDimitry Andric }
3245009b1c42SEd Schouten
3246ac9a064cSDimitry Andric static void
verifyConvergenceControl(const MachineFunction & MF,MachineDominatorTree & DT,std::function<void (const Twine & Message)> FailureCB)3247ac9a064cSDimitry Andric verifyConvergenceControl(const MachineFunction &MF, MachineDominatorTree &DT,
3248ac9a064cSDimitry Andric std::function<void(const Twine &Message)> FailureCB) {
3249ac9a064cSDimitry Andric MachineConvergenceVerifier CV;
3250ac9a064cSDimitry Andric CV.initialize(&errs(), FailureCB, MF);
3251ac9a064cSDimitry Andric
3252ac9a064cSDimitry Andric for (const auto &MBB : MF) {
3253ac9a064cSDimitry Andric CV.visit(MBB);
3254ac9a064cSDimitry Andric for (const auto &MI : MBB.instrs())
3255ac9a064cSDimitry Andric CV.visit(MI);
3256ac9a064cSDimitry Andric }
3257ac9a064cSDimitry Andric
3258ac9a064cSDimitry Andric if (CV.sawTokens()) {
3259ac9a064cSDimitry Andric DT.recalculate(const_cast<MachineFunction &>(MF));
3260ac9a064cSDimitry Andric CV.verify(DT);
3261ac9a064cSDimitry Andric }
3262ac9a064cSDimitry Andric }
3263ac9a064cSDimitry Andric
visitMachineFunctionAfter()326459850d08SRoman Divacky void MachineVerifier::visitMachineFunctionAfter() {
3265ac9a064cSDimitry Andric auto FailureCB = [this](const Twine &Message) {
3266ac9a064cSDimitry Andric report(Message.str().c_str(), MF);
3267ac9a064cSDimitry Andric };
3268ac9a064cSDimitry Andric verifyConvergenceControl(*MF, DT, FailureCB);
3269ac9a064cSDimitry Andric
3270829000e0SRoman Divacky calcRegsPassed();
3271009b1c42SEd Schouten
3272044eb2f6SDimitry Andric for (const MachineBasicBlock &MBB : *MF)
3273044eb2f6SDimitry Andric checkPHIOps(MBB);
32747d453863SRoman Divacky
3275d39c594dSDimitry Andric // Now check liveness info if available
32767d453863SRoman Divacky calcRegsRequired();
327763faed5bSDimitry Andric
327858b69754SDimitry Andric // Check for killed virtual registers that should be live out.
32795ca98fd9SDimitry Andric for (const auto &MBB : *MF) {
32805ca98fd9SDimitry Andric BBInfo &MInfo = MBBInfoMap[&MBB];
3281b60736ecSDimitry Andric for (Register VReg : MInfo.vregsRequired)
3282cfca06d7SDimitry Andric if (MInfo.regsKilled.count(VReg)) {
32835ca98fd9SDimitry Andric report("Virtual register killed in block, but needed live out.", &MBB);
3284cfca06d7SDimitry Andric errs() << "Virtual register " << printReg(VReg)
328558b69754SDimitry Andric << " is used after the block.\n";
328658b69754SDimitry Andric }
328758b69754SDimitry Andric }
328858b69754SDimitry Andric
328958b69754SDimitry Andric if (!MF->empty()) {
329063faed5bSDimitry Andric BBInfo &MInfo = MBBInfoMap[&MF->front()];
3291b60736ecSDimitry Andric for (Register VReg : MInfo.vregsRequired) {
329201095a5dSDimitry Andric report("Virtual register defs don't dominate all uses.", MF);
3293cfca06d7SDimitry Andric report_context_vreg(VReg);
329401095a5dSDimitry Andric }
329563faed5bSDimitry Andric }
329663faed5bSDimitry Andric
3297d39c594dSDimitry Andric if (LiveVars)
32987d453863SRoman Divacky verifyLiveVariables();
3299d39c594dSDimitry Andric if (LiveInts)
3300d39c594dSDimitry Andric verifyLiveIntervals();
3301e6d15924SDimitry Andric
3302706b4fc4SDimitry Andric // Check live-in list of each MBB. If a register is live into MBB, check
3303706b4fc4SDimitry Andric // that the register is in regsLiveOut of each predecessor block. Since
3304706b4fc4SDimitry Andric // this must come from a definition in the predecesssor or its live-in
3305706b4fc4SDimitry Andric // list, this will catch a live-through case where the predecessor does not
3306706b4fc4SDimitry Andric // have the register in its live-in list. This currently only checks
3307706b4fc4SDimitry Andric // registers that have no aliases, are not allocatable and are not
3308706b4fc4SDimitry Andric // reserved, which could mean a condition code register for instance.
3309706b4fc4SDimitry Andric if (MRI->tracksLiveness())
3310706b4fc4SDimitry Andric for (const auto &MBB : *MF)
3311706b4fc4SDimitry Andric for (MachineBasicBlock::RegisterMaskPair P : MBB.liveins()) {
3312706b4fc4SDimitry Andric MCPhysReg LiveInReg = P.PhysReg;
3313706b4fc4SDimitry Andric bool hasAliases = MCRegAliasIterator(LiveInReg, TRI, false).isValid();
3314706b4fc4SDimitry Andric if (hasAliases || isAllocatable(LiveInReg) || isReserved(LiveInReg))
3315706b4fc4SDimitry Andric continue;
3316706b4fc4SDimitry Andric for (const MachineBasicBlock *Pred : MBB.predecessors()) {
3317706b4fc4SDimitry Andric BBInfo &PInfo = MBBInfoMap[Pred];
3318706b4fc4SDimitry Andric if (!PInfo.regsLiveOut.count(LiveInReg)) {
3319706b4fc4SDimitry Andric report("Live in register not found to be live out from predecessor.",
3320706b4fc4SDimitry Andric &MBB);
3321706b4fc4SDimitry Andric errs() << TRI->getName(LiveInReg)
3322706b4fc4SDimitry Andric << " not found to be live out from "
3323706b4fc4SDimitry Andric << printMBBReference(*Pred) << "\n";
3324706b4fc4SDimitry Andric }
3325706b4fc4SDimitry Andric }
3326706b4fc4SDimitry Andric }
3327706b4fc4SDimitry Andric
3328e6d15924SDimitry Andric for (auto CSInfo : MF->getCallSitesInfo())
3329e6d15924SDimitry Andric if (!CSInfo.first->isCall())
3330e6d15924SDimitry Andric report("Call site info referencing instruction that is not call", MF);
3331b60736ecSDimitry Andric
3332b60736ecSDimitry Andric // If there's debug-info, check that we don't have any duplicate value
3333b60736ecSDimitry Andric // tracking numbers.
3334b60736ecSDimitry Andric if (MF->getFunction().getSubprogram()) {
3335b60736ecSDimitry Andric DenseSet<unsigned> SeenNumbers;
33364b4fe385SDimitry Andric for (const auto &MBB : *MF) {
33374b4fe385SDimitry Andric for (const auto &MI : MBB) {
3338b60736ecSDimitry Andric if (auto Num = MI.peekDebugInstrNum()) {
3339b60736ecSDimitry Andric auto Result = SeenNumbers.insert((unsigned)Num);
3340b60736ecSDimitry Andric if (!Result.second)
3341b60736ecSDimitry Andric report("Instruction has a duplicated value tracking number", &MI);
3342b60736ecSDimitry Andric }
3343b60736ecSDimitry Andric }
3344b60736ecSDimitry Andric }
3345b60736ecSDimitry Andric }
33467d453863SRoman Divacky }
33477d453863SRoman Divacky
verifyLiveVariables()33487d453863SRoman Divacky void MachineVerifier::verifyLiveVariables() {
33497d453863SRoman Divacky assert(LiveVars && "Don't call verifyLiveVariables without LiveVars");
3350b60736ecSDimitry Andric for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
3351b60736ecSDimitry Andric Register Reg = Register::index2VirtReg(I);
33527d453863SRoman Divacky LiveVariables::VarInfo &VI = LiveVars->getVarInfo(Reg);
33535ca98fd9SDimitry Andric for (const auto &MBB : *MF) {
33545ca98fd9SDimitry Andric BBInfo &MInfo = MBBInfoMap[&MBB];
33557d453863SRoman Divacky
33567d453863SRoman Divacky // Our vregsRequired should be identical to LiveVariables' AliveBlocks
33577d453863SRoman Divacky if (MInfo.vregsRequired.count(Reg)) {
33585ca98fd9SDimitry Andric if (!VI.AliveBlocks.test(MBB.getNumber())) {
33595ca98fd9SDimitry Andric report("LiveVariables: Block missing from AliveBlocks", &MBB);
3360044eb2f6SDimitry Andric errs() << "Virtual register " << printReg(Reg)
33617d453863SRoman Divacky << " must be live through the block.\n";
33627d453863SRoman Divacky }
33637d453863SRoman Divacky } else {
33645ca98fd9SDimitry Andric if (VI.AliveBlocks.test(MBB.getNumber())) {
33655ca98fd9SDimitry Andric report("LiveVariables: Block should not be in AliveBlocks", &MBB);
3366044eb2f6SDimitry Andric errs() << "Virtual register " << printReg(Reg)
33677d453863SRoman Divacky << " is not needed live through the block.\n";
33687d453863SRoman Divacky }
33697d453863SRoman Divacky }
33707d453863SRoman Divacky }
33717d453863SRoman Divacky }
33727d453863SRoman Divacky }
33737d453863SRoman Divacky
verifyLiveIntervals()3374d39c594dSDimitry Andric void MachineVerifier::verifyLiveIntervals() {
3375d39c594dSDimitry Andric assert(LiveInts && "Don't call verifyLiveIntervals without LiveInts");
3376b60736ecSDimitry Andric for (unsigned I = 0, E = MRI->getNumVirtRegs(); I != E; ++I) {
3377b60736ecSDimitry Andric Register Reg = Register::index2VirtReg(I);
3378cf099d11SDimitry Andric
3379cf099d11SDimitry Andric // Spilling and splitting may leave unused registers around. Skip them.
338058b69754SDimitry Andric if (MRI->reg_nodbg_empty(Reg))
3381cf099d11SDimitry Andric continue;
3382cf099d11SDimitry Andric
338358b69754SDimitry Andric if (!LiveInts->hasInterval(Reg)) {
338458b69754SDimitry Andric report("Missing live interval for virtual register", MF);
3385044eb2f6SDimitry Andric errs() << printReg(Reg, TRI) << " still has defs or uses\n";
3386cf099d11SDimitry Andric continue;
338758b69754SDimitry Andric }
3388cf099d11SDimitry Andric
338958b69754SDimitry Andric const LiveInterval &LI = LiveInts->getInterval(Reg);
3390b60736ecSDimitry Andric assert(Reg == LI.reg() && "Invalid reg to interval mapping");
339158b69754SDimitry Andric verifyLiveInterval(LI);
339258b69754SDimitry Andric }
3393d39c594dSDimitry Andric
339458b69754SDimitry Andric // Verify all the cached regunit intervals.
339558b69754SDimitry Andric for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
3396f8af5cf6SDimitry Andric if (const LiveRange *LR = LiveInts->getCachedRegUnit(i))
3397f8af5cf6SDimitry Andric verifyLiveRange(*LR, i);
339858b69754SDimitry Andric }
339958b69754SDimitry Andric
verifyLiveRangeValue(const LiveRange & LR,const VNInfo * VNI,Register Reg,LaneBitmask LaneMask)3400f8af5cf6SDimitry Andric void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
3401b60736ecSDimitry Andric const VNInfo *VNI, Register Reg,
3402dd58ef01SDimitry Andric LaneBitmask LaneMask) {
340358b69754SDimitry Andric if (VNI->isUnused())
340458b69754SDimitry Andric return;
340558b69754SDimitry Andric
3406f8af5cf6SDimitry Andric const VNInfo *DefVNI = LR.getVNInfoAt(VNI->def);
3407d39c594dSDimitry Andric
3408cf099d11SDimitry Andric if (!DefVNI) {
3409dd58ef01SDimitry Andric report("Value not live at VNInfo def and not marked unused", MF);
3410dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3411dd58ef01SDimitry Andric report_context(*VNI);
341258b69754SDimitry Andric return;
3413d39c594dSDimitry Andric }
3414d39c594dSDimitry Andric
3415cf099d11SDimitry Andric if (DefVNI != VNI) {
3416dd58ef01SDimitry Andric report("Live segment at def has different VNInfo", MF);
3417dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3418dd58ef01SDimitry Andric report_context(*VNI);
341958b69754SDimitry Andric return;
3420d39c594dSDimitry Andric }
3421d39c594dSDimitry Andric
3422cf099d11SDimitry Andric const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def);
3423cf099d11SDimitry Andric if (!MBB) {
3424dd58ef01SDimitry Andric report("Invalid VNInfo definition index", MF);
3425dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3426dd58ef01SDimitry Andric report_context(*VNI);
342758b69754SDimitry Andric return;
3428cf099d11SDimitry Andric }
3429cf099d11SDimitry Andric
3430cf099d11SDimitry Andric if (VNI->isPHIDef()) {
3431cf099d11SDimitry Andric if (VNI->def != LiveInts->getMBBStartIdx(MBB)) {
3432dd58ef01SDimitry Andric report("PHIDef VNInfo is not defined at MBB start", MBB);
3433dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3434dd58ef01SDimitry Andric report_context(*VNI);
3435cf099d11SDimitry Andric }
343658b69754SDimitry Andric return;
343758b69754SDimitry Andric }
343858b69754SDimitry Andric
3439cf099d11SDimitry Andric // Non-PHI def.
3440cf099d11SDimitry Andric const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def);
3441cf099d11SDimitry Andric if (!MI) {
3442dd58ef01SDimitry Andric report("No instruction at VNInfo def index", MBB);
3443dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3444dd58ef01SDimitry Andric report_context(*VNI);
344558b69754SDimitry Andric return;
3446cf099d11SDimitry Andric }
3447cf099d11SDimitry Andric
3448f8af5cf6SDimitry Andric if (Reg != 0) {
344963faed5bSDimitry Andric bool hasDef = false;
3450cf099d11SDimitry Andric bool isEarlyClobber = false;
345101095a5dSDimitry Andric for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
345263faed5bSDimitry Andric if (!MOI->isReg() || !MOI->isDef())
345363faed5bSDimitry Andric continue;
3454e3b55780SDimitry Andric if (Reg.isVirtual()) {
3455f8af5cf6SDimitry Andric if (MOI->getReg() != Reg)
345663faed5bSDimitry Andric continue;
345763faed5bSDimitry Andric } else {
3458e3b55780SDimitry Andric if (!MOI->getReg().isPhysical() || !TRI->hasRegUnit(MOI->getReg(), Reg))
345963faed5bSDimitry Andric continue;
346063faed5bSDimitry Andric }
3461b915e9e0SDimitry Andric if (LaneMask.any() &&
3462b915e9e0SDimitry Andric (TRI->getSubRegIndexLaneMask(MOI->getSubReg()) & LaneMask).none())
346367c32a98SDimitry Andric continue;
346463faed5bSDimitry Andric hasDef = true;
346563faed5bSDimitry Andric if (MOI->isEarlyClobber())
3466cf099d11SDimitry Andric isEarlyClobber = true;
3467cf099d11SDimitry Andric }
346863faed5bSDimitry Andric
346963faed5bSDimitry Andric if (!hasDef) {
347063faed5bSDimitry Andric report("Defining instruction does not modify register", MI);
3471dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3472dd58ef01SDimitry Andric report_context(*VNI);
3473cf099d11SDimitry Andric }
3474cf099d11SDimitry Andric
3475cf099d11SDimitry Andric // Early clobber defs begin at USE slots, but other defs must begin at
3476cf099d11SDimitry Andric // DEF slots.
3477cf099d11SDimitry Andric if (isEarlyClobber) {
347863faed5bSDimitry Andric if (!VNI->def.isEarlyClobber()) {
3479dd58ef01SDimitry Andric report("Early clobber def must be at an early-clobber slot", MBB);
3480dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3481dd58ef01SDimitry Andric report_context(*VNI);
3482cf099d11SDimitry Andric }
348363faed5bSDimitry Andric } else if (!VNI->def.isRegister()) {
3484dd58ef01SDimitry Andric report("Non-PHI, non-early clobber def must be at a register slot", MBB);
3485dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3486dd58ef01SDimitry Andric report_context(*VNI);
3487cf099d11SDimitry Andric }
3488d39c594dSDimitry Andric }
3489f8af5cf6SDimitry Andric }
3490d39c594dSDimitry Andric
verifyLiveRangeSegment(const LiveRange & LR,const LiveRange::const_iterator I,Register Reg,LaneBitmask LaneMask)3491f8af5cf6SDimitry Andric void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
3492f8af5cf6SDimitry Andric const LiveRange::const_iterator I,
3493b60736ecSDimitry Andric Register Reg,
3494b60736ecSDimitry Andric LaneBitmask LaneMask) {
3495f8af5cf6SDimitry Andric const LiveRange::Segment &S = *I;
3496f8af5cf6SDimitry Andric const VNInfo *VNI = S.valno;
3497f8af5cf6SDimitry Andric assert(VNI && "Live segment has no valno");
3498d39c594dSDimitry Andric
3499f8af5cf6SDimitry Andric if (VNI->id >= LR.getNumValNums() || VNI != LR.getValNumInfo(VNI->id)) {
3500dd58ef01SDimitry Andric report("Foreign valno in live segment", MF);
3501dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3502dd58ef01SDimitry Andric report_context(S);
3503dd58ef01SDimitry Andric report_context(*VNI);
3504d39c594dSDimitry Andric }
3505d39c594dSDimitry Andric
3506cf099d11SDimitry Andric if (VNI->isUnused()) {
3507dd58ef01SDimitry Andric report("Live segment valno is marked unused", MF);
3508dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3509dd58ef01SDimitry Andric report_context(S);
3510d39c594dSDimitry Andric }
3511d39c594dSDimitry Andric
3512f8af5cf6SDimitry Andric const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(S.start);
3513cf099d11SDimitry Andric if (!MBB) {
3514dd58ef01SDimitry Andric report("Bad start of live segment, no basic block", MF);
3515dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3516dd58ef01SDimitry Andric report_context(S);
351758b69754SDimitry Andric return;
3518cf099d11SDimitry Andric }
3519cf099d11SDimitry Andric SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB);
3520f8af5cf6SDimitry Andric if (S.start != MBBStartIdx && S.start != VNI->def) {
3521dd58ef01SDimitry Andric report("Live segment must begin at MBB entry or valno def", MBB);
3522dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3523dd58ef01SDimitry Andric report_context(S);
3524cf099d11SDimitry Andric }
3525cf099d11SDimitry Andric
3526cf099d11SDimitry Andric const MachineBasicBlock *EndMBB =
3527f8af5cf6SDimitry Andric LiveInts->getMBBFromIndex(S.end.getPrevSlot());
3528cf099d11SDimitry Andric if (!EndMBB) {
3529dd58ef01SDimitry Andric report("Bad end of live segment, no basic block", MF);
3530dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3531dd58ef01SDimitry Andric report_context(S);
353258b69754SDimitry Andric return;
3533cf099d11SDimitry Andric }
353463faed5bSDimitry Andric
35357fa27ce4SDimitry Andric // Checks for non-live-out segments.
35367fa27ce4SDimitry Andric if (S.end != LiveInts->getMBBEndIdx(EndMBB)) {
353758b69754SDimitry Andric // RegUnit intervals are allowed dead phis.
3538e3b55780SDimitry Andric if (!Reg.isVirtual() && VNI->isPHIDef() && S.start == VNI->def &&
3539e3b55780SDimitry Andric S.end == VNI->def.getDeadSlot())
354058b69754SDimitry Andric return;
354163faed5bSDimitry Andric
3542cf099d11SDimitry Andric // The live segment is ending inside EndMBB
3543cf099d11SDimitry Andric const MachineInstr *MI =
3544f8af5cf6SDimitry Andric LiveInts->getInstructionFromIndex(S.end.getPrevSlot());
3545cf099d11SDimitry Andric if (!MI) {
3546dd58ef01SDimitry Andric report("Live segment doesn't end at a valid instruction", EndMBB);
3547dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3548dd58ef01SDimitry Andric report_context(S);
354958b69754SDimitry Andric return;
355063faed5bSDimitry Andric }
355163faed5bSDimitry Andric
355263faed5bSDimitry Andric // The block slot must refer to a basic block boundary.
3553f8af5cf6SDimitry Andric if (S.end.isBlock()) {
3554dd58ef01SDimitry Andric report("Live segment ends at B slot of an instruction", EndMBB);
3555dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3556dd58ef01SDimitry Andric report_context(S);
355763faed5bSDimitry Andric }
355863faed5bSDimitry Andric
3559f8af5cf6SDimitry Andric if (S.end.isDead()) {
356063faed5bSDimitry Andric // Segment ends on the dead slot.
356163faed5bSDimitry Andric // That means there must be a dead def.
3562f8af5cf6SDimitry Andric if (!SlotIndex::isSameInstr(S.start, S.end)) {
3563dd58ef01SDimitry Andric report("Live segment ending at dead slot spans instructions", EndMBB);
3564dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3565dd58ef01SDimitry Andric report_context(S);
3566cf099d11SDimitry Andric }
3567cf099d11SDimitry Andric }
3568cf099d11SDimitry Andric
3569c0981da4SDimitry Andric // After tied operands are rewritten, a live segment can only end at an
3570c0981da4SDimitry Andric // early-clobber slot if it is being redefined by an early-clobber def.
35717fa27ce4SDimitry Andric // TODO: Before tied operands are rewritten, a live segment can only end at
35727fa27ce4SDimitry Andric // an early-clobber slot if the last use is tied to an early-clobber def.
3573c0981da4SDimitry Andric if (MF->getProperties().hasProperty(
3574c0981da4SDimitry Andric MachineFunctionProperties::Property::TiedOpsRewritten) &&
3575c0981da4SDimitry Andric S.end.isEarlyClobber()) {
3576f8af5cf6SDimitry Andric if (I + 1 == LR.end() || (I + 1)->start != S.end) {
357763faed5bSDimitry Andric report("Live segment ending at early clobber slot must be "
35787fa27ce4SDimitry Andric "redefined by an EC def in the same instruction",
35797fa27ce4SDimitry Andric EndMBB);
3580dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3581dd58ef01SDimitry Andric report_context(S);
358263faed5bSDimitry Andric }
358363faed5bSDimitry Andric }
358463faed5bSDimitry Andric
358563faed5bSDimitry Andric // The following checks only apply to virtual registers. Physreg liveness
358663faed5bSDimitry Andric // is too weird to check.
3587e3b55780SDimitry Andric if (Reg.isVirtual()) {
3588f8af5cf6SDimitry Andric // A live segment can end with either a redefinition, a kill flag on a
358963faed5bSDimitry Andric // use, or a dead flag on a def.
359063faed5bSDimitry Andric bool hasRead = false;
359167c32a98SDimitry Andric bool hasSubRegDef = false;
359201095a5dSDimitry Andric bool hasDeadDef = false;
359301095a5dSDimitry Andric for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
3594f8af5cf6SDimitry Andric if (!MOI->isReg() || MOI->getReg() != Reg)
359563faed5bSDimitry Andric continue;
3596b915e9e0SDimitry Andric unsigned Sub = MOI->getSubReg();
35977fa27ce4SDimitry Andric LaneBitmask SLM =
35987fa27ce4SDimitry Andric Sub != 0 ? TRI->getSubRegIndexLaneMask(Sub) : LaneBitmask::getAll();
359901095a5dSDimitry Andric if (MOI->isDef()) {
3600b915e9e0SDimitry Andric if (Sub != 0) {
360167c32a98SDimitry Andric hasSubRegDef = true;
3602044eb2f6SDimitry Andric // An operand %0:sub0 reads %0:sub1..n. Invert the lane
3603b915e9e0SDimitry Andric // mask for subregister defs. Read-undef defs will be handled by
3604b915e9e0SDimitry Andric // readsReg below.
3605b915e9e0SDimitry Andric SLM = ~SLM;
3606b915e9e0SDimitry Andric }
360701095a5dSDimitry Andric if (MOI->isDead())
360801095a5dSDimitry Andric hasDeadDef = true;
360901095a5dSDimitry Andric }
3610b915e9e0SDimitry Andric if (LaneMask.any() && (LaneMask & SLM).none())
3611b915e9e0SDimitry Andric continue;
361263faed5bSDimitry Andric if (MOI->readsReg())
361363faed5bSDimitry Andric hasRead = true;
361463faed5bSDimitry Andric }
361501095a5dSDimitry Andric if (S.end.isDead()) {
361601095a5dSDimitry Andric // Make sure that the corresponding machine operand for a "dead" live
361701095a5dSDimitry Andric // range has the dead flag. We cannot perform this check for subregister
361801095a5dSDimitry Andric // liveranges as partially dead values are allowed.
3619b915e9e0SDimitry Andric if (LaneMask.none() && !hasDeadDef) {
36207fa27ce4SDimitry Andric report(
36217fa27ce4SDimitry Andric "Instruction ending live segment on dead slot has no dead flag",
362201095a5dSDimitry Andric MI);
362301095a5dSDimitry Andric report_context(LR, Reg, LaneMask);
362401095a5dSDimitry Andric report_context(S);
362501095a5dSDimitry Andric }
362601095a5dSDimitry Andric } else {
362763faed5bSDimitry Andric if (!hasRead) {
362867c32a98SDimitry Andric // When tracking subregister liveness, the main range must start new
362967c32a98SDimitry Andric // values on partial register writes, even if there is no read.
3630b915e9e0SDimitry Andric if (!MRI->shouldTrackSubRegLiveness(Reg) || LaneMask.any() ||
36315a5ac124SDimitry Andric !hasSubRegDef) {
363267c32a98SDimitry Andric report("Instruction ending live segment doesn't read the register",
363367c32a98SDimitry Andric MI);
3634dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3635dd58ef01SDimitry Andric report_context(S);
3636cf099d11SDimitry Andric }
3637cf099d11SDimitry Andric }
3638cf099d11SDimitry Andric }
363967c32a98SDimitry Andric }
36407fa27ce4SDimitry Andric }
3641cf099d11SDimitry Andric
3642cf099d11SDimitry Andric // Now check all the basic blocks in this live segment.
3643dd58ef01SDimitry Andric MachineFunction::const_iterator MFI = MBB->getIterator();
3644f8af5cf6SDimitry Andric // Is this live segment the beginning of a non-PHIDef VN?
3645f8af5cf6SDimitry Andric if (S.start == VNI->def && !VNI->isPHIDef()) {
3646cf099d11SDimitry Andric // Not live-in to any blocks.
3647cf099d11SDimitry Andric if (MBB == EndMBB)
364858b69754SDimitry Andric return;
3649cf099d11SDimitry Andric // Skip this block.
3650cf099d11SDimitry Andric ++MFI;
3651cf099d11SDimitry Andric }
3652d8e91e46SDimitry Andric
3653d8e91e46SDimitry Andric SmallVector<SlotIndex, 4> Undefs;
3654d8e91e46SDimitry Andric if (LaneMask.any()) {
3655d8e91e46SDimitry Andric LiveInterval &OwnerLI = LiveInts->getInterval(Reg);
3656d8e91e46SDimitry Andric OwnerLI.computeSubRangeUndefs(Undefs, LaneMask, *MRI, *Indexes);
3657d8e91e46SDimitry Andric }
3658d8e91e46SDimitry Andric
3659044eb2f6SDimitry Andric while (true) {
3660dd58ef01SDimitry Andric assert(LiveInts->isLiveInToMBB(LR, &*MFI));
3661cf099d11SDimitry Andric // We don't know how to track physregs into a landing pad.
3662e3b55780SDimitry Andric if (!Reg.isVirtual() && MFI->isEHPad()) {
3663cf099d11SDimitry Andric if (&*MFI == EndMBB)
3664cf099d11SDimitry Andric break;
3665cf099d11SDimitry Andric ++MFI;
3666cf099d11SDimitry Andric continue;
3667cf099d11SDimitry Andric }
366858b69754SDimitry Andric
366958b69754SDimitry Andric // Is VNI a PHI-def in the current block?
367058b69754SDimitry Andric bool IsPHI = VNI->isPHIDef() &&
3671dd58ef01SDimitry Andric VNI->def == LiveInts->getMBBStartIdx(&*MFI);
367258b69754SDimitry Andric
3673cf099d11SDimitry Andric // Check that VNI is live-out of all predecessors.
3674cfca06d7SDimitry Andric for (const MachineBasicBlock *Pred : MFI->predecessors()) {
3675cfca06d7SDimitry Andric SlotIndex PEnd = LiveInts->getMBBEndIdx(Pred);
3676344a3780SDimitry Andric // Predecessor of landing pad live-out on last call.
3677344a3780SDimitry Andric if (MFI->isEHPad()) {
3678f65dcba8SDimitry Andric for (const MachineInstr &MI : llvm::reverse(*Pred)) {
3679f65dcba8SDimitry Andric if (MI.isCall()) {
3680f65dcba8SDimitry Andric PEnd = Indexes->getInstructionIndex(MI).getBoundaryIndex();
3681344a3780SDimitry Andric break;
3682344a3780SDimitry Andric }
3683344a3780SDimitry Andric }
3684344a3780SDimitry Andric }
3685f8af5cf6SDimitry Andric const VNInfo *PVNI = LR.getVNInfoBefore(PEnd);
3686cf099d11SDimitry Andric
36877ab83427SDimitry Andric // All predecessors must have a live-out value. However for a phi
36887ab83427SDimitry Andric // instruction with subregister intervals
36897ab83427SDimitry Andric // only one of the subregisters (not necessarily the current one) needs to
36907ab83427SDimitry Andric // be defined.
36917ab83427SDimitry Andric if (!PVNI && (LaneMask.none() || !IsPHI)) {
3692cfca06d7SDimitry Andric if (LiveRangeCalc::isJointlyDominated(Pred, Undefs, *Indexes))
3693d8e91e46SDimitry Andric continue;
3694cfca06d7SDimitry Andric report("Register not marked live out of predecessor", Pred);
3695dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3696dd58ef01SDimitry Andric report_context(*VNI);
3697044eb2f6SDimitry Andric errs() << " live into " << printMBBReference(*MFI) << '@'
3698044eb2f6SDimitry Andric << LiveInts->getMBBStartIdx(&*MFI) << ", not live before "
369958b69754SDimitry Andric << PEnd << '\n';
3700cf099d11SDimitry Andric continue;
3701cf099d11SDimitry Andric }
3702cf099d11SDimitry Andric
370358b69754SDimitry Andric // Only PHI-defs can take different predecessor values.
370458b69754SDimitry Andric if (!IsPHI && PVNI != VNI) {
3705cfca06d7SDimitry Andric report("Different value live out of predecessor", Pred);
3706dd58ef01SDimitry Andric report_context(LR, Reg, LaneMask);
3707044eb2f6SDimitry Andric errs() << "Valno #" << PVNI->id << " live out of "
3708cfca06d7SDimitry Andric << printMBBReference(*Pred) << '@' << PEnd << "\nValno #"
3709044eb2f6SDimitry Andric << VNI->id << " live into " << printMBBReference(*MFI) << '@'
3710dd58ef01SDimitry Andric << LiveInts->getMBBStartIdx(&*MFI) << '\n';
3711cf099d11SDimitry Andric }
3712cf099d11SDimitry Andric }
3713cf099d11SDimitry Andric if (&*MFI == EndMBB)
3714cf099d11SDimitry Andric break;
3715cf099d11SDimitry Andric ++MFI;
3716cf099d11SDimitry Andric }
3717cf099d11SDimitry Andric }
3718cf099d11SDimitry Andric
verifyLiveRange(const LiveRange & LR,Register Reg,LaneBitmask LaneMask)3719b60736ecSDimitry Andric void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
3720dd58ef01SDimitry Andric LaneBitmask LaneMask) {
372167c32a98SDimitry Andric for (const VNInfo *VNI : LR.valnos)
372267c32a98SDimitry Andric verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
372358b69754SDimitry Andric
3724f8af5cf6SDimitry Andric for (LiveRange::const_iterator I = LR.begin(), E = LR.end(); I != E; ++I)
372567c32a98SDimitry Andric verifyLiveRangeSegment(LR, I, Reg, LaneMask);
3726f8af5cf6SDimitry Andric }
3727f8af5cf6SDimitry Andric
verifyLiveInterval(const LiveInterval & LI)3728f8af5cf6SDimitry Andric void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
3729b60736ecSDimitry Andric Register Reg = LI.reg();
3730e3b55780SDimitry Andric assert(Reg.isVirtual());
37315a5ac124SDimitry Andric verifyLiveRange(LI, Reg);
37325a5ac124SDimitry Andric
3733b1c73532SDimitry Andric if (LI.hasSubRanges()) {
3734b915e9e0SDimitry Andric LaneBitmask Mask;
3735dd58ef01SDimitry Andric LaneBitmask MaxMask = MRI->getMaxLaneMaskForVReg(Reg);
373667c32a98SDimitry Andric for (const LiveInterval::SubRange &SR : LI.subranges()) {
3737b915e9e0SDimitry Andric if ((Mask & SR.LaneMask).any()) {
3738dd58ef01SDimitry Andric report("Lane masks of sub ranges overlap in live interval", MF);
3739dd58ef01SDimitry Andric report_context(LI);
3740dd58ef01SDimitry Andric }
3741b915e9e0SDimitry Andric if ((SR.LaneMask & ~MaxMask).any()) {
3742dd58ef01SDimitry Andric report("Subrange lanemask is invalid", MF);
3743dd58ef01SDimitry Andric report_context(LI);
3744dd58ef01SDimitry Andric }
3745dd58ef01SDimitry Andric if (SR.empty()) {
3746dd58ef01SDimitry Andric report("Subrange must not be empty", MF);
3747b60736ecSDimitry Andric report_context(SR, LI.reg(), SR.LaneMask);
3748dd58ef01SDimitry Andric }
374967c32a98SDimitry Andric Mask |= SR.LaneMask;
3750b60736ecSDimitry Andric verifyLiveRange(SR, LI.reg(), SR.LaneMask);
3751dd58ef01SDimitry Andric if (!LI.covers(SR)) {
3752dd58ef01SDimitry Andric report("A Subrange is not covered by the main range", MF);
3753dd58ef01SDimitry Andric report_context(LI);
3754dd58ef01SDimitry Andric }
375567c32a98SDimitry Andric }
3756b1c73532SDimitry Andric }
375767c32a98SDimitry Andric
3758cf099d11SDimitry Andric // Check the LI only has one connected component.
3759cf099d11SDimitry Andric ConnectedVNInfoEqClasses ConEQ(*LiveInts);
3760050e163aSDimitry Andric unsigned NumComp = ConEQ.Classify(LI);
3761cf099d11SDimitry Andric if (NumComp > 1) {
3762dd58ef01SDimitry Andric report("Multiple connected components in live interval", MF);
3763dd58ef01SDimitry Andric report_context(LI);
3764cf099d11SDimitry Andric for (unsigned comp = 0; comp != NumComp; ++comp) {
37655a5ac124SDimitry Andric errs() << comp << ": valnos";
3766cfca06d7SDimitry Andric for (const VNInfo *I : LI.valnos)
3767cfca06d7SDimitry Andric if (comp == ConEQ.getEqClass(I))
3768cfca06d7SDimitry Andric errs() << ' ' << I->id;
37695a5ac124SDimitry Andric errs() << '\n';
3770cf099d11SDimitry Andric }
3771d39c594dSDimitry Andric }
3772d39c594dSDimitry Andric }
3773f8af5cf6SDimitry Andric
3774f8af5cf6SDimitry Andric namespace {
3775044eb2f6SDimitry Andric
3776f8af5cf6SDimitry Andric // FrameSetup and FrameDestroy can have zero adjustment, so using a single
3777f8af5cf6SDimitry Andric // integer, we can't tell whether it is a FrameSetup or FrameDestroy if the
3778f8af5cf6SDimitry Andric // value is zero.
3779f8af5cf6SDimitry Andric // We use a bool plus an integer to capture the stack state.
3780f8af5cf6SDimitry Andric struct StackStateOfBB {
3781044eb2f6SDimitry Andric StackStateOfBB() = default;
StackStateOfBB__anon3a9898fa0711::StackStateOfBB3782f8af5cf6SDimitry Andric StackStateOfBB(int EntryVal, int ExitVal, bool EntrySetup, bool ExitSetup) :
3783f8af5cf6SDimitry Andric EntryValue(EntryVal), ExitValue(ExitVal), EntryIsSetup(EntrySetup),
3784f8af5cf6SDimitry Andric ExitIsSetup(ExitSetup) {}
3785044eb2f6SDimitry Andric
3786f8af5cf6SDimitry Andric // Can be negative, which means we are setting up a frame.
3787044eb2f6SDimitry Andric int EntryValue = 0;
3788044eb2f6SDimitry Andric int ExitValue = 0;
3789044eb2f6SDimitry Andric bool EntryIsSetup = false;
3790044eb2f6SDimitry Andric bool ExitIsSetup = false;
3791f8af5cf6SDimitry Andric };
3792044eb2f6SDimitry Andric
3793044eb2f6SDimitry Andric } // end anonymous namespace
3794f8af5cf6SDimitry Andric
3795f8af5cf6SDimitry Andric /// Make sure on every path through the CFG, a FrameSetup <n> is always followed
3796f8af5cf6SDimitry Andric /// by a FrameDestroy <n>, stack adjustments are identical on all
3797f8af5cf6SDimitry Andric /// CFG edges to a merge point, and frame is destroyed at end of a return block.
verifyStackFrame()3798f8af5cf6SDimitry Andric void MachineVerifier::verifyStackFrame() {
37995a5ac124SDimitry Andric unsigned FrameSetupOpcode = TII->getCallFrameSetupOpcode();
38005a5ac124SDimitry Andric unsigned FrameDestroyOpcode = TII->getCallFrameDestroyOpcode();
3801d99dafe2SDimitry Andric if (FrameSetupOpcode == ~0u && FrameDestroyOpcode == ~0u)
3802d99dafe2SDimitry Andric return;
3803f8af5cf6SDimitry Andric
3804f8af5cf6SDimitry Andric SmallVector<StackStateOfBB, 8> SPState;
3805f8af5cf6SDimitry Andric SPState.resize(MF->getNumBlockIDs());
3806b915e9e0SDimitry Andric df_iterator_default_set<const MachineBasicBlock*> Reachable;
3807f8af5cf6SDimitry Andric
3808f8af5cf6SDimitry Andric // Visit the MBBs in DFS order.
3809f8af5cf6SDimitry Andric for (df_ext_iterator<const MachineFunction *,
3810b915e9e0SDimitry Andric df_iterator_default_set<const MachineBasicBlock *>>
3811f8af5cf6SDimitry Andric DFI = df_ext_begin(MF, Reachable), DFE = df_ext_end(MF, Reachable);
3812f8af5cf6SDimitry Andric DFI != DFE; ++DFI) {
3813f8af5cf6SDimitry Andric const MachineBasicBlock *MBB = *DFI;
3814f8af5cf6SDimitry Andric
3815f8af5cf6SDimitry Andric StackStateOfBB BBState;
3816f8af5cf6SDimitry Andric // Check the exit state of the DFS stack predecessor.
3817f8af5cf6SDimitry Andric if (DFI.getPathLength() >= 2) {
3818f8af5cf6SDimitry Andric const MachineBasicBlock *StackPred = DFI.getPath(DFI.getPathLength() - 2);
3819f8af5cf6SDimitry Andric assert(Reachable.count(StackPred) &&
3820f8af5cf6SDimitry Andric "DFS stack predecessor is already visited.\n");
3821f8af5cf6SDimitry Andric BBState.EntryValue = SPState[StackPred->getNumber()].ExitValue;
3822f8af5cf6SDimitry Andric BBState.EntryIsSetup = SPState[StackPred->getNumber()].ExitIsSetup;
3823f8af5cf6SDimitry Andric BBState.ExitValue = BBState.EntryValue;
3824f8af5cf6SDimitry Andric BBState.ExitIsSetup = BBState.EntryIsSetup;
3825f8af5cf6SDimitry Andric }
3826f8af5cf6SDimitry Andric
3827b1c73532SDimitry Andric if ((int)MBB->getCallFrameSize() != -BBState.EntryValue) {
3828b1c73532SDimitry Andric report("Call frame size on entry does not match value computed from "
3829b1c73532SDimitry Andric "predecessor",
3830b1c73532SDimitry Andric MBB);
3831b1c73532SDimitry Andric errs() << "Call frame size on entry " << MBB->getCallFrameSize()
3832b1c73532SDimitry Andric << " does not match value computed from predecessor "
3833b1c73532SDimitry Andric << -BBState.EntryValue << '\n';
3834b1c73532SDimitry Andric }
3835b1c73532SDimitry Andric
3836f8af5cf6SDimitry Andric // Update stack state by checking contents of MBB.
38375ca98fd9SDimitry Andric for (const auto &I : *MBB) {
38385ca98fd9SDimitry Andric if (I.getOpcode() == FrameSetupOpcode) {
3839f8af5cf6SDimitry Andric if (BBState.ExitIsSetup)
38405ca98fd9SDimitry Andric report("FrameSetup is after another FrameSetup", &I);
3841ac9a064cSDimitry Andric if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack())
3842ac9a064cSDimitry Andric report("AdjustsStack not set in presence of a frame pseudo "
3843ac9a064cSDimitry Andric "instruction.", &I);
38446b3f41edSDimitry Andric BBState.ExitValue -= TII->getFrameTotalSize(I);
3845f8af5cf6SDimitry Andric BBState.ExitIsSetup = true;
3846f8af5cf6SDimitry Andric }
3847f8af5cf6SDimitry Andric
38485ca98fd9SDimitry Andric if (I.getOpcode() == FrameDestroyOpcode) {
38496b3f41edSDimitry Andric int Size = TII->getFrameTotalSize(I);
3850f8af5cf6SDimitry Andric if (!BBState.ExitIsSetup)
38515ca98fd9SDimitry Andric report("FrameDestroy is not after a FrameSetup", &I);
3852f8af5cf6SDimitry Andric int AbsSPAdj = BBState.ExitValue < 0 ? -BBState.ExitValue :
3853f8af5cf6SDimitry Andric BBState.ExitValue;
3854f8af5cf6SDimitry Andric if (BBState.ExitIsSetup && AbsSPAdj != Size) {
38555ca98fd9SDimitry Andric report("FrameDestroy <n> is after FrameSetup <m>", &I);
38565a5ac124SDimitry Andric errs() << "FrameDestroy <" << Size << "> is after FrameSetup <"
3857f8af5cf6SDimitry Andric << AbsSPAdj << ">.\n";
3858f8af5cf6SDimitry Andric }
3859ac9a064cSDimitry Andric if (!MRI->isSSA() && !MF->getFrameInfo().adjustsStack())
3860ac9a064cSDimitry Andric report("AdjustsStack not set in presence of a frame pseudo "
3861ac9a064cSDimitry Andric "instruction.", &I);
3862f8af5cf6SDimitry Andric BBState.ExitValue += Size;
3863f8af5cf6SDimitry Andric BBState.ExitIsSetup = false;
3864f8af5cf6SDimitry Andric }
3865f8af5cf6SDimitry Andric }
3866f8af5cf6SDimitry Andric SPState[MBB->getNumber()] = BBState;
3867f8af5cf6SDimitry Andric
3868f8af5cf6SDimitry Andric // Make sure the exit state of any predecessor is consistent with the entry
3869f8af5cf6SDimitry Andric // state.
3870cfca06d7SDimitry Andric for (const MachineBasicBlock *Pred : MBB->predecessors()) {
3871cfca06d7SDimitry Andric if (Reachable.count(Pred) &&
3872cfca06d7SDimitry Andric (SPState[Pred->getNumber()].ExitValue != BBState.EntryValue ||
3873cfca06d7SDimitry Andric SPState[Pred->getNumber()].ExitIsSetup != BBState.EntryIsSetup)) {
3874f8af5cf6SDimitry Andric report("The exit stack state of a predecessor is inconsistent.", MBB);
3875cfca06d7SDimitry Andric errs() << "Predecessor " << printMBBReference(*Pred)
3876cfca06d7SDimitry Andric << " has exit state (" << SPState[Pred->getNumber()].ExitValue
3877cfca06d7SDimitry Andric << ", " << SPState[Pred->getNumber()].ExitIsSetup << "), while "
3878044eb2f6SDimitry Andric << printMBBReference(*MBB) << " has entry state ("
3879f8af5cf6SDimitry Andric << BBState.EntryValue << ", " << BBState.EntryIsSetup << ").\n";
3880f8af5cf6SDimitry Andric }
3881f8af5cf6SDimitry Andric }
3882f8af5cf6SDimitry Andric
3883f8af5cf6SDimitry Andric // Make sure the entry state of any successor is consistent with the exit
3884f8af5cf6SDimitry Andric // state.
3885cfca06d7SDimitry Andric for (const MachineBasicBlock *Succ : MBB->successors()) {
3886cfca06d7SDimitry Andric if (Reachable.count(Succ) &&
3887cfca06d7SDimitry Andric (SPState[Succ->getNumber()].EntryValue != BBState.ExitValue ||
3888cfca06d7SDimitry Andric SPState[Succ->getNumber()].EntryIsSetup != BBState.ExitIsSetup)) {
3889f8af5cf6SDimitry Andric report("The entry stack state of a successor is inconsistent.", MBB);
3890cfca06d7SDimitry Andric errs() << "Successor " << printMBBReference(*Succ)
3891cfca06d7SDimitry Andric << " has entry state (" << SPState[Succ->getNumber()].EntryValue
3892cfca06d7SDimitry Andric << ", " << SPState[Succ->getNumber()].EntryIsSetup << "), while "
3893044eb2f6SDimitry Andric << printMBBReference(*MBB) << " has exit state ("
3894f8af5cf6SDimitry Andric << BBState.ExitValue << ", " << BBState.ExitIsSetup << ").\n";
3895f8af5cf6SDimitry Andric }
3896f8af5cf6SDimitry Andric }
3897f8af5cf6SDimitry Andric
3898f8af5cf6SDimitry Andric // Make sure a basic block with return ends with zero stack adjustment.
3899f8af5cf6SDimitry Andric if (!MBB->empty() && MBB->back().isReturn()) {
3900f8af5cf6SDimitry Andric if (BBState.ExitIsSetup)
3901f8af5cf6SDimitry Andric report("A return block ends with a FrameSetup.", MBB);
3902f8af5cf6SDimitry Andric if (BBState.ExitValue)
3903f8af5cf6SDimitry Andric report("A return block ends with a nonzero stack adjustment.", MBB);
3904f8af5cf6SDimitry Andric }
3905f8af5cf6SDimitry Andric }
3906f8af5cf6SDimitry Andric }
3907