[llvm] [Passes] Enhance `--print-pipeline-passes` (PR #202892)

via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 10 01:59:23 PDT 2026


https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/202892

>From 3b2a2ce144d80c5d49435cb3792797f13fab6701 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Wed, 10 Jun 2026 16:29:23 +0800
Subject: [PATCH] [Passes] Support tree like pipeline printing

---
 llvm/include/llvm/Passes/PassBuilder.h       |  22 +-
 llvm/lib/Passes/PassBuilder.cpp              |  62 +-
 llvm/test/CodeGen/X86/llc-pipeline-npm.ll    | 714 ++++++++++---------
 llvm/test/tools/opt/print-pipeline-passes.ll |  13 +
 llvm/tools/llc/NewPMDriver.cpp               |   3 +-
 llvm/tools/opt/NewPMDriver.cpp               |   2 +-
 6 files changed, 462 insertions(+), 354 deletions(-)
 create mode 100644 llvm/test/tools/opt/print-pipeline-passes.ll

diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h
index 83d5dbbed751c..da99a5ab1ee92 100644
--- a/llvm/include/llvm/Passes/PassBuilder.h
+++ b/llvm/include/llvm/Passes/PassBuilder.h
@@ -999,8 +999,28 @@ class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
   }
 };
 
+enum class PrintPipelinePassesFormat {
+  Text,
+  Tree,
+};
+
+struct PrintPipelinePassesFormatParser
+    : public cl::parser<std::optional<PrintPipelinePassesFormat>> {
+  // using cl::parser<std::optional<PrintPipelinePassesFormat>>::parser;
+  PrintPipelinePassesFormatParser(cl::Option &O)
+      : cl::parser<std::optional<PrintPipelinePassesFormat>>(O) {}
+  LLVM_ABI bool parse(cl::Option &O, StringRef ArgName, StringRef ArgValue,
+                      std::optional<PrintPipelinePassesFormat> &Val);
+};
+
 /// Common option used by multiple tools to print pipeline passes
-LLVM_ABI extern cl::opt<bool> PrintPipelinePasses;
+LLVM_ABI extern cl::opt<std::optional<PrintPipelinePassesFormat>, false,
+                        PrintPipelinePassesFormatParser>
+    PrintPipelinePasses;
+
+LLVM_ABI void printFormattedPipelinePasses(
+    raw_ostream &OS, StringRef Pipeline,
+    PrintPipelinePassesFormat Format = PrintPipelinePassesFormat::Text);
 }
 
 #endif
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index f7db63ef8bf74..a31e5b65813e1 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -199,6 +199,7 @@
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/FormatAdapters.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/Regex.h"
 #include "llvm/Target/TargetMachine.h"
@@ -398,10 +399,63 @@
 
 using namespace llvm;
 
-cl::opt<bool> llvm::PrintPipelinePasses(
-    "print-pipeline-passes",
-    cl::desc("Print a '-passes' compatible string describing the pipeline "
-             "(best-effort only)."));
+cl::opt<std::optional<PrintPipelinePassesFormat>, false,
+        PrintPipelinePassesFormatParser>
+    llvm::PrintPipelinePasses(
+        "print-pipeline-passes", cl::ValueOptional,
+        cl::desc(
+            "Print string describing the pipeline (best-effort only).\n"
+            "  - =text\tPrint a '-passes' compatible string describing the "
+            "pipeline.\n"
+            "  - =tree\tPrint a tree-like structure describing the pipeline."));
+
+bool PrintPipelinePassesFormatParser::parse(
+    cl::Option &O, StringRef ArgName, StringRef Arg,
+    std::optional<PrintPipelinePassesFormat> &Val) {
+  std::optional<PrintPipelinePassesFormat> Format =
+      StringSwitch<std::optional<PrintPipelinePassesFormat>>(Arg)
+          .Case("text", PrintPipelinePassesFormat::Text)
+          .Case("", PrintPipelinePassesFormat::Text)
+          .Case("tree", PrintPipelinePassesFormat::Tree)
+          .Default(std::nullopt);
+
+  if (!Format)
+    return O.error(formatv(
+        "'{0}' value invalid for print-pipeline-passes argument!", Arg));
+
+  Val = Format;
+  return false;
+}
+
+void llvm::printFormattedPipelinePasses(raw_ostream &OS, StringRef Pipeline,
+                                        PrintPipelinePassesFormat Format) {
+  switch (Format) {
+  case PrintPipelinePassesFormat::Text:
+    OS << Pipeline;
+    break;
+  case PrintPipelinePassesFormat::Tree: {
+    int IndentLevel = 0;
+    for (char C : Pipeline) {
+      switch (C) {
+      case '(':
+        ++IndentLevel;
+        OS << formatv("\n{0}", fmt_repeat("  ", IndentLevel));
+        break;
+      case ')':
+        --IndentLevel;
+        assert(IndentLevel >= 0 && "Invalid pipeline string!");
+        break;
+      case ',':
+        OS << formatv("\n{0}", fmt_repeat("  ", IndentLevel));
+        break;
+      default:
+        OS << C;
+      }
+    }
+    break;
+  }
+  }
+}
 
 AnalysisKey NoOpModuleAnalysis::Key;
 AnalysisKey NoOpCGSCCAnalysis::Key;
diff --git a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
index db6d77f8bde54..ec96575e266e8 100644
--- a/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
+++ b/llvm/test/CodeGen/X86/llc-pipeline-npm.ll
@@ -1,14 +1,14 @@
-; RUN: llc -enable-new-pm -mtriple=x86_64 -O0 -print-pipeline-passes < %s 2>&1 \
-; RUN:   | tr ',' '\n' | FileCheck -check-prefix=O0 %s
+; RUN: llc -enable-new-pm -mtriple=x86_64 -O0 -print-pipeline-passes=tree < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=O0 %s
 
-; RUN: llc -enable-new-pm -mtriple=x86_64 -O2 -print-pipeline-passes < %s 2>&1 \
-; RUN:   | tr ',' '\n' | FileCheck -check-prefix=O2 %s
+; RUN: llc -enable-new-pm -mtriple=x86_64 -O2 -print-pipeline-passes=tree < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=O2 %s
 
-; RUN: llc -enable-new-pm -mtriple=x86_64-windows -O0 -print-pipeline-passes < %s 2>&1 \
-; RUN:   | tr ',' '\n' | FileCheck -check-prefix=O0-WINDOWS %s
+; RUN: llc -enable-new-pm -mtriple=x86_64-windows -O0 -print-pipeline-passes=tree < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=O0-WINDOWS %s
 
