[llvm-branch-commits] [flang] [flang] Add an example plugin exercising the HLFIR pipeline extension points (PR #212196)

Valentin Churavy via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Sep 30 03:12:33 PDT 2026


https://github.com/vchuravy updated https://github.com/llvm/llvm-project/pull/212196

>From 323a51dd33b10fd8fdfe3355e9fa0c29981d220c Mon Sep 17 00:00:00 2001
From: Valentin Churavy <v.churavy at gmail.com>
Date: Sun, 26 Jul 2026 23:53:30 +0200
Subject: [PATCH 1/2] [flang] Add an example plugin exercising the HLFIR
 pipeline extension points

The HLFIR extension points, the pipeline config callback registry and fir-opt's
symbol export all exist to let an out-of-tree MLIR pass run while the HLFIR
intrinsic operations (hlfir.sum, hlfir.matmul, ...) are still present. None of
that was covered end to end, and nothing showed how to use it.

Add flang/examples/HLFIRPipelinePlugin, modelled on PrintFlangFunctionNames. It
contributes a pass that prints the HLFIR operations still present in the module,
tagged with the pipeline position it was inserted at, and exposes it through
both plugin entry points: a static initializer calling
fir::registerPassPipelineConfigCallback for the `flang -fc1 -load` path, and
mlirGetPassPluginInfo so fir-opt can load it with --load-pass-plugin.

Nothing is linked into the shared object; MLIR, FIR and flang symbols resolve
against the host tool, which is what export_executable_symbols_for_plugins on
flang and fir-opt provides.

Two tests use it. Examples/hlfir-pipeline-plugin.f90 covers -emit-fir and
-emit-llvm, so both callback invocation sites, plus a no-plugin negative check.
It checks -O0 and -O2 because at -O0 the intrinsics reach both extension points,
while at -O2 SimplifyHLFIRIntrinsics has expanded them before the Last one -
which is why both points exist. Examples/fir-opt-pass-plugin.fir covers
--load-pass-plugin and the pass showing up in fir-opt's registry.

Co-Authored-By: Claude Opus 5 <noreply at anthropic.com>
---
 flang/docs/FlangDriver.md                     |  17 +++
 flang/examples/CMakeLists.txt                 |   1 +
 .../HLFIRPipelinePlugin/CMakeLists.txt        |  15 +++
 .../HLFIRPipelinePlugin.cpp                   | 111 ++++++++++++++++++
 flang/test/CMakeLists.txt                     |   1 +
 flang/test/Examples/fir-opt-pass-plugin.fir   |  34 ++++++
 flang/test/Examples/hlfir-pipeline-plugin.f90 |  51 ++++++++
 7 files changed, 230 insertions(+)
 create mode 100644 flang/examples/HLFIRPipelinePlugin/CMakeLists.txt
 create mode 100644 flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
 create mode 100644 flang/test/Examples/fir-opt-pass-plugin.fir
 create mode 100644 flang/test/Examples/hlfir-pipeline-plugin.f90

diff --git a/flang/docs/FlangDriver.md b/flang/docs/FlangDriver.md
index d9ecbbc1372bf..3568965b9b770 100644
--- a/flang/docs/FlangDriver.md
+++ b/flang/docs/FlangDriver.md
@@ -590,6 +590,23 @@ These callbacks run on both the `-emit-fir` path
 (`CodeGenAction::generateLLVMIR`), so registering once is enough. The registry
 is append-only and runs callbacks in registration order.
 
+There is an example plugin in `flang/examples/HLFIRPipelinePlugin`, tested by
+`flang/test/Examples/hlfir-pipeline-plugin.f90`.
+
+### Loading MLIR Pass Plugins into `fir-opt`
+
+`fir-opt` is built on `MlirOptMain` and therefore accepts MLIR's
+`--load-pass-plugin` and `--load-dialect-plugin` options. As with `mlir-opt`,
+the plugin resolves the MLIR, FIR and HLFIR symbols it uses against the host
+tool, which therefore has to export them
+(`export_executable_symbols_for_plugins` in
+`flang/tools/fir-opt/CMakeLists.txt`):
+
+```bash
+fir-opt --load-pass-plugin=./MyPasses.so \
+        --pass-pipeline='builtin.module(my-hlfir-pass)' input.fir
+```
+
 ## LLVM Pass Plugins
 
 Pass plugins are dynamic shared objects that consist of one or more LLVM IR
diff --git a/flang/examples/CMakeLists.txt b/flang/examples/CMakeLists.txt
index 746a6f23ae015..c91cfd82aff9e 100644
--- a/flang/examples/CMakeLists.txt
+++ b/flang/examples/CMakeLists.txt
@@ -1,3 +1,4 @@
+add_subdirectory(HLFIRPipelinePlugin)
 add_subdirectory(PrintFlangFunctionNames)
 add_subdirectory(FlangOmpReport)
 add_subdirectory(FeatureList)
diff --git a/flang/examples/HLFIRPipelinePlugin/CMakeLists.txt b/flang/examples/HLFIRPipelinePlugin/CMakeLists.txt
new file mode 100644
index 0000000000000..af46cd87ed077
--- /dev/null
+++ b/flang/examples/HLFIRPipelinePlugin/CMakeLists.txt
@@ -0,0 +1,15 @@
+# TODO: Note that this is currently only available on Linux.
+# On Windows, we would also have to specify e.g. `PLUGIN_TOOL`.
+#
+# Nothing is linked in on purpose: the MLIR, FIR and flang symbols the plugin
+# uses are resolved against the host tool (`flang -fc1` or `fir-opt`) when the
+# shared object is loaded, which is why both export their symbols for plugins.
+add_llvm_example_library(flangHLFIRPipelinePlugin
+    MODULE
+    HLFIRPipelinePlugin.cpp
+
+    DEPENDS
+    acc_gen
+    flangPasses
+    omp_gen
+)
diff --git a/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp b/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
new file mode 100644
index 0000000000000..be93de897cdf8
--- /dev/null
+++ b/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
@@ -0,0 +1,111 @@
+//===-- HLFIRPipelinePlugin.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
+//
+//===----------------------------------------------------------------------===//
+//
+// Example plugin adding an out-of-tree MLIR pass to flang's HLFIR-to-FIR pass
+// pipeline, at the points where the HLFIR intrinsic operations (hlfir.sum,
+// hlfir.matmul, ...) are still present. The pass prints those operations,
+// tagged with the pipeline position it was inserted at.
+//
+// It is exposed through both plugin entry points. For `flang -fc1 -load`, a
+// static initializer calls fir::registerPassPipelineConfigCallback and hooks
+// the pass onto the HLFIROptEarly and HLFIROptLast extension points. For
+// fir-opt, mlirGetPassPluginInfo makes it available to --load-pass-plugin:
+//
+//   fir-opt --load-pass-plugin=./flangHLFIRPipelinePlugin.so \
+//           --pass-pipeline='builtin.module(print-hlfir-intrinsics)'
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Passes/Pipelines.h"
+#include "flang/Tools/CrossToolHelpers.h"
+
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Pass/PassManager.h"
+#include "mlir/Pass/PassRegistry.h"
+#include "mlir/Tools/Plugins/PassPlugin.h"
+
+#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace {
+
+/// Print every HLFIR operation still present in the module, tagged with a
+/// caller-supplied label. Matches on the `hlfir` dialect namespace rather than
+/// a hard-coded op list, so the example does not need to link the HLFIR dialect
+/// library.
+struct PrintHLFIRIntrinsicsPass
+    : public mlir::PassWrapper<PrintHLFIRIntrinsicsPass,
+          mlir::OperationPass<mlir::ModuleOp>> {
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(PrintHLFIRIntrinsicsPass)
+
+  PrintHLFIRIntrinsicsPass() = default;
+  explicit PrintHLFIRIntrinsicsPass(llvm::StringRef labelValue) {
+    label = labelValue.str();
+  }
+  PrintHLFIRIntrinsicsPass(const PrintHLFIRIntrinsicsPass &other)
+      : mlir::PassWrapper<PrintHLFIRIntrinsicsPass,
+            mlir::OperationPass<mlir::ModuleOp>>(other) {
+    label = other.label;
+  }
+
+  llvm::StringRef getArgument() const override {
+    return "print-hlfir-intrinsics";
+  }
+  llvm::StringRef getDescription() const override {
+    return "Print the HLFIR operations that are still present in the module";
+  }
+
+  Option<std::string> label{*this, "label",
+      llvm::cl::desc("Tag prefixed to every printed line, identifying the "
+                     "pipeline position this pass was inserted at"),
+      llvm::cl::init("hlfir")};
+
+  void runOnOperation() override {
+    llvm::outs() << "[" << label << "] begin\n";
+    getOperation().walk([&](mlir::Operation *op) {
+      if (op->getName().getDialectNamespace() == "hlfir") {
+        llvm::outs() << "[" << label << "] " << op->getName().getStringRef()
+                     << "\n";
+      }
+    });
+    llvm::outs() << "[" << label << "] end\n";
+  }
+};
+
+struct FlangPipelineRegistration {
+  FlangPipelineRegistration() {
+    fir::registerPassPipelineConfigCallback(
+        [](MLIRToLLVMPassPipelineConfig &config) {
+          config.registerHLFIROptEarlyEPCallbacks(
+              [](mlir::PassManager &pm, llvm::OptimizationLevel) {
+                pm.addPass(
+                    std::make_unique<PrintHLFIRIntrinsicsPass>("hlfir-early"));
+              });
+          config.registerHLFIROptLastEPCallbacks(
+              [](mlir::PassManager &pm, llvm::OptimizationLevel) {
+                pm.addPass(
+                    std::make_unique<PrintHLFIRIntrinsicsPass>("hlfir-last"));
+              });
+        });
+  }
+};
+
+// The constructor runs when the shared object is loaded, before any compilation
+// starts.
+static FlangPipelineRegistration flangPipelineRegistration;
+
+} // namespace
+
+/// Entry point used by fir-opt's --load-pass-plugin.
+extern "C" LLVM_ATTRIBUTE_WEAK mlir::PassPluginLibraryInfo
+mlirGetPassPluginInfo() {
+  return {MLIR_PLUGIN_API_VERSION, "HLFIRPipelinePlugin", LLVM_VERSION_STRING,
+      []() { mlir::PassRegistration<PrintHLFIRIntrinsicsPass>(); }};
+}
diff --git a/flang/test/CMakeLists.txt b/flang/test/CMakeLists.txt
index 50980a521b241..76e5b0809b31b 100644
--- a/flang/test/CMakeLists.txt
+++ b/flang/test/CMakeLists.txt
@@ -138,6 +138,7 @@ if (LLVM_INCLUDE_EXAMPLES)
     flangPrintFunctionNames
     flangOmpReport
     flangFeatureList
