[llvm] [Target] Add target-independent TargetVerifier dispatcher (PR #205703)
Matt Arsenault via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 04:18:23 PDT 2026
================
@@ -0,0 +1,82 @@
+//===-- TargetVerifier.cpp - Target-dependent IR Verifier ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the target-independent dispatcher for target-dependent
+// IR verification. See llvm/Target/TargetVerifier.h for the design.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Target/TargetVerifier.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+// The registry maps Triple::ArchType (stored as unsigned, since there is no
+// DenseMapInfo for the enum) to the factory that builds that target's
+// TargetVerify. It is populated by backends from LLVMInitialize<T>Target().
+static DenseMap<unsigned, TargetVerifyFactory> &getTargetVerifyRegistry() {
+ static DenseMap<unsigned, TargetVerifyFactory> Registry;
+ return Registry;
+}
+
+void llvm::registerTargetVerify(Triple::ArchType Arch,
+ TargetVerifyFactory Factory) {
+ getTargetVerifyRegistry()[static_cast<unsigned>(Arch)] = Factory;
+}
+
+const TargetVerifyFactory *llvm::getTargetVerify(Triple::ArchType Arch) {
+ DenseMap<unsigned, TargetVerifyFactory> &Registry = getTargetVerifyRegistry();
+ auto It = Registry.find(static_cast<unsigned>(Arch));
+ if (It == Registry.end())
+ return nullptr;
+ return &It->second;
+}
+
+PreservedAnalyses TargetVerifierPass::run(Module &M, ModuleAnalysisManager &AM) {
+ // Use the module triple to decide which target-dependent verification to run.
+ // If the target did not register a verifier, there is nothing target-specific
+ // to do, so skip everything (including the generic verifier) and stay a no-op.
+ const TargetVerifyFactory *Factory =
+ getTargetVerify(M.getTargetTriple().getArch());
+ if (!Factory)
+ return PreservedAnalyses::all();
+
+ bool Broken = false;
+
+ // (1) Run the generic IR verifier. After the VerifierAMDGPU split, the
+ // generic verifier dispatches to each target's IR-level checks (e.g. the
+ // verifyAMDGPU* routines in VerifierAMDGPU.cpp for AMDGPU modules), so this
+ // is how the target's "<Target>Verifier" runs.
+ Broken |= verifyModule(M, &errs());
+
+ // (2) Run the target's subtarget/feature-dependent verifier (TargetVerify).
+ if (std::unique_ptr<TargetVerify> TV{(*Factory)(M)}) {
+ for (Function &F : M) {
+ if (F.isDeclaration())
+ continue;
+ if (!TV->run(F))
+ Broken = true;
+ }
+ TV->MessagesStr.flush();
+ if (!TV->Messages.empty())
+ errs() << TV->Messages;
+ }
+
+ if (Broken) {
+ if (FatalErrors)
+ report_fatal_error("broken module found, compilation aborted!");
----------------
arsenm wrote:
No new uses of report_fatal_error
https://github.com/llvm/llvm-project/pull/205703
More information about the llvm-commits
mailing list