-; RUN: llc -enable-new-pm -mtriple=x86_64-windows -O3 -print-pipeline-passes < %s 2>&1 \
-; RUN:   | tr ',' '\n' | FileCheck -check-prefix=O3-WINDOWS %s
+; RUN: llc -enable-new-pm -mtriple=x86_64-windows -O3 -print-pipeline-passes=tree < %s 2>&1 \
+; RUN:   | FileCheck -check-prefix=O3-WINDOWS %s
 
 ; O0: require<MachineModuleAnalysis>
 ; O0-NEXT: require<profile-summary>
@@ -16,64 +16,68 @@
 ; O0-NEXT: require<runtime-libcall-info>
 ; O0-NEXT: require<libcall-lowering-info>
 ; O0-NEXT: pre-isel-intrinsic-lowering
-; O0-NEXT: function(expand-ir-insts<O0>
-; O0-NEXT: atomic-expand
-; O0-NEXT: x86-lower-amx-intrinsics
-; O0-NEXT: x86-lower-amx-type
-; O0-NEXT: verify
-; O0-NEXT: gc-lowering)
+; O0-NEXT: function
+; O0-NEXT:   expand-ir-insts<O0>
+; O0-NEXT:   atomic-expand
+; O0-NEXT:   x86-lower-amx-intrinsics
+; O0-NEXT:   x86-lower-amx-type
+; O0-NEXT:   verify
+; O0-NEXT:   gc-lowering
 ; O0-NEXT: shadow-stack-gc-lowering
-; O0-NEXT: function(unreachableblockelim
-; O0-NEXT: ee-instrument<post-inline>
-; O0-NEXT: scalarize-masked-mem-intrin
-; O0-NEXT: expand-reductions
-; O0-NEXT: indirectbr-expand
-; O0-NEXT: dwarf-eh-prepare
-; O0-NEXT: inline-asm-prepare
-; O0-NEXT: safe-stack
-; O0-NEXT: stack-protector
-; O0-NEXT: verify)
+; O0-NEXT: function
+; O0-NEXT:   unreachableblockelim
+; O0-NEXT:   ee-instrument<post-inline>
+; O0-NEXT:   scalarize-masked-mem-intrin
+; O0-NEXT:   expand-reductions
+; O0-NEXT:   indirectbr-expand
+; O0-NEXT:   dwarf-eh-prepare
+; O0-NEXT:   inline-asm-prepare
+; O0-NEXT:   safe-stack
+; O0-NEXT:   stack-protector
+; O0-NEXT:   verify
 ; O0-NEXT: x86-asm-printer-begin
-; O0-NEXT: function(machine-function(x86-isel
-; O0-NEXT: x86-global-base-reg
-; O0-NEXT: x86-argument-stack-slot
-; O0-NEXT: finalize-isel
-; O0-NEXT: localstackalloc
-; O0-NEXT: x86-suppress-apx-for-relocation
-; O0-NEXT: x86-slh
-; O0-NEXT: x86-flags-copy-lowering
-; O0-NEXT: x86-dyn-alloca-expander
-; O0-NEXT: x86-fast-pre-tile-config
-; O0-NEXT: phi-node-elimination
-; O0-NEXT: two-address-instruction
-; O0-NEXT: regallocfast
-; O0-NEXT: x86-lower-tile-copy
-; O0-NEXT: x86-fp-stackifier
-; O0-NEXT: remove-redundant-debug-values
-; O0-NEXT: fixup-statepoint-caller-saved
-; O0-NEXT: prolog-epilog
-; O0-NEXT: post-ra-pseudos
-; O0-NEXT: x86-expand-pseudo
-; O0-NEXT: kcfi
-; O0-NEXT: fentry-insert
-; O0-NEXT: xray-instrumentation
-; O0-NEXT: patchable-function
-; O0-NEXT: x86-indirect-branch-tracking
-; O0-NEXT: x86-insert-vzeroupper
-; O0-NEXT: x86-compress-evex
-; O0-NEXT: x86-insert-x87-wait
-; O0-NEXT: FuncletLayoutPass
-; O0-NEXT: remove-loads-into-fake-uses
-; O0-NEXT: StackMapLivenessPass
-; O0-NEXT: live-debug-values<emit-debug-entry-values>
-; O0-NEXT: machine-sanmd
-; O0-NEXT: stack-frame-layout
-; O0-NEXT: x86-seses
-; O0-NEXT: x86-return-thunks
-; O0-NEXT: x86-lvi-ret
-; O0-NEXT: verify
-; O0-NEXT: x86-asm-printer)
-; O0-NEXT: free-machine-function)
+; O0-NEXT: function
+; O0-NEXT:   machine-function
+; O0-NEXT:     x86-isel
+; O0-NEXT:     x86-global-base-reg
+; O0-NEXT:     x86-argument-stack-slot
+; O0-NEXT:     finalize-isel
+; O0-NEXT:     localstackalloc
+; O0-NEXT:     x86-suppress-apx-for-relocation
+; O0-NEXT:     x86-slh
+; O0-NEXT:     x86-flags-copy-lowering
+; O0-NEXT:     x86-dyn-alloca-expander
+; O0-NEXT:     x86-fast-pre-tile-config
+; O0-NEXT:     phi-node-elimination
+; O0-NEXT:     two-address-instruction
+; O0-NEXT:     regallocfast
+; O0-NEXT:     x86-lower-tile-copy
+; O0-NEXT:     x86-fp-stackifier
+; O0-NEXT:     remove-redundant-debug-values
+; O0-NEXT:     fixup-statepoint-caller-saved
+; O0-NEXT:     prolog-epilog
+; O0-NEXT:     post-ra-pseudos
+; O0-NEXT:     x86-expand-pseudo
+; O0-NEXT:     kcfi
+; O0-NEXT:     fentry-insert
+; O0-NEXT:     xray-instrumentation
+; O0-NEXT:     patchable-function
+; O0-NEXT:     x86-indirect-branch-tracking
+; O0-NEXT:     x86-insert-vzeroupper
+; O0-NEXT:     x86-compress-evex
+; O0-NEXT:     x86-insert-x87-wait
+; O0-NEXT:     FuncletLayoutPass
+; O0-NEXT:     remove-loads-into-fake-uses
+; O0-NEXT:     StackMapLivenessPass
+; O0-NEXT:     live-debug-values<emit-debug-entry-values>
+; O0-NEXT:     machine-sanmd
+; O0-NEXT:     stack-frame-layout
+; O0-NEXT:     x86-seses
+; O0-NEXT:     x86-return-thunks
+; O0-NEXT:     x86-lvi-ret
+; O0-NEXT:     verify
+; O0-NEXT:     x86-asm-printer
+; O0-NEXT:   free-machine-function
 ; O0-NEXT: x86-asm-printer-end
 
 ; O2: require<MachineModuleAnalysis>