+    flangHLFIRPipelinePlugin
     )
 endif ()
 
diff --git a/flang/test/Examples/fir-opt-pass-plugin.fir b/flang/test/Examples/fir-opt-pass-plugin.fir
new file mode 100644
index 0000000000000..f061ac1678f25
--- /dev/null
+++ b/flang/test/Examples/fir-opt-pass-plugin.fir
@@ -0,0 +1,34 @@
+// Check that fir-opt can load an out-of-tree MLIR pass plugin. This needs
+// fir-opt to export its symbols (export_executable_symbols_for_plugins in
+// flang/tools/fir-opt/CMakeLists.txt); without them the shared object cannot
+// resolve the MLIR and FIR symbols it uses and fails to load.
+
+// REQUIRES: plugins, examples
+// XFAIL: system-aix
+
+// RUN: fir-opt --load-pass-plugin=%llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
+// RUN:   --pass-pipeline='builtin.module(print-hlfir-intrinsics{label=fir-opt})' \
+// RUN:   -o /dev/null %s | FileCheck %s
+
+// The plugin's pass must also show up in fir-opt's pass registry.
+// RUN: fir-opt --load-pass-plugin=%llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
+// RUN:   --help 2>&1 | FileCheck %s --check-prefix=HELP
+
+// CHECK:      [fir-opt] begin
+// CHECK:      [fir-opt] hlfir.matmul
+// CHECK:      [fir-opt] hlfir.sum
+// CHECK:      [fir-opt] end
+
+// HELP: --print-hlfir-intrinsics
+
+func.func @test_hlfir_intrinsics(%a: !fir.ref<!fir.array<3x3xf32>>,
+                                 %b: !fir.ref<!fir.array<3x3xf32>>,
+                                 %c: !fir.ref<!fir.array<3x3xf32>>,
+                                 %s: !fir.ref<f32>) {
+  %0 = hlfir.matmul %a %b : (!fir.ref<!fir.array<3x3xf32>>, !fir.ref<!fir.array<3x3xf32>>) -> !hlfir.expr<3x3xf32>
+  hlfir.assign %0 to %c : !hlfir.expr<3x3xf32>, !fir.ref<!fir.array<3x3xf32>>
+  hlfir.destroy %0 : !hlfir.expr<3x3xf32>
+  %1 = hlfir.sum %a : (!fir.ref<!fir.array<3x3xf32>>) -> f32
+  hlfir.assign %1 to %s : f32, !fir.ref<f32>
+  return
+}
diff --git a/flang/test/Examples/hlfir-pipeline-plugin.f90 b/flang/test/Examples/hlfir-pipeline-plugin.f90
new file mode 100644
index 0000000000000..4958a9a9538ac
--- /dev/null
+++ b/flang/test/Examples/hlfir-pipeline-plugin.f90
@@ -0,0 +1,51 @@
+! Check that a plugin loaded with `flang -fc1 -load` can insert MLIR passes into
+! the HLFIR-to-FIR pass pipeline through the HLFIR extension points.
+
+! REQUIRES: plugins, examples
+! XFAIL: system-aix
+
+! At -O0 no HLFIR simplification runs, so the intrinsics reach both extension
+! points. -emit-fir exercises CodeGenAction::lowerHLFIRToFIR.
+! RUN: %flang_fc1 -load %llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
+! RUN:   -emit-fir -o /dev/null %s 2>&1 | FileCheck %s
+
+! The same callbacks must fire on the -emit-llvm path, which builds its own
+! config in CodeGenAction::generateLLVMIR.
+! RUN: %flang_fc1 -load %llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
+! RUN:   -emit-llvm -o /dev/null %s 2>&1 | FileCheck %s
+
+! At -O2 SimplifyHLFIRIntrinsics expands the intrinsics before the Last
+! extension point, which is why both extension points exist.
+! RUN: %flang_fc1 -load %llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
+! RUN:   -O2 -emit-fir -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=O2
+
+! Without the plugin nothing is printed.
+! RUN: %flang_fc1 -emit-fir -o /dev/null %s 2>&1 \
+! RUN:   | FileCheck %s --check-prefix=NOPLUGIN --allow-empty
+
+! CHECK:      [hlfir-early] begin
+! CHECK:      [hlfir-early] hlfir.matmul
+! CHECK:      [hlfir-early] hlfir.sum
+! CHECK:      [hlfir-early] end
+! CHECK:      [hlfir-last] begin
+! CHECK:      [hlfir-last] hlfir.matmul
+! CHECK:      [hlfir-last] hlfir.sum
+! CHECK:      [hlfir-last] end
+
+! O2:      [hlfir-early] begin
+! O2:      [hlfir-early] hlfir.matmul
+! O2:      [hlfir-early] hlfir.sum
+! O2:      [hlfir-early] end
+! O2:      [hlfir-last] begin
+! O2-NOT:  hlfir.matmul
+! O2-NOT:  hlfir.sum
+! O2:      [hlfir-last] end
+
+! NOPLUGIN-NOT: hlfir-early
+! NOPLUGIN-NOT: hlfir-last
+
+subroutine test_hlfir_intrinsics(a, b, c, s)
+  real :: a(3,3), b(3,3), c(3,3), s
+  c = matmul(a, b)
+  s = sum(a)
+end subroutine

