[clang] [CIR] Intitial upstreaming of LibOpt pass (PR #172487)
Hendrik Hübner via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 15 05:51:06 PST 2026
https://github.com/HendrikHuebner updated https://github.com/llvm/llvm-project/pull/172487
>From c759e5602647b21cb189e863fdb1a7889c139dae Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Tue, 16 Dec 2025 15:50:20 +0100
Subject: [PATCH 1/5] libopt
---
clang/include/clang/CIR/CIRToCIRPasses.h | 3 +-
clang/include/clang/CIR/Dialect/Passes.h | 2 +
clang/include/clang/CIR/Dialect/Passes.td | 19 +++
.../include/clang/Frontend/FrontendOptions.h | 3 +
clang/include/clang/Options/Options.td | 9 +-
.../lib/CIR/Dialect/Transforms/CMakeLists.txt | 1 +
clang/lib/CIR/Dialect/Transforms/LibOpt.cpp | 108 ++++++++++++++++++
clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 5 +-
clang/lib/CIR/Lowering/CIRPasses.cpp | 16 ++-
clang/test/CIR/Transforms/lib-opt.cpp | 3 +
10 files changed, 165 insertions(+), 4 deletions(-)
create mode 100644 clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
create mode 100644 clang/test/CIR/Transforms/lib-opt.cpp
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index 4a23790ee8b76..ed82fe4477e82 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -33,7 +33,8 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
mlir::MLIRContext &mlirCtx,
clang::ASTContext &astCtx,
bool enableVerifier,
- bool enableCIRSimplify);
+ bool enableCIRSimplify,
+ llvm::StringRef libOptOptions);
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h
index 161f365bb1402..6d597b7f325ec 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -30,6 +30,8 @@ std::unique_ptr<Pass> createHoistAllocasPass();
std::unique_ptr<Pass> createLoweringPreparePass();
std::unique_ptr<Pass> createLoweringPreparePass(clang::ASTContext *astCtx);
std::unique_ptr<Pass> createGotoSolverPass();
+std::unique_ptr<Pass> createLibOptPass();
+std::unique_ptr<Pass> createLibOptPass(clang::ASTContext *astCtx);
void populateCIRPreLoweringPasses(mlir::OpPassManager &pm);
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index ef5308ffffd19..e5c8e94f79aa8 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -161,4 +161,23 @@ def LoweringPrepare : Pass<"cir-lowering-prepare"> {
let dependentDialects = ["cir::CIRDialect"];
}
+def LibOpt : Pass<"cir-lib-opt"> {
+ let summary = "Optimize C/C++ library calls";
+ let description = [{
+ By using higher level information from `cir-idiom-recognize`, this pass
+ apply transformations to CIR based on specific C/C++ library semantics.
+
+ Transformations done by this pass can be inspected by users by using
+ remarks. Currently supported are `all` and `transforms`.
+ }];
+ let constructor = "mlir::createLibOptPass()";
+ let dependentDialects = ["cir::CIRDialect"];
+
+ let options = [
+ ListOption<"remarksList", "remarks", "std::string",
+ "Diagnostic remarks to enable"
+ " Supported styles: {all|transforms}", "llvm::cl::ZeroOrMore">,
+ ];
+}
+
#endif // CLANG_CIR_DIALECT_PASSES_TD
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index ba7da56cb9fce..6cee55f09c47d 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -422,6 +422,9 @@ class FrontendOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned ClangIRDisableCIRVerifier : 1;
+ // Options to control ClangIR library optimization
+ std::string clangIRLibOptOptions;
+
CodeCompleteOptions CodeCompleteOpts;
/// Specifies the output format of the AST.
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index a274017953b1d..034e472f8248e 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3252,7 +3252,14 @@ def clangir_disable_verifier : Flag<["-"], "clangir-disable-verifier">,
Visibility<[ClangOption, CC1Option]>,
HelpText<"ClangIR: Disable MLIR module verifier">,
MarshallingInfoFlag<FrontendOpts<"ClangIRDisableCIRVerifier">>;
-
+def fclangir_lib_opt_EQ : Joined<["-"], "fclangir-lib-opt=">,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+ HelpText<"Enable C/C++ library based optimizations (with options)">,
+ MarshallingInfoString<FrontendOpts<"clangIRLibOptOptions">>;
+def fclangir_lib_opt : Flag<["-"], "fclangir-lib-opt">,
+ Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
+ Alias<fclangir_lib_opt_EQ>, AliasArgs<[""]>,
+ HelpText<"Enable C/C++ library based optimizations">;
defm clangir : BoolFOption<"clangir",
FrontendOpts<"UseClangIRPipeline">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
diff --git a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
index 1ace2d8634b40..ab6022841146e 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -9,6 +9,7 @@ add_clang_library(MLIRCIRTransforms
HoistAllocas.cpp
LoweringPrepare.cpp
GotoSolver.cpp
+ LibOpt.cpp
DEPENDS
MLIRCIRPassIncGen
diff --git a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
new file mode 100644
index 0000000000000..6b75d961ce4b0
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
@@ -0,0 +1,108 @@
+//===- LibOpt.cpp - Optimize CIR raised C/C++ library idioms --------------===//
+//
+// 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 pass optimizes C/C++ standard library idioms in Clang IR.
+//
+//===----------------------------------------------------------------------===//
+
+#include "PassDetail.h"
+#include "mlir/Dialect/Func/IR/FuncOps.h"
+#include "mlir/IR/BuiltinAttributes.h"
+#include "mlir/IR/Region.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Mangle.h"
+#include "clang/Basic/Module.h"
+#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+#include "clang/CIR/Dialect/Passes.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Path.h"
+
+using cir::CIRBaseBuilderTy;
+using namespace mlir;
+using namespace cir;
+
+namespace mlir {
+#define GEN_PASS_DEF_LIBOPT
+#include "clang/CIR/Dialect/Passes.h.inc"
+} // namespace mlir
+
+namespace {
+
+struct LibOptPass : public impl::LibOptBase<LibOptPass> {
+ LibOptPass() = default;
+ void runOnOperation() override;
+
+ class PassOptions {
+ enum : unsigned {
+ None = 0,
+ RemarkTransforms = 1,
+ RemarkAll = 1 << 1,
+ };
+
+ public:
+ void parseOption(const llvm::StringRef remark) {
+ value |= StringSwitch<unsigned>(remark)
+ .Case("transforms", RemarkTransforms)
+ .Case("all", RemarkAll)
+ .Default(None);
+ }
+
+ void parseOptions(LibOptPass &pass) {
+ if (isOptionsParsed)
+ return;
+
+ for (const llvm::StringRef &remark : pass.remarksList)
+ parseOption(remark);
+
+ isOptionsParsed = true;
+ }
+
+ bool emitRemarkAll() { return value & RemarkAll; }
+ bool emitRemarkTransforms() {
+ return emitRemarkAll() || value & RemarkTransforms;
+ }
+
+ private:
+ unsigned value = None;
+ bool isOptionsParsed = false;
+ };
+
+ PassOptions passOptions;
+
+ ///
+ /// AST related
+ /// -----------
+ clang::ASTContext *astCtx;
+ void setASTContext(clang::ASTContext *c) { astCtx = c; }
+
+ /// Tracks current module.
+ ModuleOp theModule;
+};
+} // namespace
+
+void LibOptPass::runOnOperation() {
+ passOptions.parseOptions(*this);
+ auto *op = getOperation();
+ if (isa<::mlir::ModuleOp>(op))
+ theModule = cast<::mlir::ModuleOp>(op);
+}
+
+std::unique_ptr<Pass> mlir::createLibOptPass() {
+ return std::make_unique<LibOptPass>();
+}
+
+std::unique_ptr<Pass> mlir::createLibOptPass(clang::ASTContext *astCtx) {
+ auto pass = std::make_unique<LibOptPass>();
+ pass->setASTContext(astCtx);
+ return std::move(pass);
+}
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index daec8ae409e0f..136719862925b 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -113,11 +113,14 @@ class CIRGenConsumer : public clang::ASTConsumer {
mlir::ModuleOp MlirModule = Gen->getModule();
mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
+
if (!FEOptions.ClangIRDisablePasses) {
+ std::string libOptOptions = FEOptions.clangIRLibOptOptions;
+
// Setup and run CIR pipeline.
if (runCIRToCIRPasses(MlirModule, MlirCtx, C,
!FEOptions.ClangIRDisableCIRVerifier,
- CGO.OptimizationLevel > 0)
+ CGO.OptimizationLevel > 0, libOptOptions)
.failed()) {
CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
return;
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 589c2c524c305..372aa02ff0ecc 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -21,16 +21,30 @@ mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
mlir::MLIRContext &mlirContext,
clang::ASTContext &astContext,
bool enableVerifier,
- bool enableCIRSimplify) {
+ bool enableCIRSimplify,
+ llvm::StringRef libOptOptions) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
+ // TODO(CIR): Make this actually propagate errors correctly. This is stubbed
+ // in to get rebases going.
+
+ auto errorHandler = [](const llvm::Twine &) -> mlir::LogicalResult {
+ return mlir::LogicalResult::failure();
+ };
+
mlir::PassManager pm(&mlirContext);
pm.addPass(mlir::createCIRCanonicalizePass());
if (enableCIRSimplify)
pm.addPass(mlir::createCIRSimplifyPass());
+ auto libOptPass = mlir::createLibOptPass();
+ if (libOptPass->initializeOptions(libOptOptions, errorHandler).failed()) {
+ return mlir::failure();
+ }
+
+ pm.addPass(std::move(libOptPass));
pm.addPass(mlir::createTargetLoweringPass());
pm.addPass(mlir::createCXXABILoweringPass());
pm.addPass(mlir::createLoweringPreparePass(&astContext));
diff --git a/clang/test/CIR/Transforms/lib-opt.cpp b/clang/test/CIR/Transforms/lib-opt.cpp
new file mode 100644
index 0000000000000..ea4c265a1a584
--- /dev/null
+++ b/clang/test/CIR/Transforms/lib-opt.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fclangir -emit-cir -mmlir --mlir-print-ir-after-all %s -o - 2>&1 | FileCheck %s -check-prefix=CIR
+
+// CIR: IR Dump After LibOpt (cir-lib-opt)
>From 9ba6a0ccc881e00c4e9352ec1d6a3d8a963b6d12 Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Fri, 19 Dec 2025 18:11:38 +0100
Subject: [PATCH 2/5] formatting
---
clang/include/clang/CIR/CIRToCIRPasses.h | 10 ++++------
clang/include/clang/CIR/Dialect/Passes.td | 6 ++++--
clang/lib/CIR/Dialect/Transforms/LibOpt.cpp | 2 +-
clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 1 -
clang/lib/CIR/Lowering/CIRPasses.cpp | 10 ++++------
5 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index ed82fe4477e82..9927a7a5ae726 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -29,12 +29,10 @@ class ModuleOp;
namespace cir {
// Run set of cleanup/prepare/etc passes CIR <-> CIR.
-mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
- mlir::MLIRContext &mlirCtx,
- clang::ASTContext &astCtx,
- bool enableVerifier,
- bool enableCIRSimplify,
- llvm::StringRef libOptOptions);
+mlir::LogicalResult
+runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx,
+ clang::ASTContext &astCtx, bool enableVerifier,
+ bool enableCIRSimplify, llvm::StringRef libOptOptions);
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index e5c8e94f79aa8..210105baa6589 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -164,12 +164,14 @@ def LoweringPrepare : Pass<"cir-lowering-prepare"> {
def LibOpt : Pass<"cir-lib-opt"> {
let summary = "Optimize C/C++ library calls";
let description = [{
- By using higher level information from `cir-idiom-recognize`, this pass
- apply transformations to CIR based on specific C/C++ library semantics.
+ This pass applies transformations on C/C++ standard library idioms,
+ such as library function calls and structs raised to CIR operations
+ using the `cir-idiom-recognize` pass.
Transformations done by this pass can be inspected by users by using
remarks. Currently supported are `all` and `transforms`.
}];
+
let constructor = "mlir::createLibOptPass()";
let dependentDialects = ["cir::CIRDialect"];
diff --git a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
index 6b75d961ce4b0..8f4e80fba33d6 100644
--- a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
@@ -61,7 +61,7 @@ struct LibOptPass : public impl::LibOptBase<LibOptPass> {
if (isOptionsParsed)
return;
- for (const llvm::StringRef &remark : pass.remarksList)
+ for (const llvm::StringRef remark : pass.remarksList)
parseOption(remark);
isOptionsParsed = true;
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 136719862925b..e3d1b3f805909 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -113,7 +113,6 @@ class CIRGenConsumer : public clang::ASTConsumer {
mlir::ModuleOp MlirModule = Gen->getModule();
mlir::MLIRContext &MlirCtx = Gen->getMLIRContext();
-
if (!FEOptions.ClangIRDisablePasses) {
std::string libOptOptions = FEOptions.clangIRLibOptOptions;
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 372aa02ff0ecc..2682950c7ddb8 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -17,12 +17,10 @@
#include "llvm/Support/TimeProfiler.h"
namespace cir {
-mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
- mlir::MLIRContext &mlirContext,
- clang::ASTContext &astContext,
- bool enableVerifier,
- bool enableCIRSimplify,
- llvm::StringRef libOptOptions) {
+mlir::LogicalResult
+runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
+ clang::ASTContext &astContext, bool enableVerifier,
+ bool enableCIRSimplify, llvm::StringRef libOptOptions) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
>From 02656a96b236f5b2650d349f08b91f900c6ac893 Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Sun, 15 Feb 2026 14:12:21 +0100
Subject: [PATCH 3/5] feedback
---
clang/include/clang/CIR/CIRToCIRPasses.h | 3 ++-
clang/include/clang/CIR/Dialect/Passes.td | 9 ---------
clang/include/clang/Frontend/FrontendOptions.h | 8 ++++++--
clang/include/clang/Options/Options.td | 6 ++++++
clang/lib/CIR/Dialect/Transforms/LibOpt.cpp | 13 ++-----------
clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 1 +
clang/lib/CIR/Lowering/CIRPasses.cpp | 14 +++++++++-----
clang/test/CIR/Transforms/lib-opt.cpp | 2 +-
8 files changed, 27 insertions(+), 29 deletions(-)
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index 9927a7a5ae726..13e5e4c3fa9bc 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -32,7 +32,8 @@ namespace cir {
mlir::LogicalResult
runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx,
clang::ASTContext &astCtx, bool enableVerifier,
- bool enableCIRSimplify, llvm::StringRef libOptOptions);
+ bool enableLibOpt, bool enableCIRSimplify,
+ llvm::StringRef libOptOptions);
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index 210105baa6589..e79b95bad6f0f 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -167,19 +167,10 @@ def LibOpt : Pass<"cir-lib-opt"> {
This pass applies transformations on C/C++ standard library idioms,
such as library function calls and structs raised to CIR operations
using the `cir-idiom-recognize` pass.
-
- Transformations done by this pass can be inspected by users by using
- remarks. Currently supported are `all` and `transforms`.
}];
let constructor = "mlir::createLibOptPass()";
let dependentDialects = ["cir::CIRDialect"];
-
- let options = [
- ListOption<"remarksList", "remarks", "std::string",
- "Diagnostic remarks to enable"
- " Supported styles: {all|transforms}", "llvm::cl::ZeroOrMore">,
- ];
}
#endif // CLANG_CIR_DIALECT_PASSES_TD
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index 6cee55f09c47d..ef4920fd9df48 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -422,6 +422,10 @@ class FrontendOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned ClangIRDisableCIRVerifier : 1;
+ /// Disable Clang IR (CIR) library optimizations
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned ClangIREnableLibOpt : 1;
+
// Options to control ClangIR library optimization
std::string clangIRLibOptOptions;
@@ -555,8 +559,8 @@ class FrontendOptions {
EmitSymbolGraphSymbolLabelsForTesting(false),
EmitPrettySymbolGraphs(false), GenReducedBMI(false),
UseClangIRPipeline(false), ClangIRDisablePasses(false),
- ClangIRDisableCIRVerifier(false), TimeTraceGranularity(500),
- TimeTraceVerbose(false) {}
+ ClangIRDisableCIRVerifier(false), ClangIREnableLibOpt(false),
+ TimeTraceGranularity(500), TimeTraceVerbose(false) {}
/// getInputKindForExtension - Return the appropriate input kind for a file
/// extension. For example, "c" would return Language::C.
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 034e472f8248e..d670f57348d31 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3252,6 +3252,12 @@ def clangir_disable_verifier : Flag<["-"], "clangir-disable-verifier">,
Visibility<[ClangOption, CC1Option]>,
HelpText<"ClangIR: Disable MLIR module verifier">,
MarshallingInfoFlag<FrontendOpts<"ClangIRDisableCIRVerifier">>;
+
+def clangir_enable_libopt : Flag<["-"], "clangir-enable-libopt">,
+ Visibility<[ClangOption, CC1Option]>,
+ HelpText<"ClangIR: Enable Library Optimizations">,
+ MarshallingInfoFlag<FrontendOpts<"ClangIREnableLibOpt">>;
+
def fclangir_lib_opt_EQ : Joined<["-"], "fclangir-lib-opt=">,
Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
HelpText<"Enable C/C++ library based optimizations (with options)">,
diff --git a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
index 8f4e80fba33d6..f8ac351a6d1b5 100644
--- a/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
+++ b/clang/lib/CIR/Dialect/Transforms/LibOpt.cpp
@@ -58,13 +58,7 @@ struct LibOptPass : public impl::LibOptBase<LibOptPass> {
}
void parseOptions(LibOptPass &pass) {
- if (isOptionsParsed)
- return;
-
- for (const llvm::StringRef remark : pass.remarksList)
- parseOption(remark);
-
- isOptionsParsed = true;
+ // To be implemented
}
bool emitRemarkAll() { return value & RemarkAll; }
@@ -74,14 +68,11 @@ struct LibOptPass : public impl::LibOptBase<LibOptPass> {
private:
unsigned value = None;
- bool isOptionsParsed = false;
};
PassOptions passOptions;
- ///
- /// AST related
- /// -----------
+ // For now the AST Context is optional for this pass.
clang::ASTContext *astCtx;
void setASTContext(clang::ASTContext *c) { astCtx = c; }
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index e3d1b3f805909..7d6ff2f79bb2f 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -119,6 +119,7 @@ class CIRGenConsumer : public clang::ASTConsumer {
// Setup and run CIR pipeline.
if (runCIRToCIRPasses(MlirModule, MlirCtx, C,
!FEOptions.ClangIRDisableCIRVerifier,
+ FEOptions.ClangIREnableLibOpt,
CGO.OptimizationLevel > 0, libOptOptions)
.failed()) {
CI.getDiagnostics().Report(diag::err_cir_to_cir_transform_failed);
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 2682950c7ddb8..349f7446eeaa5 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -20,7 +20,8 @@ namespace cir {
mlir::LogicalResult
runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
clang::ASTContext &astContext, bool enableVerifier,
- bool enableCIRSimplify, llvm::StringRef libOptOptions) {
+ bool enableLibOpt, bool enableCIRSimplify,
+ llvm::StringRef libOptOptions) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
@@ -37,12 +38,15 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
if (enableCIRSimplify)
pm.addPass(mlir::createCIRSimplifyPass());
- auto libOptPass = mlir::createLibOptPass();
- if (libOptPass->initializeOptions(libOptOptions, errorHandler).failed()) {
- return mlir::failure();
+ if (enableLibOpt) {
+ auto libOptPass = mlir::createLibOptPass();
+ if (libOptPass->initializeOptions(libOptOptions, errorHandler).failed()) {
+ return mlir::failure();
+ }
+
+ pm.addPass(std::move(libOptPass));
}
- pm.addPass(std::move(libOptPass));
pm.addPass(mlir::createTargetLoweringPass());
pm.addPass(mlir::createCXXABILoweringPass());
pm.addPass(mlir::createLoweringPreparePass(&astContext));
diff --git a/clang/test/CIR/Transforms/lib-opt.cpp b/clang/test/CIR/Transforms/lib-opt.cpp
index ea4c265a1a584..b2ba0ca8206cc 100644
--- a/clang/test/CIR/Transforms/lib-opt.cpp
+++ b/clang/test/CIR/Transforms/lib-opt.cpp
@@ -1,3 +1,3 @@
-// RUN: %clang_cc1 -fclangir -emit-cir -mmlir --mlir-print-ir-after-all %s -o - 2>&1 | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -fclangir -emit-cir -mmlir --mlir-print-ir-after-all -clangir-enable-libopt %s -o - 2>&1 | FileCheck %s -check-prefix=CIR
// CIR: IR Dump After LibOpt (cir-lib-opt)
>From 1b9339f183f73d630ea22ba5cf06ee2b4a81df63 Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Sun, 15 Feb 2026 14:12:35 +0100
Subject: [PATCH 4/5] fmt
---
clang/include/clang/CIR/CIRToCIRPasses.h | 11 ++++++-----
clang/lib/CIR/Lowering/CIRPasses.cpp | 11 ++++++-----
2 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index 13e5e4c3fa9bc..958b53ca36179 100644
--- a/clang/include/clang/CIR/CIRToCIRPasses.h
+++ b/clang/include/clang/CIR/CIRToCIRPasses.h
@@ -29,11 +29,12 @@ class ModuleOp;
namespace cir {
// Run set of cleanup/prepare/etc passes CIR <-> CIR.
-mlir::LogicalResult
-runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirCtx,
- clang::ASTContext &astCtx, bool enableVerifier,
- bool enableLibOpt, bool enableCIRSimplify,
- llvm::StringRef libOptOptions);
+mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
+ mlir::MLIRContext &mlirCtx,
+ clang::ASTContext &astCtx,
+ bool enableVerifier, bool enableLibOpt,
+ bool enableCIRSimplify,
+ llvm::StringRef libOptOptions);
} // namespace cir
diff --git a/clang/lib/CIR/Lowering/CIRPasses.cpp b/clang/lib/CIR/Lowering/CIRPasses.cpp
index 349f7446eeaa5..9fa69ae1445d0 100644
--- a/clang/lib/CIR/Lowering/CIRPasses.cpp
+++ b/clang/lib/CIR/Lowering/CIRPasses.cpp
@@ -17,11 +17,12 @@
#include "llvm/Support/TimeProfiler.h"
namespace cir {
-mlir::LogicalResult
-runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
- clang::ASTContext &astContext, bool enableVerifier,
- bool enableLibOpt, bool enableCIRSimplify,
- llvm::StringRef libOptOptions) {
+mlir::LogicalResult runCIRToCIRPasses(mlir::ModuleOp theModule,
+ mlir::MLIRContext &mlirContext,
+ clang::ASTContext &astContext,
+ bool enableVerifier, bool enableLibOpt,
+ bool enableCIRSimplify,
+ llvm::StringRef libOptOptions) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
>From 1360d37ca0487e412915f134649da72f3e26007e Mon Sep 17 00:00:00 2001
From: hhuebner <hendrik.huebner18 at gmail.com>
Date: Sun, 15 Feb 2026 14:50:52 +0100
Subject: [PATCH 5/5] deduplicate arg
---
clang/include/clang/Options/Options.td | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index d670f57348d31..a274017953b1d 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3253,19 +3253,6 @@ def clangir_disable_verifier : Flag<["-"], "clangir-disable-verifier">,
HelpText<"ClangIR: Disable MLIR module verifier">,
MarshallingInfoFlag<FrontendOpts<"ClangIRDisableCIRVerifier">>;
-def clangir_enable_libopt : Flag<["-"], "clangir-enable-libopt">,
- Visibility<[ClangOption, CC1Option]>,
- HelpText<"ClangIR: Enable Library Optimizations">,
- MarshallingInfoFlag<FrontendOpts<"ClangIREnableLibOpt">>;
-
-def fclangir_lib_opt_EQ : Joined<["-"], "fclangir-lib-opt=">,
- Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
- HelpText<"Enable C/C++ library based optimizations (with options)">,
- MarshallingInfoString<FrontendOpts<"clangIRLibOptOptions">>;
-def fclangir_lib_opt : Flag<["-"], "fclangir-lib-opt">,
- Visibility<[ClangOption, CC1Option]>, Group<f_Group>,
- Alias<fclangir_lib_opt_EQ>, AliasArgs<[""]>,
- HelpText<"Enable C/C++ library based optimizations">;
defm clangir : BoolFOption<"clangir",
FrontendOpts<"UseClangIRPipeline">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Use the ClangIR pipeline to compile">,
More information about the cfe-commits
mailing list