@@ -81,119 +85,125 @@
 ; O2-NEXT: require<collector-metadata>
 ; O2-NEXT: require<runtime-libcall-info>
 ; O2-NEXT: require<libcall-lowering-info>
-; O2-NEXT: function(objc-arc-contract)
+; O2-NEXT: function
+; O2-NEXT:   objc-arc-contract
 ; O2-NEXT: pre-isel-intrinsic-lowering
-; O2-NEXT: function(expand-ir-insts<O2>
-; O2-NEXT: atomic-expand
-; O2-NEXT: x86-lower-amx-intrinsics
-; O2-NEXT: x86-lower-amx-type
-; O2-NEXT: verify
-; O2-NEXT: loop(canon-freeze
-; O2-NEXT: loop-reduce)
-; O2-NEXT: gc-lowering)
+; O2-NEXT: function
+; O2-NEXT:   expand-ir-insts<O2>
+; O2-NEXT:   atomic-expand
+; O2-NEXT:   x86-lower-amx-intrinsics
+; O2-NEXT:   x86-lower-amx-type
+; O2-NEXT:   verify
+; O2-NEXT:   loop
+; O2-NEXT:     canon-freeze
+; O2-NEXT:     loop-reduce
+; O2-NEXT:   gc-lowering
 ; O2-NEXT: shadow-stack-gc-lowering
-; O2-NEXT: function(unreachableblockelim
-; O2-NEXT: consthoist
-; O2-NEXT: replace-with-veclib
-; O2-NEXT: partially-inline-libcalls
-; O2-NEXT: ee-instrument<post-inline>
-; O2-NEXT: scalarize-masked-mem-intrin
-; O2-NEXT: expand-reductions
-; O2-NEXT: interleaved-access
-; O2-NEXT: x86-partial-reduction
-; O2-NEXT: indirectbr-expand
-; O2-NEXT: codegenprepare
-; O2-NEXT: dwarf-eh-prepare
-; O2-NEXT: inline-asm-prepare
-; O2-NEXT: safe-stack
-; O2-NEXT: stack-protector
-; O2-NEXT: verify)
+; O2-NEXT: function
+; O2-NEXT:   unreachableblockelim
+; O2-NEXT:   consthoist
+; O2-NEXT:   replace-with-veclib
+; O2-NEXT:   partially-inline-libcalls
+; O2-NEXT:   ee-instrument<post-inline>
+; O2-NEXT:   scalarize-masked-mem-intrin
+; O2-NEXT:   expand-reductions
+; O2-NEXT:   interleaved-access
+; O2-NEXT:   x86-partial-reduction
+; O2-NEXT:   indirectbr-expand
+; O2-NEXT:   codegenprepare
+; O2-NEXT:   dwarf-eh-prepare
+; O2-NEXT:   inline-asm-prepare
+; O2-NEXT:   safe-stack
+; O2-NEXT:   stack-protector
+; O2-NEXT:   verify
 ; O2-NEXT: x86-asm-printer-begin