>From 7466b2fff494d83d45ae7976bde5bdc626dc79c5 Mon Sep 17 00:00:00 2001
From: Valentin Churavy <v.churavy at gmail.com>
Date: Wed, 30 Sep 2026 12:10:06 +0200
Subject: [PATCH 2/2] [flang] Address review comments on the HLFIR pipeline
 example plugin

- Rename the pass to print-hlfir-ops: it prints every hlfir op, not only the
  intrinsics.
- Drop the redundant option copy in the copy constructor; Pass::clone copies
  option values.
- Tests: drop the no-plugin run, which could not fail, and at -O2 only check
  that both extension points are reached rather than what
  SimplifyHLFIRIntrinsics chose to expand.

Assisted-by: Claude Code (Opus 5.5)
---
 .../HLFIRPipelinePlugin.cpp                   | 41 ++++++++-----------
 flang/test/Examples/fir-opt-pass-plugin.fir   |  4 +-
 flang/test/Examples/hlfir-pipeline-plugin.f90 | 12 +-----
 3 files changed, 21 insertions(+), 36 deletions(-)

diff --git a/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp b/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
index be93de897cdf8..283d069ceac29 100644
--- a/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
+++ b/flang/examples/HLFIRPipelinePlugin/HLFIRPipelinePlugin.cpp
@@ -7,9 +7,10 @@
 //===----------------------------------------------------------------------===//
 //
 // Example plugin adding an out-of-tree MLIR pass to flang's HLFIR-to-FIR pass
