[PATCH] D45156: [MachineVerifier] Verify the RegUsageInfo collected for the current function.

Jonas Paulsson via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 2 02:28:57 PDT 2018


jonpa created this revision.
jonpa added a reviewer: qcolombet.
Herald added a subscriber: tpr.

https://bugs.llvm.org/show_bug.cgi?id=36587 discovered a set of used (preserved) pregs in function that was corrupt which led to wrong code.

This patch adds a check in the MachineVerifier that makes sure that any registers defined by any instruction in the current function which are call-preserved have all their aliases marked as used in function in the set produced by RegUsageInfoCollector.

As it is now no verification will be done if CallPreservedMask is nullptr (this happens with a lot of AMDGPU tests).

This test fails now: LLVM :: CodeGen/AMDGPU/function-returns.ll

The test in 36587 fails like:

`# End machine code for function fn2.

  - Bad machine code: Defined register (alias) not in RegUsageInfo: R0H ***
- function:    fn2
- basic block: %bb.1  (0x50f3540)
- instruction: renamable $r0d = LGHI 0

LLVM ERROR: Found 1 machine code errors.`


https://reviews.llvm.org/D45156

Files:
  lib/CodeGen/MachineVerifier.cpp


Index: lib/CodeGen/MachineVerifier.cpp
===================================================================
--- lib/CodeGen/MachineVerifier.cpp
+++ lib/CodeGen/MachineVerifier.cpp
@@ -49,6 +49,7 @@
 #include "llvm/CodeGen/MachineOperand.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/RegisterUsageInfo.h"
 #include "llvm/CodeGen/SlotIndexes.h"
 #include "llvm/CodeGen/StackMaps.h"
 #include "llvm/CodeGen/TargetInstrInfo.h"
@@ -95,6 +96,7 @@
     const TargetInstrInfo *TII;
     const TargetRegisterInfo *TRI;
     const MachineRegisterInfo *MRI;
+    PhysicalRegisterUsageInfo *PRUI;
 
     unsigned foundErrors;
 
@@ -282,6 +284,7 @@
 
     void verifySlotIndexes() const;
     void verifyProperties(const MachineFunction &MF);
+    void verifyUsedPhysRegs(const MachineFunction &MF);
   };
 
   struct MachineVerifierPass : public MachineFunctionPass {
@@ -350,6 +353,40 @@
     report("Function has NoVRegs property but there are VReg operands", &MF);
 }
 
+static bool regIsInSet(const uint32_t *RegMask, unsigned PhysReg) {
+  return !MachineOperand::clobbersPhysReg(RegMask, PhysReg);
+}
+
+void MachineVerifier::verifyUsedPhysRegs(const MachineFunction &MF) {
+  // PhysicalRegisterUsageInfo becomes available with interprocedural
+  // register allocation.
+  if (!PRUI)
+    return;
+  const Function &F = MF.getFunction();
+  const auto *PreservedRegs = PRUI->getRegUsageInfo(&F);
+  if (!PreservedRegs)
+    return;
+  const uint32_t *CallPreservedMask =
+    TRI->getCallPreservedMask(MF, F.getCallingConv());
+  if (!CallPreservedMask)
+    return;
+
+  for (unsigned PReg = 1, PRegE = TRI->getNumRegs(); PReg < PRegE; ++PReg) {
+    // Any register defined by an instruction that is not preserved across a
+    // call according to the calling convention should result in all aliases
+    // excluded from the function mask of preserved registers.
+    if (MRI->def_empty(PReg) || regIsInSet(CallPreservedMask, PReg))
+      continue;
+    for (MCRegAliasIterator AI(PReg, TRI, true); AI.isValid(); ++AI)
+      if (regIsInSet(&(*PreservedRegs)[0], *AI)) {
+        std::string Msg = "Defined register (alias) not in RegUsageInfo: "
+          + std::string(TRI->getName(*AI));
+        const MachineOperand &DefMO = *MRI->def_begin(PReg);
+        report(Msg.c_str(), DefMO.getParent());
+      }
+  }
+}
+
 unsigned MachineVerifier::verify(MachineFunction &MF) {
   foundErrors = 0;
 
@@ -372,6 +409,7 @@
   LiveInts = nullptr;
   LiveStks = nullptr;
   Indexes = nullptr;
+  PRUI = nullptr;
   if (PASS) {
     LiveInts = PASS->getAnalysisIfAvailable<LiveIntervals>();
     // We don't want to verify LiveVariables if LiveIntervals is available.
@@ -379,12 +417,15 @@
       LiveVars = PASS->getAnalysisIfAvailable<LiveVariables>();
     LiveStks = PASS->getAnalysisIfAvailable<LiveStacks>();
     Indexes = PASS->getAnalysisIfAvailable<SlotIndexes>();
+    PRUI = PASS->getAnalysisIfAvailable<PhysicalRegisterUsageInfo>();
   }
 
   verifySlotIndexes();
 
   verifyProperties(MF);
 
+  verifyUsedPhysRegs(MF);
+
   visitMachineFunctionBefore();
   for (MachineFunction::const_iterator MFI = MF.begin(), MFE = MF.end();
        MFI!=MFE; ++MFI) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45156.140610.patch
Type: text/x-patch
Size: 3237 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180402/6a772954/attachment.bin>


More information about the llvm-commits mailing list