-; O2-NEXT: function(machine-function(x86-isel
-; O2-NEXT: x86-cleanup-local-dynamic-tls
-; O2-NEXT: x86-global-base-reg
-; O2-NEXT: x86-argument-stack-slot
-; O2-NEXT: finalize-isel
-; O2-NEXT: x86-domain-reassignment
-; O2-NEXT: early-tailduplication
-; O2-NEXT: opt-phis
-; O2-NEXT: stack-coloring
-; O2-NEXT: localstackalloc
-; O2-NEXT: dead-mi-elimination
-; O2-NEXT: early-ifcvt
-; O2-NEXT: x86-cmov-conversion
-; O2-NEXT: early-machinelicm
-; O2-NEXT: machine-cse
-; O2-NEXT: machine-sink
-; O2-NEXT: peephole-opt
-; O2-NEXT: dead-mi-elimination
-; O2-NEXT: LiveRangeShrinkPass
-; O2-NEXT: x86-fixup-setcc
-; O2-NEXT: x86-cf-opt
-; O2-NEXT: x86-avoid-sfb
-; O2-NEXT: x86-suppress-apx-for-relocation
-; O2-NEXT: x86-slh
-; O2-NEXT: x86-flags-copy-lowering
-; O2-NEXT: x86-dyn-alloca-expander
-; O2-NEXT: x86-pre-tile-config
-; O2-NEXT: detect-dead-lanes
-; O2-NEXT: init-undef
-; O2-NEXT: process-imp-defs
-; O2-NEXT: unreachable-mbb-elimination
-; O2-NEXT: require<live-vars>
-; O2-NEXT: require<machine-loops>
-; O2-NEXT: phi-node-elimination
-; O2-NEXT: two-address-instruction
-; O2-NEXT: register-coalescer
-; O2-NEXT: rename-independent-subregs
-; O2-NEXT: machine-scheduler
-; O2-NEXT: greedy<all>
-; O2-NEXT: virt-reg-rewriter
-; O2-NEXT: stack-slot-coloring
-; O2-NEXT: stack-slot-coloring
-; O2-NEXT: machine-cp
-; O2-NEXT: machinelicm
-; O2-NEXT: x86-lower-tile-copy
-; O2-NEXT: x86-fp-stackifier
-; O2-NEXT: x86-lvi-load
-; O2-NEXT: remove-redundant-debug-values
-; O2-NEXT: fixup-statepoint-caller-saved
-; O2-NEXT: postra-machine-sink
-; O2-NEXT: shrink-wrap
-; O2-NEXT: prolog-epilog
-; O2-NEXT: machine-latecleanup
-; O2-NEXT: branch-folder
-; O2-NEXT: tailduplication
-; O2-NEXT: machine-cp
-; O2-NEXT: post-ra-pseudos
-; O2-NEXT: x86-expand-pseudo
-; O2-NEXT: kcfi
-; O2-NEXT: post-RA-sched
-; O2-NEXT: block-placement
-; O2-NEXT: fentry-insert
-; O2-NEXT: xray-instrumentation
-; O2-NEXT: patchable-function
-; O2-NEXT: break-false-deps
-; O2-NEXT: x86-indirect-branch-tracking
-; O2-NEXT: x86-insert-vzeroupper
-; O2-NEXT: x86-fixup-bw-insts
-; O2-NEXT: x86-fixup-leas
-; O2-NEXT: x86-fixup-inst-tuning
-; O2-NEXT: x86-fixup-inst-tuning
-; O2-NEXT: x86-compress-evex
-; O2-NEXT: x86-insert-x87-wait
-; O2-NEXT: FuncletLayoutPass
-; O2-NEXT: remove-loads-into-fake-uses
-; O2-NEXT: StackMapLivenessPass
-; O2-NEXT: live-debug-values<emit-debug-entry-values>
-; O2-NEXT: machine-sanmd
-; O2-NEXT: stack-frame-layout
-; O2-NEXT: x86-seses
-; O2-NEXT: x86-return-thunks
-; O2-NEXT: x86-lvi-ret
-; O2-NEXT: verify
-; O2-NEXT: x86-asm-printer)
-; O2-NEXT: free-machine-function)
+; O2-NEXT: function
+; O2-NEXT:   machine-function
+; O2-NEXT:     x86-isel
+; O2-NEXT:     x86-cleanup-local-dynamic-tls
+; O2-NEXT:     x86-global-base-reg
+; O2-NEXT:     x86-argument-stack-slot
+; O2-NEXT:     finalize-isel
+; O2-NEXT:     x86-domain-reassignment
+; O2-NEXT:     early-tailduplication
+; O2-NEXT:     opt-phis
+; O2-NEXT:     stack-coloring
+; O2-NEXT:     localstackalloc
+; O2-NEXT:     dead-mi-elimination
+; O2-NEXT:     early-ifcvt
+; O2-NEXT:     x86-cmov-conversion
+; O2-NEXT:     early-machinelicm
+; O2-NEXT:     machine-cse
+; O2-NEXT:     machine-sink
+; O2-NEXT:     peephole-opt
+; O2-NEXT:     dead-mi-elimination
+; O2-NEXT:     LiveRangeShrinkPass
+; O2-NEXT:     x86-fixup-setcc
+; O2-NEXT:     x86-cf-opt
+; O2-NEXT:     x86-avoid-sfb
+; O2-NEXT:     x86-suppress-apx-for-relocation
+; O2-NEXT:     x86-slh
+; O2-NEXT:     x86-flags-copy-lowering
+; O2-NEXT:     x86-dyn-alloca-expander
+; O2-NEXT:     x86-pre-tile-config
+; O2-NEXT:     detect-dead-lanes
+; O2-NEXT:     init-undef
+; O2-NEXT:     process-imp-defs
+; O2-NEXT:     unreachable-mbb-elimination
+; O2-NEXT:     require<live-vars>
+; O2-NEXT:     require<machine-loops>
+; O2-NEXT:     phi-node-elimination
+; O2-NEXT:     two-address-instruction
+; O2-NEXT:     register-coalescer
+; O2-NEXT:     rename-independent-subregs
+; O2-NEXT:     machine-scheduler
+; O2-NEXT:     greedy<all>
+; O2-NEXT:     virt-reg-rewriter
+; O2-NEXT:     stack-slot-coloring
+; O2-NEXT:     stack-slot-coloring
+; O2-NEXT:     machine-cp
+; O2-NEXT:     machinelicm
+; O2-NEXT:     x86-lower-tile-copy
+; O2-NEXT:     x86-fp-stackifier
+; O2-NEXT:     x86-lvi-load
+; O2-NEXT:     remove-redundant-debug-values
+; O2-NEXT:     fixup-statepoint-caller-saved
+; O2-NEXT:     postra-machine-sink
+; O2-NEXT:     shrink-wrap
+; O2-NEXT:     prolog-epilog
+; O2-NEXT:     machine-latecleanup
+; O2-NEXT:     branch-folder
+; O2-NEXT:     tailduplication
+; O2-NEXT:     machine-cp
+; O2-NEXT:     post-ra-pseudos
+; O2-NEXT:     x86-expand-pseudo
+; O2-NEXT:     kcfi
+; O2-NEXT:     post-RA-sched
+; O2-NEXT:     block-placement
+; O2-NEXT:     fentry-insert
+; O2-NEXT:     xray-instrumentation
+; O2-NEXT:     patchable-function
+; O2-NEXT:     break-false-deps
+; O2-NEXT:     x86-indirect-branch-tracking
+; O2-NEXT:     x86-insert-vzeroupper
+; O2-NEXT:     x86-fixup-bw-insts
+; O2-NEXT:     x86-fixup-leas
+; O2-NEXT:     x86-fixup-inst-tuning
+; O2-NEXT:     x86-fixup-inst-tuning
+; O2-NEXT:     x86-compress-evex
+; O2-NEXT:     x86-insert-x87-wait
+; O2-NEXT:     FuncletLayoutPass
+; O2-NEXT:     remove-loads-into-fake-uses
+; O2-NEXT:     StackMapLivenessPass
+; O2-NEXT:     live-debug-values<emit-debug-entry-values>
+; O2-NEXT:     machine-sanmd
+; O2-NEXT:     stack-frame-layout
+; O2-NEXT:     x86-seses
+; O2-NEXT:     x86-return-thunks
+; O2-NEXT:     x86-lvi-ret
+; O2-NEXT:     verify
+; O2-NEXT:     x86-asm-printer
+; O2-NEXT:   free-machine-function
 ; O2-NEXT: x86-asm-printer-end
 
 ; O0-WINDOWS: require<MachineModuleAnalysis>
@@ -202,68 +212,72 @@
 ; O0-WINDOWS-NEXT: require<runtime-libcall-info>
 ; O0-WINDOWS-NEXT: require<libcall-lowering-info>
 ; O0-WINDOWS-NEXT: pre-isel-intrinsic-lowering
-; O0-WINDOWS-NEXT: function(expand-ir-insts<O0>
-; O0-WINDOWS-NEXT: atomic-expand
-; O0-WINDOWS-NEXT: x86-lower-amx-intrinsics
-; O0-WINDOWS-NEXT: x86-lower-amx-type
-; O0-WINDOWS-NEXT: verify
-; O0-WINDOWS-NEXT: gc-lowering)
+; O0-WINDOWS-NEXT: function
+; O0-WINDOWS-NEXT:   expand-ir-insts<O0>
+; O0-WINDOWS-NEXT:   atomic-expand
+; O0-WINDOWS-NEXT:   x86-lower-amx-intrinsics
+; O0-WINDOWS-NEXT:   x86-lower-amx-type
+; O0-WINDOWS-NEXT:   verify
+; O0-WINDOWS-NEXT:   gc-lowering
 ; O0-WINDOWS-NEXT: shadow-stack-gc-lowering
