Index: llvm/examples/IRTransforms/CMakeLists.txt
===================================================================
--- llvm/examples/IRTransforms/CMakeLists.txt
+++ llvm/examples/IRTransforms/CMakeLists.txt
@@ -1,15 +1,19 @@
-set(LLVM_LINK_COMPONENTS
-  Analysis
-  Core
-  Support
-  )
+if(LLVM_EXAMPLEIRTRANSFORMS_LINK_INTO_TOOLS)
+    message(WARNING "Setting LLVM_EXAMPLEIRTRANSFORMS_LINK_INTO_TOOLS=ON only makes sense for testing purpose")
+endif()
 
-add_llvm_example_library(ExampleIRTransforms
-  InitializePasses.cpp
-  SimplifyCFG.cpp
+# The plugin expects to not link against the Support and Core libraries,
+# but expects them to exist in the process loading the plugin. This doesn't
+# work with DLLs on Windows (where a shared library can't have undefined
+# references), so just skip this example on Windows.
+if (NOT WIN32)
+  add_llvm_pass_plugin(ExampleIRTransforms
+    SimplifyCFG.cpp
+    DEPENDS
+    intrinsics_gen
+    BUILDTREE_ONLY
+    )
 
-  ADDITIONAL_HEADER_DIRS
-
-  DEPENDS
-  intrinsics_gen
-  )
+  install(TARGETS ${name} RUNTIME DESTINATION "${LLVM_EXAMPLES_INSTALL_DIR}")
+  set_target_properties(${name} PROPERTIES FOLDER "Examples")
+endif()
Index: llvm/examples/IRTransforms/InitializePasses.h
===================================================================
--- llvm/examples/IRTransforms/InitializePasses.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//===- InitializePasses.h - -------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXAMPLES_IRTRANSFORMS_INITIALIZEPASSES__H
-#define LLVM_EXAMPLES_IRTRANSFORMS_INITIALIZEPASSES__H
-
-#include "llvm/IR/PassManager.h"
-#include "llvm/PassRegistry.h"
-
-namespace llvm {
-
-void initializeExampleIRTransforms(PassRegistry &Registry);
-void initializeSimplifyCFGLegacyPassPass(PassRegistry &Registry);
-
-} // end namespace llvm
-
-#endif
Index: llvm/examples/IRTransforms/InitializePasses.cpp
===================================================================
--- llvm/examples/IRTransforms/InitializePasses.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//===-- InitializePasses.cpp ----------------------------------------------===//
-//
-// 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 implements the initialization hook for the example
-// transforms.
-//
-//===----------------------------------------------------------------------===//
-
-#include "InitializePasses.h"
-#include "llvm/PassRegistry.h"
-
-using namespace llvm;
-
-void initializeExampleIRTransforms(PassRegistry &Registry) {
-  initializeSimplifyCFGLegacyPassPass(Registry);
-}
Index: llvm/examples/IRTransforms/SimplifyCFG.h
===================================================================
--- llvm/examples/IRTransforms/SimplifyCFG.h
+++ /dev/null
@@ -1,24 +0,0 @@
-//===- SimplifyCFG.h - Tutorial SimplifyCFG ---------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_EXAMPLES_IRTRANSFORMS_SIMPLIFYCFG__H
-#define LLVM_EXAMPLES_IRTRANSFORMS_SIMPLIFYCFG__H
-
-#include "llvm/Pass.h"
-#include "llvm/PassRegistry.h"
-
-namespace llvm {
-
-FunctionPass *createSimplifyCFGPass();
-
-void initializeSimplifyCFGLegacyPassPass(PassRegistry &);
-
-} // end namespace llvm
-
-#endif // LLVM_EXAMPLES_IRTRANSFORMS_SIMPLIFYCFG__H
Index: llvm/examples/IRTransforms/SimplifyCFG.cpp
===================================================================
--- llvm/examples/IRTransforms/SimplifyCFG.cpp
+++ llvm/examples/IRTransforms/SimplifyCFG.cpp
@@ -27,20 +27,18 @@
 //     predecessor, if that block has a single successor.
 //
 // TODOs
-//  * Hook up pass to the new pass manager.
 //  * Preserve LoopInfo.
 //  * Add fixed point iteration to delete all dead blocks
 //  * Add implementation using reachability to discover dead blocks.
 //===----------------------------------------------------------------------===//
 
-#include "SimplifyCFG.h"
-#include "InitializePasses.h"
 #include "llvm/Analysis/DomTreeUpdater.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/PassManager.h"
 #include "llvm/IR/PatternMatch.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassPlugin.h"
 #include "llvm/Support/CommandLine.h"
 
 using namespace llvm;
