[clang] [CIR][Passes] Add CallConvLowering pass skeleton (PR #189613)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 31 08:47:44 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-driver
Author: Chaitanya (skc7)
<details>
<summary>Changes</summary>
Upstreaming clangIR PR: https://github.com/llvm/clangir/pull/642
This patch adds a new CallConvLowering pass that aims to lower the calling conventions of the functions in the module.
This pass is disabled by default and can be enabled by passing the flag `-fclangir-call-conv-lowering`. Once this pass is more mature, it should be enabled by default as a required step to lower to LLVM Dialect.
---
Full diff: https://github.com/llvm/llvm-project/pull/189613.diff
11 Files Affected:
- (modified) clang/include/clang/CIR/CIRToCIRPasses.h (+2-1)
- (modified) clang/include/clang/CIR/Dialect/Passes.h (+3)
- (modified) clang/include/clang/CIR/Dialect/Passes.td (+11)
- (modified) clang/include/clang/Frontend/FrontendOptions.h (+3)
- (modified) clang/include/clang/Options/Options.td (+8)
- (modified) clang/lib/CIR/Dialect/Transforms/CMakeLists.txt (+1)
- (added) clang/lib/CIR/Dialect/Transforms/CallConvLowering.cpp (+58)
- (modified) clang/lib/CIR/FrontendAction/CIRGenAction.cpp (+2-1)
- (modified) clang/lib/CIR/Lowering/CIRPasses.cpp (+7-1)
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+3)
- (added) clang/test/CIR/Transforms/call-conv-lowering-pass.cpp (+5)
``````````diff
diff --git a/clang/include/clang/CIR/CIRToCIRPasses.h b/clang/include/clang/CIR/CIRToCIRPasses.h
index ec6d75332bed9..061b4462ed846 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 enableIdiomRecognizer, bool enableCIRSimplify);
+ bool enableIdiomRecognizer, bool enableCIRSimplify,
+ bool enableCallingConvLowering);
} // namespace cir
diff --git a/clang/include/clang/CIR/Dialect/Passes.h b/clang/include/clang/CIR/Dialect/Passes.h
index d441dfcbc6c14..31332e968309f 100644
--- a/clang/include/clang/CIR/Dialect/Passes.h
+++ b/clang/include/clang/CIR/Dialect/Passes.h
@@ -34,6 +34,9 @@ std::unique_ptr<Pass> createGotoSolverPass();
std::unique_ptr<Pass> createIdiomRecognizerPass();
std::unique_ptr<Pass> createIdiomRecognizerPass(clang::ASTContext *astCtx);
+/// Create a pass to lower ABI-independent function definitions/calls.
+std::unique_ptr<Pass> createCallConvLoweringPass();
+
void populateCIRPreLoweringPasses(mlir::OpPassManager &pm);
//===----------------------------------------------------------------------===//
diff --git a/clang/include/clang/CIR/Dialect/Passes.td b/clang/include/clang/CIR/Dialect/Passes.td
index 32cd182aacec7..7f08221c965ca 100644
--- a/clang/include/clang/CIR/Dialect/Passes.td
+++ b/clang/include/clang/CIR/Dialect/Passes.td
@@ -195,4 +195,15 @@ def IdiomRecognizer : Pass<"cir-idiom-recognizer", "mlir::ModuleOp"> {
let dependentDialects = ["cir::CIRDialect"];
}
+def CallConvLowering : Pass<"cir-call-conv-lowering"> {
+ let summary = "Handle calling conventions for CIR functions";
+ let description = [{
+ This pass lowers CIR function definitions and calls according to the
+ calling conventions for the target architecture. This pass is necessary
+ to properly lower CIR functions to LLVM IR.
+ }];
+ let constructor = "mlir::createCallConvLoweringPass()";
+ let dependentDialects = ["cir::CIRDialect"];
+}
+
#endif // CLANG_CIR_DIALECT_PASSES_TD
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index f7f51bc37c98d..26028fd82087c 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -426,6 +426,9 @@ class FrontendOptions {
LLVM_PREFERRED_TYPE(bool)
unsigned ClangIREnableIdiomRecognizer : 1;
+ // Enable Clang IR call conv lowering pass.
+ unsigned ClangIRCallConvLowering : 1;
+
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 215d4e885709c..a787c3fbcddae 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3355,6 +3355,14 @@ def clangir_enable_idiom_recognizer : Flag<["-"], "clangir-enable-idiom-recogniz
HelpText<"ClangIR: Enable Idiom Recognizer pass">,
MarshallingInfoFlag<FrontendOpts<"ClangIREnableIdiomRecognizer">>;
+// FIXME(cir): Remove this option once all pre-existing tests are compatible with
+// the calling convention lowering pass.
+defm clangir_call_conv_lowering : BoolFOption<"clangir-call-conv-lowering",
+ FrontendOpts<"ClangIRCallConvLowering">, DefaultFalse,
+ PosFlag<SetTrue, [], [ClangOption, CC1Option], "Transform CIR to abide to calling conventions during lowering">,
+ NegFlag<SetFalse, [], [ClangOption, CC1Option], "Ignore calling convention during lowering">,
+ BothFlags<[], [ClangOption, CC1Option], "">>;
+
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 411bbc386b9d1..205e59dbb9eb4 100644
--- a/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
+++ b/clang/lib/CIR/Dialect/Transforms/CMakeLists.txt
@@ -11,6 +11,7 @@ add_clang_library(MLIRCIRTransforms
LoweringPrepare.cpp
GotoSolver.cpp
IdiomRecognizer.cpp
+ CallConvLowering.cpp
DEPENDS
MLIRCIRPassIncGen
diff --git a/clang/lib/CIR/Dialect/Transforms/CallConvLowering.cpp b/clang/lib/CIR/Dialect/Transforms/CallConvLowering.cpp
new file mode 100644
index 0000000000000..1c166d5bd0c09
--- /dev/null
+++ b/clang/lib/CIR/Dialect/Transforms/CallConvLowering.cpp
@@ -0,0 +1,58 @@
+//===- CallConvLowering.cpp - Rewrites functions according to call convs --===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/BuiltinOps.h"
+#include "mlir/Pass/Pass.h"
+#include "clang/CIR/Dialect/IR/CIRDialect.h"
+
+#define GEN_PASS_DEF_CALLCONVLOWERING
+#include "clang/CIR/Dialect/Passes.h.inc"
+
+namespace cir {
+
+struct CallConvLowering {
+ CallConvLowering(mlir::ModuleOp module) : module(module) {}
+
+ void lower(FuncOp op) {
+ // TODO(cir): Implement calling convention lowering for function definitions
+ // and calls once the upstream LowerModule has the necessary APIs.
+ }
+
+private:
+ mlir::ModuleOp module;
+};
+
+//===----------------------------------------------------------------------===//
+// Pass
+//===----------------------------------------------------------------------===//
+
+struct CallConvLoweringPass
+ : ::impl::CallConvLoweringBase<CallConvLoweringPass> {
+ using CallConvLoweringBase::CallConvLoweringBase;
+
+ void runOnOperation() override;
+ llvm::StringRef getArgument() const override {
+ return "cir-call-conv-lowering";
+ };
+};
+
+void CallConvLoweringPass::runOnOperation() {
+ auto module = mlir::dyn_cast<mlir::ModuleOp>(getOperation());
+ CallConvLowering cc(module);
+ module.walk([&](FuncOp op) { cc.lower(op); });
+}
+
+} // namespace cir
+
+namespace mlir {
+
+std::unique_ptr<mlir::Pass> createCallConvLoweringPass() {
+ return std::make_unique<cir::CallConvLoweringPass>();
+}
+
+} // namespace mlir
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index ab273539b1ce2..5d4e70d6724e1 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -122,7 +122,8 @@ class CIRGenConsumer : public clang::ASTConsumer {
// Setup and run CIR pipeline.
if (runCIRToCIRPasses(
MlirModule, MlirCtx, C, !FEOptions.ClangIRDisableCIRVerifier,
- FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 0)
+ FEOptions.ClangIREnableIdiomRecognizer, CGO.OptimizationLevel > 0,
+ FEOptions.ClangIRCallConvLowering)
.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 7b93356a34c38..1cc00610d3fdb 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 enableIdiomRecognizer, bool enableCIRSimplify) {
+ bool enableIdiomRecognizer, bool enableCIRSimplify,
+ bool enableCallConvLowering) {
llvm::TimeTraceScope scope("CIR To CIR Passes");
@@ -37,6 +38,11 @@ runCIRToCIRPasses(mlir::ModuleOp theModule, mlir::MLIRContext &mlirContext,
pm.addPass(mlir::createCXXABILoweringPass());
pm.addPass(mlir::createLoweringPreparePass(&astContext));
+ // FIXME(cir): This pass should run by default, but it is lacking support for
+ // several code bits. Once it's more mature, we should fix this.
+ if (enableCallConvLowering)
+ pm.addPass(mlir::createCallConvLoweringPass());
+
pm.enableVerifier(enableVerifier);
(void)mlir::applyPassManagerCLOptions(pm);
return pm.run(theModule);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index db82695f87d6b..e3edee10767e7 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5112,6 +5112,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (Args.hasArg(options::OPT_fclangir))
CmdArgs.push_back("-fclangir");
+ if (Args.hasArg(options::OPT_fclangir_call_conv_lowering))
+ CmdArgs.push_back("-fclangir-call-conv-lowering");
+
if (IsOpenMPDevice) {
// We have to pass the triple of the host if compiling for an OpenMP device.
std::string NormalizedTriple =
diff --git a/clang/test/CIR/Transforms/call-conv-lowering-pass.cpp b/clang/test/CIR/Transforms/call-conv-lowering-pass.cpp
new file mode 100644
index 0000000000000..5581a45e83071
--- /dev/null
+++ b/clang/test/CIR/Transforms/call-conv-lowering-pass.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -fclangir-call-conv-lowering -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s
+
+// CHECK: cir.func {{.*}}@_Z5emptyv()
+void empty() {}
``````````
</details>
https://github.com/llvm/llvm-project/pull/189613
More information about the cfe-commits
mailing list