-; O0-WINDOWS-NEXT: function(unreachableblockelim
-; O0-WINDOWS-NEXT: ee-instrument<post-inline>
-; O0-WINDOWS-NEXT: scalarize-masked-mem-intrin
-; O0-WINDOWS-NEXT: expand-reductions
-; O0-WINDOWS-NEXT: indirectbr-expand
-; O0-WINDOWS-NEXT: cfguard
-; O0-WINDOWS-NEXT: win-eh-prepare
-; O0-WINDOWS-NEXT: dwarf-eh-prepare
-; O0-WINDOWS-NEXT: inline-asm-prepare
-; O0-WINDOWS-NEXT: safe-stack
-; O0-WINDOWS-NEXT: stack-protector
-; O0-WINDOWS-NEXT: verify)
+; O0-WINDOWS-NEXT: function
+; O0-WINDOWS-NEXT:   unreachableblockelim
+; O0-WINDOWS-NEXT:   ee-instrument<post-inline>
+; O0-WINDOWS-NEXT:   scalarize-masked-mem-intrin
+; O0-WINDOWS-NEXT:   expand-reductions
+; O0-WINDOWS-NEXT:   indirectbr-expand
+; O0-WINDOWS-NEXT:   cfguard
+; O0-WINDOWS-NEXT:   win-eh-prepare
+; O0-WINDOWS-NEXT:   dwarf-eh-prepare
+; O0-WINDOWS-NEXT:   inline-asm-prepare
+; O0-WINDOWS-NEXT:   safe-stack
+; O0-WINDOWS-NEXT:   stack-protector
+; O0-WINDOWS-NEXT:   verify
 ; O0-WINDOWS-NEXT: x86-asm-printer-begin
-; O0-WINDOWS-NEXT: function(machine-function(x86-isel
-; O0-WINDOWS-NEXT: x86-global-base-reg
-; O0-WINDOWS-NEXT: x86-argument-stack-slot
-; O0-WINDOWS-NEXT: finalize-isel
-; O0-WINDOWS-NEXT: localstackalloc
-; O0-WINDOWS-NEXT: x86-suppress-apx-for-relocation
-; O0-WINDOWS-NEXT: x86-slh
-; O0-WINDOWS-NEXT: x86-flags-copy-lowering
-; O0-WINDOWS-NEXT: x86-dyn-alloca-expander
-; O0-WINDOWS-NEXT: x86-fast-pre-tile-config
-; O0-WINDOWS-NEXT: phi-node-elimination
-; O0-WINDOWS-NEXT: two-address-instruction
-; O0-WINDOWS-NEXT: regallocfast
-; O0-WINDOWS-NEXT: x86-lower-tile-copy
-; O0-WINDOWS-NEXT: x86-fp-stackifier
-; O0-WINDOWS-NEXT: remove-redundant-debug-values
-; O0-WINDOWS-NEXT: fixup-statepoint-caller-saved
-; O0-WINDOWS-NEXT: prolog-epilog
-; O0-WINDOWS-NEXT: post-ra-pseudos
-; O0-WINDOWS-NEXT: x86-expand-pseudo
-; O0-WINDOWS-NEXT: kcfi
-; O0-WINDOWS-NEXT: fentry-insert
-; O0-WINDOWS-NEXT: xray-instrumentation
-; O0-WINDOWS-NEXT: patchable-function
-; O0-WINDOWS-NEXT: x86-indirect-branch-tracking
-; O0-WINDOWS-NEXT: x86-insert-vzeroupper
-; O0-WINDOWS-NEXT: x86-compress-evex
-; O0-WINDOWS-NEXT: x86-insert-x87-wait
-; O0-WINDOWS-NEXT: FuncletLayoutPass
-; O0-WINDOWS-NEXT: remove-loads-into-fake-uses
-; O0-WINDOWS-NEXT: StackMapLivenessPass
-; O0-WINDOWS-NEXT: live-debug-values<emit-debug-entry-values>
-; O0-WINDOWS-NEXT: machine-sanmd
-; O0-WINDOWS-NEXT: stack-frame-layout
-; O0-WINDOWS-NEXT: x86-seses
-; O0-WINDOWS-NEXT: x86-return-thunks
-; O0-WINDOWS-NEXT: x86-avoid-trailing-call
-; O0-WINDOWS-NEXT: x86-lvi-ret
-; O0-WINDOWS-NEXT: x86-wineh-unwindv2
-; O0-WINDOWS-NEXT: verify
-; O0-WINDOWS-NEXT: x86-asm-printer)
-; O0-WINDOWS-NEXT: free-machine-function)
+; O0-WINDOWS-NEXT: function
+; O0-WINDOWS-NEXT:   machine-function
+; O0-WINDOWS-NEXT:     x86-isel
+; O0-WINDOWS-NEXT:     x86-global-base-reg
+; O0-WINDOWS-NEXT:     x86-argument-stack-slot
+; O0-WINDOWS-NEXT:     finalize-isel
+; O0-WINDOWS-NEXT:     localstackalloc
+; O0-WINDOWS-NEXT:     x86-suppress-apx-for-relocation
+; O0-WINDOWS-NEXT:     x86-slh
+; O0-WINDOWS-NEXT:     x86-flags-copy-lowering
+; O0-WINDOWS-NEXT:     x86-dyn-alloca-expander
+; O0-WINDOWS-NEXT:     x86-fast-pre-tile-config
+; O0-WINDOWS-NEXT:     phi-node-elimination
+; O0-WINDOWS-NEXT:     two-address-instruction
+; O0-WINDOWS-NEXT:     regallocfast
+; O0-WINDOWS-NEXT:     x86-lower-tile-copy
+; O0-WINDOWS-NEXT:     x86-fp-stackifier
+; O0-WINDOWS-NEXT:     remove-redundant-debug-values
+; O0-WINDOWS-NEXT:     fixup-statepoint-caller-saved
+; O0-WINDOWS-NEXT:     prolog-epilog
+; O0-WINDOWS-NEXT:     post-ra-pseudos
+; O0-WINDOWS-NEXT:     x86-expand-pseudo
+; O0-WINDOWS-NEXT:     kcfi
+; O0-WINDOWS-NEXT:     fentry-insert
+; O0-WINDOWS-NEXT:     xray-instrumentation
+; O0-WINDOWS-NEXT:     patchable-function
+; O0-WINDOWS-NEXT:     x86-indirect-branch-tracking
+; O0-WINDOWS-NEXT:     x86-insert-vzeroupper
+; O0-WINDOWS-NEXT:     x86-compress-evex
+; O0-WINDOWS-NEXT:     x86-insert-x87-wait
+; O0-WINDOWS-NEXT:     FuncletLayoutPass
+; O0-WINDOWS-NEXT:     remove-loads-into-fake-uses
+; O0-WINDOWS-NEXT:     StackMapLivenessPass
+; O0-WINDOWS-NEXT:     live-debug-values<emit-debug-entry-values>
+; O0-WINDOWS-NEXT:     machine-sanmd
+; O0-WINDOWS-NEXT:     stack-frame-layout
+; O0-WINDOWS-NEXT:     x86-seses
+; O0-WINDOWS-NEXT:     x86-return-thunks
+; O0-WINDOWS-NEXT:     x86-avoid-trailing-call
+; O0-WINDOWS-NEXT:     x86-lvi-ret
+; O0-WINDOWS-NEXT:     x86-wineh-unwindv2
+; O0-WINDOWS-NEXT:     verify
+; O0-WINDOWS-NEXT:     x86-asm-printer
+; O0-WINDOWS-NEXT:   free-machine-function
 ; O0-WINDOWS-NEXT: x86-asm-printer-end
 
 ; O3-WINDOWS: require<MachineModuleAnalysis>