@@ -369,46 +367,48 @@
 }
 
 namespace {
-struct SimplifyCFGLegacyPass : public FunctionPass {
-  static char ID;
-  SimplifyCFGLegacyPass() : FunctionPass(ID) {
-    initializeSimplifyCFGLegacyPassPass(*PassRegistry::getPassRegistry());
-  }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.addRequired<DominatorTreeWrapperPass>();
-    // Version 1 of the implementation does not preserve the dominator tree.
-    if (Version != V1)
-      AU.addPreserved<DominatorTreeWrapperPass>();
-
-    FunctionPass::getAnalysisUsage(AU);
-  }
-
-  bool runOnFunction(Function &F) override {
-    if (skipFunction(F))
-      return false;
-
+struct SimplifyCFGPass : public PassInfoMixin<SimplifyCFGPass> {
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM) {
     switch (Version) {
     case V1:
-      return doSimplify_v1(F);
+      doSimplify_v1(F);
+      break;
     case V2: {
-      auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-      return doSimplify_v2(F, DT);
+      DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
+      doSimplify_v2(F, DT);
+      break;
     }
     case V3: {
-      auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
-      return doSimplify_v3(F, DT);
+      DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
+      doSimplify_v3(F, DT);
+      break;
     }
     }
 
-    llvm_unreachable("Unsupported version");
+    return PreservedAnalyses::none();
   }
 };
 } // namespace
 
-char SimplifyCFGLegacyPass::ID = 0;
-INITIALIZE_PASS_BEGIN(SimplifyCFGLegacyPass, DEBUG_TYPE,
-                      "Tutorial CFG simplification", false, false)
-INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
-INITIALIZE_PASS_END(SimplifyCFGLegacyPass, DEBUG_TYPE,
-                    "Tutorial CFG simplifications", false, false)
+/* New PM Registration */
+llvm::PassPluginLibraryInfo getExampleIRTransformsPluginInfo() {
+  return {LLVM_PLUGIN_API_VERSION, "SimplifyCFG", LLVM_VERSION_STRING,
+          [](PassBuilder &PB) {
+            PB.registerPipelineParsingCallback(
+                [](StringRef Name, llvm::FunctionPassManager &PM,
+                   ArrayRef<llvm::PassBuilder::PipelineElement>) {
+                  if (Name == "tut-simplifycfg") {
+                    PM.addPass(SimplifyCFGPass());
+                    return true;
+                  }
+                  return false;
+                });
+          }};
+}
+
+#ifndef LLVM_SIMPLIFYCFG_LINK_INTO_TOOLS
+extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
+llvmGetPassPluginInfo() {
+  return getExampleIRTransformsPluginInfo();
+}
+#endif
Index: llvm/test/CMakeLists.txt
===================================================================
--- llvm/test/CMakeLists.txt
+++ llvm/test/CMakeLists.txt
@@ -16,6 +16,7 @@
   LLVM_BUILD_EXAMPLES
   LLVM_ENABLE_PLUGINS
   LLVM_BYE_LINK_INTO_TOOLS
+  LLVM_EXAMPLEIRTRANSFORMS_LINK_INTO_TOOLS
   LLVM_HAVE_TF_AOT
   LLVM_HAVE_TFLITE
   LLVM_INLINER_MODEL_AUTOGENERATED
