[clang] 4a1e9f7 - [CIR] Make the -save-temps flag emit .cir and .mlir files (#186814)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 20 07:44:51 PDT 2026
Author: Jan Leyonberg
Date: 2026-03-20T10:44:47-04:00
New Revision: 4a1e9f73103fa3d66c7db93f1047905c07d543e2
URL: https://github.com/llvm/llvm-project/commit/4a1e9f73103fa3d66c7db93f1047905c07d543e2
DIFF: https://github.com/llvm/llvm-project/commit/4a1e9f73103fa3d66c7db93f1047905c07d543e2.diff
LOG: [CIR] Make the -save-temps flag emit .cir and .mlir files (#186814)
This patch makes ClangIR emit .cir and .mlir files when the-save-temps
flag is specified. Having these files emitted is useful e.g. when
inspecting the generated code for OpenMP offloading.
Co-authored-by: Claude Opus 4.6 noreply at anthropic.com
Added:
clang/test/CIR/CodeGen/save-temps.c
Modified:
clang/include/clang/CIR/LowerToLLVM.h
clang/lib/CIR/FrontendAction/CIRGenAction.cpp
clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/CIR/LowerToLLVM.h b/clang/include/clang/CIR/LowerToLLVM.h
index 6e1b0270fcd2b..393b997c50695 100644
--- a/clang/include/clang/CIR/LowerToLLVM.h
+++ b/clang/include/clang/CIR/LowerToLLVM.h
@@ -12,6 +12,7 @@
#ifndef CLANG_CIR_LOWERTOLLVM_H
#define CLANG_CIR_LOWERTOLLVM_H
+#include "llvm/ADT/StringRef.h"
#include <memory>
namespace llvm {
@@ -28,7 +29,8 @@ namespace cir {
namespace direct {
std::unique_ptr<llvm::Module>
lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule,
- llvm::LLVMContext &llvmCtx);
+ llvm::LLVMContext &llvmCtx,
+ llvm::StringRef mlirSaveTempsOutFile = {});
} // namespace direct
} // namespace cir
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 19c407545b961..ab273539b1ce2 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -15,7 +15,10 @@
#include "clang/CIR/LowerToLLVM.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/Frontend/CompilerInstance.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
using namespace cir;
using namespace clang;
@@ -44,8 +47,10 @@ getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
}
static std::unique_ptr<llvm::Module>
-lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx) {
- return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx);
+lowerFromCIRToLLVMIR(mlir::ModuleOp MLIRModule, llvm::LLVMContext &LLVMCtx,
+ llvm::StringRef mlirSaveTempsOutFile = {}) {
+ return direct::lowerDirectlyFromCIRToLLVMIR(MLIRModule, LLVMCtx,
+ mlirSaveTempsOutFile);
}
class CIRGenConsumer : public clang::ASTConsumer {
@@ -136,9 +141,26 @@ class CIRGenConsumer : public clang::ASTConsumer {
case CIRGenAction::OutputType::EmitBC:
case CIRGenAction::OutputType::EmitObj:
case CIRGenAction::OutputType::EmitAssembly: {
+ StringRef saveTempsPrefix = CGO.SaveTempsFilePrefix;
+ std::string cirSaveTempsOutFile, mlirSaveTempsOutFile;
+ if (!saveTempsPrefix.empty()) {
+ SmallString<128> stem(saveTempsPrefix);
+ llvm::sys::path::replace_extension(stem, "cir");
+ cirSaveTempsOutFile = std::string(stem);
+ llvm::sys::path::replace_extension(stem, "mlir");
+ mlirSaveTempsOutFile = std::string(stem);
+ }
+
+ if (!cirSaveTempsOutFile.empty()) {
+ std::error_code ec;
+ llvm::raw_fd_ostream out(cirSaveTempsOutFile, ec);
+ if (!ec)
+ MlirModule->print(out);
+ }
+
llvm::LLVMContext LLVMCtx;
std::unique_ptr<llvm::Module> LLVMModule =
- lowerFromCIRToLLVMIR(MlirModule, LLVMCtx);
+ lowerFromCIRToLLVMIR(MlirModule, LLVMCtx, mlirSaveTempsOutFile);
BackendAction BEAction = getBackendActionFromOutputType(Action);
emitBackendOutput(
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 60c3030bfbea1..6463c662ade6d 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -46,6 +46,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TimeProfiler.h"
+#include "llvm/Support/raw_ostream.h"
using namespace cir;
using namespace llvm;
@@ -4925,7 +4926,8 @@ void populateCIRToLLVMPasses(mlir::OpPassManager &pm) {
}
std::unique_ptr<llvm::Module>
-lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, LLVMContext &llvmCtx) {
+lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, LLVMContext &llvmCtx,
+ StringRef mlirSaveTempsOutFile) {
llvm::TimeTraceScope scope("lower from CIR to LLVM directly");
mlir::MLIRContext *mlirCtx = mlirModule.getContext();
@@ -4941,6 +4943,13 @@ lowerDirectlyFromCIRToLLVMIR(mlir::ModuleOp mlirModule, LLVMContext &llvmCtx) {
"The pass manager failed to lower CIR to LLVMIR dialect!");
}
+ if (!mlirSaveTempsOutFile.empty()) {
+ std::error_code ec;
+ llvm::raw_fd_ostream out(mlirSaveTempsOutFile, ec);
+ if (!ec)
+ mlirModule->print(out);
+ }
+
mlir::registerBuiltinDialectTranslation(*mlirCtx);
mlir::registerLLVMDialectTranslation(*mlirCtx);
mlir::registerOpenMPDialectTranslation(*mlirCtx);
diff --git a/clang/test/CIR/CodeGen/save-temps.c b/clang/test/CIR/CodeGen/save-temps.c
new file mode 100644
index 0000000000000..8449ce38bace5
--- /dev/null
+++ b/clang/test/CIR/CodeGen/save-temps.c
@@ -0,0 +1,20 @@
+// Test that -save-temps with -fclangir emits .cir and .mlir intermediate files.
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm \
+// RUN: -save-temps=obj -o %t.ll %s
+
+// Check that the .cir file was created and contains CIR dialect ops
+// RUN: FileCheck --input-file=%t.cir %s --check-prefix=CIR
+
+// CIR: cir.func
+// CIR: cir.return
+
+// Check that the .mlir file was created and contains LLVM dialect ops
+// RUN: FileCheck --input-file=%t.mlir %s --check-prefix=MLIR
+
+// MLIR: llvm.func
+// MLIR: llvm.return
+
+int foo(int x) {
+ return x + 1;
+}
More information about the cfe-commits
mailing list