@@ -271,120 +285,126 @@
 ; O3-WINDOWS-NEXT: require<collector-metadata>
 ; O3-WINDOWS-NEXT: require<runtime-libcall-info>
 ; O3-WINDOWS-NEXT: require<libcall-lowering-info>
-; O3-WINDOWS-NEXT: function(objc-arc-contract)
+; O3-WINDOWS-NEXT: function
+; O3-WINDOWS-NEXT:   objc-arc-contract
 ; O3-WINDOWS-NEXT: pre-isel-intrinsic-lowering
-; O3-WINDOWS-NEXT: function(expand-ir-insts<O3>
-; O3-WINDOWS-NEXT: atomic-expand
-; O3-WINDOWS-NEXT: x86-lower-amx-intrinsics
-; O3-WINDOWS-NEXT: x86-lower-amx-type
-; O3-WINDOWS-NEXT: verify
-; O3-WINDOWS-NEXT: loop(canon-freeze
-; O3-WINDOWS-NEXT: loop-reduce)
-; O3-WINDOWS-NEXT: gc-lowering)
+; O3-WINDOWS-NEXT: function
+; O3-WINDOWS-NEXT:   expand-ir-insts<O3>
+; O3-WINDOWS-NEXT:   atomic-expand
+; O3-WINDOWS-NEXT:   x86-lower-amx-intrinsics
+; O3-WINDOWS-NEXT:   x86-lower-amx-type
+; O3-WINDOWS-NEXT:   verify
+; O3-WINDOWS-NEXT:   loop
+; O3-WINDOWS-NEXT:     canon-freeze
+; O3-WINDOWS-NEXT:     loop-reduce
+; O3-WINDOWS-NEXT:   gc-lowering
 ; O3-WINDOWS-NEXT: shadow-stack-gc-lowering
-; O3-WINDOWS-NEXT: function(unreachableblockelim
-; O3-WINDOWS-NEXT: consthoist
-; O3-WINDOWS-NEXT: replace-with-veclib
-; O3-WINDOWS-NEXT: partially-inline-libcalls
-; O3-WINDOWS-NEXT: ee-instrument<post-inline>
-; O3-WINDOWS-NEXT: scalarize-masked-mem-intrin
-; O3-WINDOWS-NEXT: expand-reductions
-; O3-WINDOWS-NEXT: interleaved-access
-; O3-WINDOWS-NEXT: x86-partial-reduction
-; O3-WINDOWS-NEXT: indirectbr-expand
-; O3-WINDOWS-NEXT: cfguard
-; O3-WINDOWS-NEXT: codegenprepare
-; O3-WINDOWS-NEXT: win-eh-prepare
-; O3-WINDOWS-NEXT: dwarf-eh-prepare
-; O3-WINDOWS-NEXT: inline-asm-prepare
-; O3-WINDOWS-NEXT: safe-stack
-; O3-WINDOWS-NEXT: stack-protector
-; O3-WINDOWS-NEXT: verify)
+; O3-WINDOWS-NEXT: function
+; O3-WINDOWS-NEXT:   unreachableblockelim
+; O3-WINDOWS-NEXT:   consthoist
+; O3-WINDOWS-NEXT:   replace-with-veclib
+; O3-WINDOWS-NEXT:   partially-inline-libcalls
+; O3-WINDOWS-NEXT:   ee-instrument<post-inline>
+; O3-WINDOWS-NEXT:   scalarize-masked-mem-intrin
+; O3-WINDOWS-NEXT:   expand-reductions
+; O3-WINDOWS-NEXT:   interleaved-access
+; O3-WINDOWS-NEXT:   x86-partial-reduction
+; O3-WINDOWS-NEXT:   indirectbr-expand
+; O3-WINDOWS-NEXT:   cfguard
+; O3-WINDOWS-NEXT:   codegenprepare
+; O3-WINDOWS-NEXT:   win-eh-prepare
+; O3-WINDOWS-NEXT:   dwarf-eh-prepare
+; O3-WINDOWS-NEXT:   inline-asm-prepare
+; O3-WINDOWS-NEXT:   safe-stack
+; O3-WINDOWS-NEXT:   stack-protector
+; O3-WINDOWS-NEXT:   verify
 ; O3-WINDOWS-NEXT: x86-asm-printer-begin