@@ -189,6 +190,7 @@
   if (NOT WIN32)
     list(APPEND LLVM_TEST_DEPENDS
       Bye
+      ExampleIRTransforms
       )
   endif()
 endif()
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg-blockaddress.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg-blockaddress.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg-blockaddress.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 -enable-new-pm=0 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 -S < %s | FileCheck %s
 
 define i8* @simp1(i32 %x) {
 ; CHECK-LABEL: @simp1(
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg1.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg1.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg1.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 -enable-new-pm=0 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 -S < %s | FileCheck %s
 
 define i32 @simp1() {
 ; CHECK-LABEL: @simp1(
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg2-dead-block-order.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg2-dead-block-order.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg2-dead-block-order.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 -enable-new-pm=0 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 -S < %s | FileCheck %s
 
 define i32 @remove_dead_blocks() {
 ; CHECK-LABEL: @remove_dead_blocks(
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg3-phis.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg3-phis.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg3-phis.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 -enable-new-pm=0 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 -S < %s | FileCheck %s
 
 define i32 @phi_cond_branch_eliminated() {
 ; CHECK-LABEL: @phi_cond_branch_eliminated(
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg4-multiple-duplicate-cfg-updates.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg4-multiple-duplicate-cfg-updates.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg4-multiple-duplicate-cfg-updates.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 < %s -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 < %s -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 < %s -S -verify-dom-info | FileCheck %s
 
 ; Check that we do not crash when we remove edges multiple times in
 ; the DomTreeUpdater.
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg5-del-phis-for-dead-block.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg5-del-phis-for-dead-block.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg5-del-phis-for-dead-block.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 < %s -enable-new-pm=0 -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 < %s -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 < %s -S -verify-dom-info | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 < %s -S -verify-dom-info | FileCheck %s
 
 define void @test() {
 ; CHECK-LABEL: @test(
Index: llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg6-dead-self-loop.ll
===================================================================
--- llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg6-dead-self-loop.ll
+++ llvm/test/Examples/IRTransforms/SimplifyCFG/tut-simplify-cfg6-dead-self-loop.ll
@@ -1,7 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v1 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v2 -enable-new-pm=0 -S < %s | FileCheck %s
-; RUN: opt -tut-simplifycfg -tut-simplifycfg-version=v3 -enable-new-pm=0 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v1 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v2 -S < %s | FileCheck %s
+; RUN: opt %loadexampleirtransforms -passes=tut-simplifycfg -tut-simplifycfg-version=v3 -S < %s | FileCheck %s
 
 define i32 @simp1() {
 ; CHECK-LABEL: @simp1(
Index: llvm/test/lit.cfg.py
===================================================================
--- llvm/test/lit.cfg.py
+++ llvm/test/lit.cfg.py
@@ -288,6 +288,13 @@
                                  .format(config.llvm_shlib_dir,
                                          config.llvm_shlib_ext)))
 
+if config.linked_exampleirtransforms_extension:
+    config.substitutions.append(('%loadexampleirtransforms',''))
+else:
+    config.substitutions.append(('%loadexampleirtransforms',
+                                 '-load-pass-plugin={}/ExampleIRTransforms{}'
+                                 .format(config.llvm_shlib_dir,
+                                 config.llvm_shlib_ext)))
 
 # Static libraries are not built if BUILD_SHARED_LIBS is ON.
 if not config.build_shared_libs and not config.link_llvm_dylib:
Index: llvm/test/lit.site.cfg.py.in
===================================================================
--- llvm/test/lit.site.cfg.py.in
+++ llvm/test/lit.site.cfg.py.in
@@ -52,6 +52,7 @@
 config.libcxx_used = @LLVM_LIBCXX_USED@
 config.has_plugins = @LLVM_ENABLE_PLUGINS@
 config.linked_bye_extension = @LLVM_BYE_LINK_INTO_TOOLS@
+config.linked_exampleirtransforms_extension = @LLVM_EXAMPLEIRTRANSFORMS_LINK_INTO_TOOLS@
 config.have_tf_aot = @LLVM_HAVE_TF_AOT@
 config.have_tflite = @LLVM_HAVE_TFLITE@
 config.llvm_inliner_model_autogenerated = @LLVM_INLINER_MODEL_AUTOGENERATED@
Index: llvm/tools/opt/CMakeLists.txt
===================================================================
--- llvm/tools/opt/CMakeLists.txt
+++ llvm/tools/opt/CMakeLists.txt
@@ -40,7 +40,3 @@
   SUPPORT_PLUGINS
   )
 export_executable_symbols_for_plugins(opt)
-
-if(LLVM_BUILD_EXAMPLES)
-    target_link_libraries(opt PRIVATE ExampleIRTransforms)
-endif(LLVM_BUILD_EXAMPLES)
Index: llvm/tools/opt/opt.cpp
===================================================================
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -314,10 +314,6 @@
       codegen::getExplicitCodeModel(), GetCodeGenOptLevel());
 }
 
-#ifdef BUILD_EXAMPLES
-void initializeExampleIRTransforms(llvm::PassRegistry &Registry);
-#endif
-
 struct TimeTracerRAII {
   TimeTracerRAII(StringRef ProgramName) {
     if (TimeTrace)
@@ -454,10 +450,6 @@
   initializeReplaceWithVeclibLegacyPass(Registry);
   initializeJMCInstrumenterPass(Registry);
 
-#ifdef BUILD_EXAMPLES
-  initializeExampleIRTransforms(Registry);
-#endif
-
   SmallVector<PassPlugin, 1> PluginList;
   PassPlugins.setCallback([&](const std::string &PluginPath) {
     auto Plugin = PassPlugin::Load(PluginPath);