-// pipeline, at the points where the HLFIR intrinsic operations (hlfir.sum,
-// hlfir.matmul, ...) are still present. The pass prints those operations,
-// tagged with the pipeline position it was inserted at.
+// pipeline, at the points where the module is still in HLFIR, including the
+// intrinsic operations (hlfir.sum, hlfir.matmul, ...). The pass prints the
+// HLFIR operations it finds, tagged with the pipeline position it was inserted
+// at.
 //
 // It is exposed through both plugin entry points. For `flang -fc1 -load`, a
 // static initializer calls fir::registerPassPipelineConfigCallback and hooks
@@ -17,7 +18,7 @@
 // fir-opt, mlirGetPassPluginInfo makes it available to --load-pass-plugin:
 //
 //   fir-opt --load-pass-plugin=./flangHLFIRPipelinePlugin.so \
-//           --pass-pipeline='builtin.module(print-hlfir-intrinsics)'
+//           --pass-pipeline='builtin.module(print-hlfir-ops)'
 //
 //===----------------------------------------------------------------------===//
 
@@ -40,24 +41,20 @@ namespace {
 /// caller-supplied label. Matches on the `hlfir` dialect namespace rather than
 /// a hard-coded op list, so the example does not need to link the HLFIR dialect
 /// library.
-struct PrintHLFIRIntrinsicsPass
-    : public mlir::PassWrapper<PrintHLFIRIntrinsicsPass,
-          mlir::OperationPass<mlir::ModuleOp>> {
-  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(PrintHLFIRIntrinsicsPass)
+struct PrintHLFIROpsPass : public mlir::PassWrapper<PrintHLFIROpsPass,
+                               mlir::OperationPass<mlir::ModuleOp>> {
+  MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(PrintHLFIROpsPass)
 
-  PrintHLFIRIntrinsicsPass() = default;
-  explicit PrintHLFIRIntrinsicsPass(llvm::StringRef labelValue) {
+  PrintHLFIROpsPass() = default;
+  explicit PrintHLFIROpsPass(llvm::StringRef labelValue) {
     label = labelValue.str();
   }
-  PrintHLFIRIntrinsicsPass(const PrintHLFIRIntrinsicsPass &other)
-      : mlir::PassWrapper<PrintHLFIRIntrinsicsPass,
-            mlir::OperationPass<mlir::ModuleOp>>(other) {
-    label = other.label;
-  }
+  // Options are not copyable; Pass::clone copies their values afterwards.
+  PrintHLFIROpsPass(const PrintHLFIROpsPass &other)
+      : mlir::PassWrapper<PrintHLFIROpsPass,
+            mlir::OperationPass<mlir::ModuleOp>>(other) {}
 
-  llvm::StringRef getArgument() const override {
-    return "print-hlfir-intrinsics";
-  }
+  llvm::StringRef getArgument() const override { return "print-hlfir-ops"; }
   llvm::StringRef getDescription() const override {
     return "Print the HLFIR operations that are still present in the module";
   }
@@ -85,13 +82,11 @@ struct FlangPipelineRegistration {
         [](MLIRToLLVMPassPipelineConfig &config) {
           config.registerHLFIROptEarlyEPCallbacks(
               [](mlir::PassManager &pm, llvm::OptimizationLevel) {
-                pm.addPass(
-                    std::make_unique<PrintHLFIRIntrinsicsPass>("hlfir-early"));
+                pm.addPass(std::make_unique<PrintHLFIROpsPass>("hlfir-early"));
               });
           config.registerHLFIROptLastEPCallbacks(
               [](mlir::PassManager &pm, llvm::OptimizationLevel) {
-                pm.addPass(
-                    std::make_unique<PrintHLFIRIntrinsicsPass>("hlfir-last"));
+                pm.addPass(std::make_unique<PrintHLFIROpsPass>("hlfir-last"));
               });
         });
   }
@@ -107,5 +102,5 @@ static FlangPipelineRegistration flangPipelineRegistration;
 extern "C" LLVM_ATTRIBUTE_WEAK mlir::PassPluginLibraryInfo
 mlirGetPassPluginInfo() {
   return {MLIR_PLUGIN_API_VERSION, "HLFIRPipelinePlugin", LLVM_VERSION_STRING,
-      []() { mlir::PassRegistration<PrintHLFIRIntrinsicsPass>(); }};
+      []() { mlir::PassRegistration<PrintHLFIROpsPass>(); }};
 }
diff --git a/flang/test/Examples/fir-opt-pass-plugin.fir b/flang/test/Examples/fir-opt-pass-plugin.fir
index f061ac1678f25..248c19210c6b5 100644
--- a/flang/test/Examples/fir-opt-pass-plugin.fir
+++ b/flang/test/Examples/fir-opt-pass-plugin.fir
@@ -7,7 +7,7 @@
 // XFAIL: system-aix
 
 // RUN: fir-opt --load-pass-plugin=%llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
-// RUN:   --pass-pipeline='builtin.module(print-hlfir-intrinsics{label=fir-opt})' \
+// RUN:   --pass-pipeline='builtin.module(print-hlfir-ops{label=fir-opt})' \
 // RUN:   -o /dev/null %s | FileCheck %s
 
 // The plugin's pass must also show up in fir-opt's pass registry.
@@ -19,7 +19,7 @@
 // CHECK:      [fir-opt] hlfir.sum
 // CHECK:      [fir-opt] end
 
-// HELP: --print-hlfir-intrinsics
+// HELP: --print-hlfir-ops
 
 func.func @test_hlfir_intrinsics(%a: !fir.ref<!fir.array<3x3xf32>>,
                                  %b: !fir.ref<!fir.array<3x3xf32>>,
diff --git a/flang/test/Examples/hlfir-pipeline-plugin.f90 b/flang/test/Examples/hlfir-pipeline-plugin.f90
index 4958a9a9538ac..1051f2a112694 100644
--- a/flang/test/Examples/hlfir-pipeline-plugin.f90
+++ b/flang/test/Examples/hlfir-pipeline-plugin.f90
@@ -14,15 +14,10 @@
 ! RUN: %flang_fc1 -load %llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
 ! RUN:   -emit-llvm -o /dev/null %s 2>&1 | FileCheck %s
 
-! At -O2 SimplifyHLFIRIntrinsics expands the intrinsics before the Last
-! extension point, which is why both extension points exist.
+! Both extension points are also reached with the optimizing pipeline.
 ! RUN: %flang_fc1 -load %llvmshlibdir/flangHLFIRPipelinePlugin%pluginext \
 ! RUN:   -O2 -emit-fir -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=O2
 
-! Without the plugin nothing is printed.
-! RUN: %flang_fc1 -emit-fir -o /dev/null %s 2>&1 \
-! RUN:   | FileCheck %s --check-prefix=NOPLUGIN --allow-empty
-
 ! CHECK:      [hlfir-early] begin
 ! CHECK:      [hlfir-early] hlfir.matmul
 ! CHECK:      [hlfir-early] hlfir.sum
@@ -37,13 +32,8 @@
 ! O2:      [hlfir-early] hlfir.sum
 ! O2:      [hlfir-early] end
 ! O2:      [hlfir-last] begin
-! O2-NOT:  hlfir.matmul
-! O2-NOT:  hlfir.sum
 ! O2:      [hlfir-last] end
 
-! NOPLUGIN-NOT: hlfir-early
-! NOPLUGIN-NOT: hlfir-last
-
 subroutine test_hlfir_intrinsics(a, b, c, s)
   real :: a(3,3), b(3,3), c(3,3), s
   c = matmul(a, b)



More information about the llvm-branch-commits mailing list