-; O3-WINDOWS-NEXT: function(machine-function(x86-isel
-; O3-WINDOWS-NEXT: x86-global-base-reg
-; O3-WINDOWS-NEXT: x86-argument-stack-slot
-; O3-WINDOWS-NEXT: finalize-isel
-; O3-WINDOWS-NEXT: x86-domain-reassignment
-; O3-WINDOWS-NEXT: early-tailduplication
-; O3-WINDOWS-NEXT: opt-phis
-; O3-WINDOWS-NEXT: stack-coloring
-; O3-WINDOWS-NEXT: localstackalloc
-; O3-WINDOWS-NEXT: dead-mi-elimination
-; O3-WINDOWS-NEXT: early-ifcvt
-; O3-WINDOWS-NEXT: x86-cmov-conversion
-; O3-WINDOWS-NEXT: early-machinelicm
-; O3-WINDOWS-NEXT: machine-cse
-; O3-WINDOWS-NEXT: machine-sink
-; O3-WINDOWS-NEXT: peephole-opt
-; O3-WINDOWS-NEXT: dead-mi-elimination
-; O3-WINDOWS-NEXT: LiveRangeShrinkPass
-; O3-WINDOWS-NEXT: x86-fixup-setcc
-; O3-WINDOWS-NEXT: x86-cf-opt
-; O3-WINDOWS-NEXT: x86-avoid-sfb
-; O3-WINDOWS-NEXT: x86-suppress-apx-for-relocation
-; O3-WINDOWS-NEXT: x86-slh
-; O3-WINDOWS-NEXT: x86-flags-copy-lowering
-; O3-WINDOWS-NEXT: x86-dyn-alloca-expander
-; O3-WINDOWS-NEXT: x86-pre-tile-config
-; O3-WINDOWS-NEXT: detect-dead-lanes
-; O3-WINDOWS-NEXT: init-undef
-; O3-WINDOWS-NEXT: process-imp-defs
-; O3-WINDOWS-NEXT: unreachable-mbb-elimination
-; O3-WINDOWS-NEXT: require<live-vars>
-; O3-WINDOWS-NEXT: require<machine-loops>
-; O3-WINDOWS-NEXT: phi-node-elimination
-; O3-WINDOWS-NEXT: two-address-instruction
-; O3-WINDOWS-NEXT: register-coalescer
-; O3-WINDOWS-NEXT: rename-independent-subregs
-; O3-WINDOWS-NEXT: machine-scheduler
-; O3-WINDOWS-NEXT: greedy<all>
-; O3-WINDOWS-NEXT: virt-reg-rewriter
-; O3-WINDOWS-NEXT: stack-slot-coloring
-; O3-WINDOWS-NEXT: stack-slot-coloring
-; O3-WINDOWS-NEXT: machine-cp
-; O3-WINDOWS-NEXT: machinelicm
-; O3-WINDOWS-NEXT: x86-lower-tile-copy
-; O3-WINDOWS-NEXT: x86-fp-stackifier
-; O3-WINDOWS-NEXT: x86-lvi-load
-; O3-WINDOWS-NEXT: remove-redundant-debug-values
-; O3-WINDOWS-NEXT: fixup-statepoint-caller-saved
-; O3-WINDOWS-NEXT: postra-machine-sink
-; O3-WINDOWS-NEXT: shrink-wrap
-; O3-WINDOWS-NEXT: prolog-epilog
-; O3-WINDOWS-NEXT: machine-latecleanup
-; O3-WINDOWS-NEXT: branch-folder
-; O3-WINDOWS-NEXT: tailduplication
-; O3-WINDOWS-NEXT: machine-cp
-; O3-WINDOWS-NEXT: post-ra-pseudos
-; O3-WINDOWS-NEXT: x86-expand-pseudo
-; O3-WINDOWS-NEXT: kcfi
-; O3-WINDOWS-NEXT: post-RA-sched
-; O3-WINDOWS-NEXT: block-placement
-; O3-WINDOWS-NEXT: fentry-insert
-; O3-WINDOWS-NEXT: xray-instrumentation
-; O3-WINDOWS-NEXT: patchable-function
-; O3-WINDOWS-NEXT: break-false-deps
-; O3-WINDOWS-NEXT: x86-indirect-branch-tracking
-; O3-WINDOWS-NEXT: x86-insert-vzeroupper
-; O3-WINDOWS-NEXT: x86-fixup-bw-insts
-; O3-WINDOWS-NEXT: x86-fixup-leas
-; O3-WINDOWS-NEXT: x86-fixup-inst-tuning
-; O3-WINDOWS-NEXT: x86-fixup-inst-tuning
-; O3-WINDOWS-NEXT: x86-compress-evex
-; O3-WINDOWS-NEXT: x86-insert-x87-wait
-; O3-WINDOWS-NEXT: FuncletLayoutPass
-; O3-WINDOWS-NEXT: remove-loads-into-fake-uses
-; O3-WINDOWS-NEXT: StackMapLivenessPass
-; O3-WINDOWS-NEXT: live-debug-values<emit-debug-entry-values>
-; O3-WINDOWS-NEXT: machine-sanmd
-; O3-WINDOWS-NEXT: stack-frame-layout
-; O3-WINDOWS-NEXT: x86-seses
-; O3-WINDOWS-NEXT: x86-return-thunks
-; O3-WINDOWS-NEXT: x86-avoid-trailing-call
-; O3-WINDOWS-NEXT: x86-lvi-ret
-; O3-WINDOWS-NEXT: x86-wineh-unwindv2
-; O3-WINDOWS-NEXT: verify
-; O3-WINDOWS-NEXT: x86-asm-printer)
-; O3-WINDOWS-NEXT: free-machine-function)
+; O3-WINDOWS-NEXT: function
+; O3-WINDOWS-NEXT:   machine-function
+; O3-WINDOWS-NEXT:     x86-isel
+; O3-WINDOWS-NEXT:     x86-global-base-reg
+; O3-WINDOWS-NEXT:     x86-argument-stack-slot
+; O3-WINDOWS-NEXT:     finalize-isel
+; O3-WINDOWS-NEXT:     x86-domain-reassignment
+; O3-WINDOWS-NEXT:     early-tailduplication
+; O3-WINDOWS-NEXT:     opt-phis
+; O3-WINDOWS-NEXT:     stack-coloring
+; O3-WINDOWS-NEXT:     localstackalloc
+; O3-WINDOWS-NEXT:     dead-mi-elimination
+; O3-WINDOWS-NEXT:     early-ifcvt
+; O3-WINDOWS-NEXT:     x86-cmov-conversion
+; O3-WINDOWS-NEXT:     early-machinelicm
+; O3-WINDOWS-NEXT:     machine-cse
+; O3-WINDOWS-NEXT:     machine-sink
+; O3-WINDOWS-NEXT:     peephole-opt
+; O3-WINDOWS-NEXT:     dead-mi-elimination
+; O3-WINDOWS-NEXT:     LiveRangeShrinkPass
+; O3-WINDOWS-NEXT:     x86-fixup-setcc
+; O3-WINDOWS-NEXT:     x86-cf-opt
+; O3-WINDOWS-NEXT:     x86-avoid-sfb
+; O3-WINDOWS-NEXT:     x86-suppress-apx-for-relocation
+; O3-WINDOWS-NEXT:     x86-slh
+; O3-WINDOWS-NEXT:     x86-flags-copy-lowering
+; O3-WINDOWS-NEXT:     x86-dyn-alloca-expander
+; O3-WINDOWS-NEXT:     x86-pre-tile-config
+; O3-WINDOWS-NEXT:     detect-dead-lanes
+; O3-WINDOWS-NEXT:     init-undef
+; O3-WINDOWS-NEXT:     process-imp-defs
+; O3-WINDOWS-NEXT:     unreachable-mbb-elimination
+; O3-WINDOWS-NEXT:     require<live-vars>
+; O3-WINDOWS-NEXT:     require<machine-loops>
+; O3-WINDOWS-NEXT:     phi-node-elimination
+; O3-WINDOWS-NEXT:     two-address-instruction
+; O3-WINDOWS-NEXT:     register-coalescer
+; O3-WINDOWS-NEXT:     rename-independent-subregs
+; O3-WINDOWS-NEXT:     machine-scheduler
+; O3-WINDOWS-NEXT:     greedy<all>
+; O3-WINDOWS-NEXT:     virt-reg-rewriter
+; O3-WINDOWS-NEXT:     stack-slot-coloring
+; O3-WINDOWS-NEXT:     stack-slot-coloring
+; O3-WINDOWS-NEXT:     machine-cp
+; O3-WINDOWS-NEXT:     machinelicm
+; O3-WINDOWS-NEXT:     x86-lower-tile-copy
+; O3-WINDOWS-NEXT:     x86-fp-stackifier
+; O3-WINDOWS-NEXT:     x86-lvi-load
+; O3-WINDOWS-NEXT:     remove-redundant-debug-values
+; O3-WINDOWS-NEXT:     fixup-statepoint-caller-saved
+; O3-WINDOWS-NEXT:     postra-machine-sink
+; O3-WINDOWS-NEXT:     shrink-wrap
+; O3-WINDOWS-NEXT:     prolog-epilog
+; O3-WINDOWS-NEXT:     machine-latecleanup
+; O3-WINDOWS-NEXT:     branch-folder
+; O3-WINDOWS-NEXT:     tailduplication
+; O3-WINDOWS-NEXT:     machine-cp
+; O3-WINDOWS-NEXT:     post-ra-pseudos
+; O3-WINDOWS-NEXT:     x86-expand-pseudo
+; O3-WINDOWS-NEXT:     kcfi
+; O3-WINDOWS-NEXT:     post-RA-sched
+; O3-WINDOWS-NEXT:     block-placement
+; O3-WINDOWS-NEXT:     fentry-insert
+; O3-WINDOWS-NEXT:     xray-instrumentation
+; O3-WINDOWS-NEXT:     patchable-function
+; O3-WINDOWS-NEXT:     break-false-deps
+; O3-WINDOWS-NEXT:     x86-indirect-branch-tracking
+; O3-WINDOWS-NEXT:     x86-insert-vzeroupper
+; O3-WINDOWS-NEXT:     x86-fixup-bw-insts
+; O3-WINDOWS-NEXT:     x86-fixup-leas
+; O3-WINDOWS-NEXT:     x86-fixup-inst-tuning
+; O3-WINDOWS-NEXT:     x86-fixup-inst-tuning
+; O3-WINDOWS-NEXT:     x86-compress-evex
+; O3-WINDOWS-NEXT:     x86-insert-x87-wait
+; O3-WINDOWS-NEXT:     FuncletLayoutPass
+; O3-WINDOWS-NEXT:     remove-loads-into-fake-uses
+; O3-WINDOWS-NEXT:     StackMapLivenessPass
+; O3-WINDOWS-NEXT:     live-debug-values<emit-debug-entry-values>
+; O3-WINDOWS-NEXT:     machine-sanmd
+; O3-WINDOWS-NEXT:     stack-frame-layout
+; O3-WINDOWS-NEXT:     x86-seses
+; O3-WINDOWS-NEXT:     x86-return-thunks
+; O3-WINDOWS-NEXT:     x86-avoid-trailing-call
+; O3-WINDOWS-NEXT:     x86-lvi-ret
+; O3-WINDOWS-NEXT:     x86-wineh-unwindv2
+; O3-WINDOWS-NEXT:     verify
+; O3-WINDOWS-NEXT:     x86-asm-printer
+; O3-WINDOWS-NEXT:   free-machine-function
 ; O3-WINDOWS-NEXT: x86-asm-printer-end
diff --git a/llvm/test/tools/opt/print-pipeline-passes.ll b/llvm/test/tools/opt/print-pipeline-passes.ll
new file mode 100644
index 0000000000000..c6451bafc8301
--- /dev/null
+++ b/llvm/test/tools/opt/print-pipeline-passes.ll
@@ -0,0 +1,13 @@
+; RUN: opt -p 'no-op-module' %s --filetype=null --disable-pipeline-verification --print-pipeline-passes | \
+; RUN: FileCheck %s --check-prefix=TEXT
+
+; RUN: opt -p 'no-op-module,function(no-op-function)' %s --filetype=null \
+; RUN: --disable-pipeline-verification --print-pipeline-passes=tree | \
+; RUN: FileCheck %s --strict-whitespace --match-full-lines --check-prefix=TREE
+
+; TEXT: no-op-module,verify
+
+; TREE:no-op-module
+; TREE-NEXT:function
+; TREE-NEXT:  no-op-function
+; TREE-NEXT:verify
diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp
index 105d2d6eda15f..b50fb3ada22cb 100644
--- a/llvm/tools/llc/NewPMDriver.cpp
+++ b/llvm/tools/llc/NewPMDriver.cpp
@@ -186,7 +186,8 @@ int llvm::compileModuleWithNewPM(
       auto PassName = PIC.getPassNameForClassName(ClassName);
       return PassName.empty() ? ClassName : PassName;
     });
-    outs() << PipelineStr << '\n';
+    printFormattedPipelinePasses(outs(), PipelineStr, *PrintPipelinePasses);
+    outs() << '\n';
     return 0;
   }
 
diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp
index c303048137648..f5007bb7c3571 100644
--- a/llvm/tools/opt/NewPMDriver.cpp
+++ b/llvm/tools/opt/NewPMDriver.cpp
@@ -553,7 +553,7 @@ bool llvm::runPassPipeline(
       auto PassName = PIC.getPassNameForClassName(ClassName);
       return PassName.empty() ? ClassName : PassName;
     });
-    outs() << Pipeline;
+    printFormattedPipelinePasses(outs(), Pipeline, *PrintPipelinePasses);
     outs() << "\n";
 
     if (!DisablePipelineVerification) {



More information about the llvm-commits mailing list