https://github.com/bcardosolopes updated 
https://github.com/llvm/llvm-project/pull/229607

>From b51e47682093c138ec936f64ab682529fbe1823d Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <[email protected]>
Date: Tue, 6 Oct 2026 16:01:43 -0700
Subject: [PATCH 1/2] [CIR] Add -emit-cir-bc driver action

Teach the driver to serialize CIR directly to bytecode: new EmitCIRBC
frontend action kind, TY_CIRBC (.cirbc) driver type, and EmitCIRBCAction
writing the in-memory module with mlir::writeBytecodeToFile instead of
printing text. .cirbc inputs map to the CIR language like .cir.

Tests cover cc1 emission with magic-byte and read-back pins, .cir-input
and .cirbc-input round trips, and driver forwarding, phase selection,
default output name, and flag-implied pipeline selection.

Together with the attribute encodings from #229586, the driver can now
emit CIR bytecode end to end, removing the text round-trip from bytecode
measurements. It is a step towards selfhosting with bytecode.
---
 .../clang/Basic/DiagnosticCodeGenKinds.td     |  3 +++
 .../clang/CIR/FrontendAction/CIRGenAction.h   |  8 ++++++++
 clang/include/clang/Driver/Types.def          |  1 +
 .../include/clang/Frontend/FrontendOptions.h  |  3 +++
 clang/include/clang/Options/Options.td        |  3 +++
 clang/lib/CIR/FrontendAction/CIRGenAction.cpp | 19 +++++++++++++++++++
 clang/lib/CIR/FrontendAction/CMakeLists.txt   |  1 +
 clang/lib/Driver/Driver.cpp                   |  3 +++
 clang/lib/Driver/ToolChains/Clang.cpp         |  2 ++
 clang/lib/Frontend/CompilerInvocation.cpp     |  5 ++++-
 clang/lib/Frontend/FrontendOptions.cpp        |  2 +-
 .../ExecuteCompilerInvocation.cpp             | 12 ++++++++++--
 clang/test/CIR/Driver/emit-cir-bc.c           | 18 ++++++++++++++++++
 clang/test/CIR/emit-actions.cpp               | 15 +++++++++++++++
 14 files changed, 91 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CIR/Driver/emit-cir-bc.c

diff --git a/clang/include/clang/Basic/DiagnosticCodeGenKinds.td 
b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
index f135cc5df3057..c8b8bb38b20ea 100644
--- a/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
+++ b/clang/include/clang/Basic/DiagnosticCodeGenKinds.td
@@ -20,6 +20,9 @@ let Component = "CodeGen" in {
 def err_cir_to_cir_transform_failed : Error<
     "CIR-to-CIR transformation failed">, DefaultFatal;
 
+def err_cir_bc_write_failed : Error<
+    "could not write ClangIR bytecode to output stream">, DefaultFatal;
+
 def err_cir_verification_failed_pre_passes : Error<
     "CIR module verification error before running CIR-to-CIR passes">,
     DefaultFatal;
diff --git a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h 
b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
index f7ca27fa6b5a2..9f8bad248ea47 100644
--- a/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
+++ b/clang/include/clang/CIR/FrontendAction/CIRGenAction.h
@@ -33,6 +33,7 @@ class CIRGenAction : public clang::ASTFrontendAction {
   enum class OutputType {
     EmitAssembly,
     EmitCIR,
+    EmitCIRBC,
     EmitLLVM,
     EmitBC,
     EmitObj,
@@ -74,6 +75,13 @@ class EmitCIRAction : public CIRGenAction {
   EmitCIRAction(mlir::MLIRContext *MLIRCtx = nullptr);
 };
 
+class EmitCIRBCAction : public CIRGenAction {
+  virtual void anchor();
+
+public:
+  EmitCIRBCAction(mlir::MLIRContext *MLIRCtx = nullptr);
+};
+
 class EmitLLVMAction : public CIRGenAction {
   virtual void anchor();
 
diff --git a/clang/include/clang/Driver/Types.def 
b/clang/include/clang/Driver/Types.def
index 38ccdaaebe717..dd9fe5053c8fa 100644
--- a/clang/include/clang/Driver/Types.def
+++ b/clang/include/clang/Driver/Types.def
@@ -104,6 +104,7 @@ TYPE("lto-ir",                   LTO_IR,       INVALID,     
    "s",      phases
 TYPE("lto-bc",                   LTO_BC,       INVALID,         "o",      
phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 
 TYPE("cir",                      CIR,          INVALID,         "cir",    
phases::Compile, phases::Backend, phases::Assemble, phases::Link)
+TYPE("cir-bc",                   CIRBC,        INVALID,         "cirbc",  
phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 // Misc.
 TYPE("ast",                      AST,          INVALID,         "ast",    
phases::Compile, phases::Backend, phases::Assemble, phases::Link)
 TYPE("ifs",                      IFS,          INVALID,         "ifs",    
phases::IfsMerge)
diff --git a/clang/include/clang/Frontend/FrontendOptions.h 
b/clang/include/clang/Frontend/FrontendOptions.h
index cb32509aa09e2..7e2b093652566 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -68,6 +68,9 @@ enum ActionKind {
   /// Emit a .cir file
   EmitCIR,
 
+  /// Emit a .cirbc file (ClangIR bytecode).
+  EmitCIRBC,
+
   /// Emit a .ll file.
   EmitLLVM,
 
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 7c68c1bef904a..8e33916618cab 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3557,6 +3557,9 @@ defm clangir : BoolFOption<"clangir",
   BothFlags<[], [ClangOption, CC1Option], "">>;
 def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>,
   Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR">;
+def emit_cir_bc : Flag<["-"], "emit-cir-bc">,
+  Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
+  HelpText<"Build ASTs and then emit ClangIR bytecode">;
 /// ClangIR-specific options - END
 
 def flto_EQ : Joined<["-"], "flto=">,
diff --git a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp 
b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
index 627e659f62ba8..71a7a17146af3 100644
--- a/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
+++ b/clang/lib/CIR/FrontendAction/CIRGenAction.cpp
@@ -8,6 +8,7 @@
 
 #include "clang/CIR/FrontendAction/CIRGenAction.h"
 #include "CIRDiagnosticHandler.h"
+#include "mlir/Bytecode/BytecodeWriter.h"
 #include "mlir/IR/BuiltinOps.h"
 #include "mlir/IR/MLIRContext.h"
 #include "mlir/IR/OwningOpRef.h"
@@ -48,6 +49,7 @@ static BackendAction
 getBackendActionFromOutputType(CIRGenAction::OutputType Action) {
   switch (Action) {
   case CIRGenAction::OutputType::EmitCIR:
+  case CIRGenAction::OutputType::EmitCIRBC:
     assert(false &&
            "Unsupported output type for getBackendActionFromOutputType!");
     break; // Unreachable, but fall through to report that
@@ -194,6 +196,12 @@ class CIRGenConsumer : public clang::ASTConsumer {
       if (OutputStream && MlirModule)
         printCIRModule(MlirModule, *OutputStream);
       break;
+    case CIRGenAction::OutputType::EmitCIRBC:
+      if (OutputStream && MlirModule &&
+          failed(mlir::writeBytecodeToFile(MlirModule, *OutputStream)) &&
+          !CI.getDiagnostics().hasErrorOccurred())
+        CI.getDiagnostics().Report(diag::err_cir_bc_write_failed);
+      break;
     case CIRGenAction::OutputType::EmitLLVM:
     case CIRGenAction::OutputType::EmitBC:
     case CIRGenAction::OutputType::EmitObj:
@@ -433,6 +441,11 @@ void CIRGenAction::ExecuteAction() {
     // been through it, and its lowering passes are not idempotent.
     printCIRModule(*Module, *OS);
     break;
+  case OutputType::EmitCIRBC:
+    if (failed(mlir::writeBytecodeToFile(*Module, *OS)) &&
+        !Diags.hasErrorOccurred())
+      Diags.Report(diag::err_cir_bc_write_failed);
+    break;
   case OutputType::EmitLLVM:
   case OutputType::EmitBC:
   case OutputType::EmitObj:
@@ -450,6 +463,8 @@ getOutputStream(CompilerInstance &CI, StringRef InFile,
     return CI.createDefaultOutputFile(false, InFile, "s");
   case CIRGenAction::OutputType::EmitCIR:
     return CI.createDefaultOutputFile(false, InFile, "cir");
+  case CIRGenAction::OutputType::EmitCIRBC:
+    return CI.createDefaultOutputFile(true, InFile, "cirbc");
   case CIRGenAction::OutputType::EmitLLVM:
     return CI.createDefaultOutputFile(false, InFile, "ll");
   case CIRGenAction::OutputType::EmitBC:
@@ -481,6 +496,10 @@ void EmitCIRAction::anchor() {}
 EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx)
     : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {}
 
+void EmitCIRBCAction::anchor() {}
+EmitCIRBCAction::EmitCIRBCAction(mlir::MLIRContext *MLIRCtx)
+    : CIRGenAction(OutputType::EmitCIRBC, MLIRCtx) {}
+
 void EmitLLVMAction::anchor() {}
 EmitLLVMAction::EmitLLVMAction(mlir::MLIRContext *MLIRCtx)
     : CIRGenAction(OutputType::EmitLLVM, MLIRCtx) {}
diff --git a/clang/lib/CIR/FrontendAction/CMakeLists.txt 
b/clang/lib/CIR/FrontendAction/CMakeLists.txt
index be46ce6965931..d19496939af60 100644
--- a/clang/lib/CIR/FrontendAction/CMakeLists.txt
+++ b/clang/lib/CIR/FrontendAction/CMakeLists.txt
@@ -26,6 +26,7 @@ add_clang_library(clangCIRFrontendAction
   clangCodeGenUtils
   CIRRegisterAllDialects
   MLIRCIR
+  MLIRBytecodeWriter
   MLIRIR
   MLIRParser
   )
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 57beab92011a9..8525871698c8f 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -387,6 +387,7 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_emit_cir_bc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
     FinalPhase = phases::Compile;
 
@@ -4454,6 +4455,8 @@ Action *Driver::ConstructPhaseAction(
       return C.MakeAction<CompileJobAction>(Input, types::TY_AST);
     if (Args.hasArg(options::OPT_emit_cir))
       return C.MakeAction<CompileJobAction>(Input, types::TY_CIR);
+    if (Args.hasArg(options::OPT_emit_cir_bc))
+      return C.MakeAction<CompileJobAction>(Input, types::TY_CIRBC);
     if (Args.hasArg(options::OPT_module_file_info))
       return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
     if (Args.hasArg(options::OPT_verify_pch))
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 299ef698aa8ed..353a0bbee0813 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5575,6 +5575,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
       rewriteKind = RK_Fragile;
     } else if (JA.getType() == types::TY_CIR) {
       CmdArgs.push_back("-emit-cir");
+    } else if (JA.getType() == types::TY_CIRBC) {
+      CmdArgs.push_back("-emit-cir-bc");
     } else if (JA.getType() == types::TY_Image && IsAMDSPIRVForHIPDevice) {
       CmdArgs.push_back("-emit-obj");
     } else {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 7e2bb1e782eb8..da89f194c7f9f 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2816,6 +2816,7 @@ static const auto &getFrontendActionTable() {
       {frontend::EmitAssembly, OPT_S},
       {frontend::EmitBC, OPT_emit_llvm_bc},
       {frontend::EmitCIR, OPT_emit_cir},
+      {frontend::EmitCIRBC, OPT_emit_cir_bc},
       {frontend::EmitHTML, OPT_emit_html},
       {frontend::EmitLLVM, OPT_emit_llvm},
       {frontend::EmitLLVMOnly, OPT_emit_llvm_only},
@@ -3179,7 +3180,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, 
ArgList &Args,
   if (Opts.ProgramAction != frontend::GenerateModule && Opts.IsSystemModule)
     Diags.Report(diag::err_drv_argument_only_allowed_with) << "-fsystem-module"
                                                            << "-emit-module";
-  if (Args.hasArg(OPT_emit_cir))
+  if (Args.hasArg(OPT_emit_cir, OPT_emit_cir_bc))
     Opts.UseClangIRPipeline = true;
 
 #if CLANG_ENABLE_CIR
@@ -4748,6 +4749,7 @@ static bool 
isStrictlyPreprocessorAction(frontend::ActionKind Action) {
   case frontend::EmitAssembly:
   case frontend::EmitBC:
   case frontend::EmitCIR:
+  case frontend::EmitCIRBC:
   case frontend::EmitHTML:
   case frontend::EmitLLVM:
   case frontend::EmitLLVMOnly:
@@ -4789,6 +4791,7 @@ static bool isCodeGenAction(frontend::ActionKind Action) {
   case frontend::EmitAssembly:
   case frontend::EmitBC:
   case frontend::EmitCIR:
+  case frontend::EmitCIRBC:
   case frontend::EmitHTML:
   case frontend::EmitLLVM:
   case frontend::EmitLLVMOnly:
diff --git a/clang/lib/Frontend/FrontendOptions.cpp 
b/clang/lib/Frontend/FrontendOptions.cpp
index fb178b6b942e2..32db5306e35b5 100644
--- a/clang/lib/Frontend/FrontendOptions.cpp
+++ b/clang/lib/Frontend/FrontendOptions.cpp
@@ -35,6 +35,6 @@ InputKind FrontendOptions::getInputKindForExtension(StringRef 
Extension) {
       .Case("hip", Language::HIP)
       .Cases({"ll", "bc"}, Language::LLVM_IR)
       .Case("hlsl", Language::HLSL)
-      .Case("cir", Language::CIR)
+      .Cases({"cir", "cirbc"}, Language::CIR)
       .Default(Language::Unknown);
 }
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp 
b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index e872f0823f23e..32d04b17b41f8 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -56,10 +56,11 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
 
   unsigned UseCIR = CI.getFrontendOpts().UseClangIRPipeline;
   frontend::ActionKind Act = CI.getFrontendOpts().ProgramAction;
-  bool EmitsCIR = Act == EmitCIR;
+  bool EmitsCIR = Act == EmitCIR || Act == EmitCIRBC;
 
   if (!UseCIR && EmitsCIR)
-    llvm::report_fatal_error("-emit-cir and only valid when using -fclangir");
+    llvm::report_fatal_error(
+        "-emit-cir and -emit-cir-bc only valid when using -fclangir");
 
   switch (CI.getFrontendOpts().ProgramAction) {
   case ASTDeclList:            return std::make_unique<ASTDeclListAction>();
@@ -88,6 +89,13 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
 #else
     CI.getDiagnostics().Report(diag::err_fe_cir_not_built);
     return nullptr;
+#endif
+  case EmitCIRBC:
+#if CLANG_ENABLE_CIR
+    return std::make_unique<cir::EmitCIRBCAction>();
+#else
+    CI.getDiagnostics().Report(diag::err_fe_cir_not_built);
+    return nullptr;
 #endif
   case EmitHTML:               return std::make_unique<HTMLPrintAction>();
   case EmitLLVM: {
diff --git a/clang/test/CIR/Driver/emit-cir-bc.c 
b/clang/test/CIR/Driver/emit-cir-bc.c
new file mode 100644
index 0000000000000..b77b7b497f257
--- /dev/null
+++ b/clang/test/CIR/Driver/emit-cir-bc.c
@@ -0,0 +1,18 @@
+// The driver forwards -emit-cir-bc to -cc1 like -emit-cir, stays in
+// the compile phase, and names the default output after the cir-bc
+// type.
+
+// RUN: %clang -### -fclangir -emit-cir-bc %s 2>&1 | FileCheck %s
+// CHECK: "-cc1"
+// CHECK-SAME: "-emit-cir-bc"
+// CHECK-SAME: "-o" "emit-cir-bc.cirbc"
+
+// RUN: %clang -ccc-print-phases -fclangir -emit-cir-bc %s 2>&1 | FileCheck %s 
--check-prefix=PHASES
+// PHASES: compiler, {{.*}}, cir-bc
+
+// The flag implies the CIR pipeline without -fclangir.
+// RUN: %clang -### -emit-cir-bc %s 2>&1 | FileCheck %s 
--check-prefix=NOFCLANGIR
+// NOFCLANGIR: "-cc1"
+// NOFCLANGIR-SAME: "-emit-cir-bc"
+
+void foo() {}
diff --git a/clang/test/CIR/emit-actions.cpp b/clang/test/CIR/emit-actions.cpp
index 3cfb3d32e8e2c..2e9e4d961dfab 100644
--- a/clang/test/CIR/emit-actions.cpp
+++ b/clang/test/CIR/emit-actions.cpp
@@ -6,6 +6,17 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-obj %s -o 
%t.o
 // RUN: llvm-objdump -t %t.o | FileCheck %s -check-prefix=OBJ
 
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir-bc %s 
-o %t.cirbc
+// RUN: od -An -c -N4 %t.cirbc | FileCheck %s --check-prefix=CIRBC-MAGIC
+// RUN: not grep -q "cir.global" %t.cirbc
+// RUN: cir-opt %t.cirbc | FileCheck %s -check-prefix=CIRBC
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -x cir 
-emit-cir-bc %t.cir -o %t2.cirbc
+// RUN: cir-opt %t2.cirbc | FileCheck %s --check-prefix=CIRBC
+
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir 
%t.cirbc -o - | FileCheck %s --check-prefix=CIRBC
+
 // TODO: Make this test target-independent
 // REQUIRES: x86-registered-target
 
@@ -19,3 +30,7 @@ int x = 1;
 
 // OBJ: .data
 // OBJ-SAME: x
+
+// CIRBC-MAGIC: M L 357 R
+
+// CIRBC: cir.global {{.*}}@x = #cir.int<1> : !s32i

>From 6925e79e5fad18360c3337cd7255dd37985aff3e Mon Sep 17 00:00:00 2001
From: Bruno Cardoso Lopes <[email protected]>
Date: Wed, 7 Oct 2026 10:38:52 -0700
Subject: [PATCH 2/2] [CIR] Follow the -emit-llvm model for -emit-cir-bc

-emit-cir-bc is now cc1-only; at the driver, -emit-cir -c selects the
binary form while bare -emit-cir and -emit-cir -S keep emitting text.
Route .cir and .cirbc inputs through the driver to cc1 so bytecode
round-trips instead of erroring out in the gcc tool.

Assisted-by: Muse Code (Muse).
---
 clang/include/clang/Options/Options.td |  2 +-
 clang/lib/Driver/Driver.cpp            | 10 +++++---
 clang/lib/Driver/ToolChains/Clang.cpp  |  3 +++
 clang/lib/Driver/Types.cpp             |  4 +++
 clang/test/CIR/Driver/emit-cir-bc.c    | 34 +++++++++++++++++---------
 5 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 8e33916618cab..bd00d792a72d5 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3558,7 +3558,7 @@ defm clangir : BoolFOption<"clangir",
 def emit_cir : Flag<["-"], "emit-cir">, Visibility<[ClangOption, CC1Option]>,
   Group<Action_Group>, HelpText<"Build ASTs and then lower to ClangIR">;
 def emit_cir_bc : Flag<["-"], "emit-cir-bc">,
-  Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
+  Visibility<[CC1Option]>, Group<Action_Group>,
   HelpText<"Build ASTs and then emit ClangIR bytecode">;
 /// ClangIR-specific options - END
 
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 8525871698c8f..f6269fd9528e4 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -387,7 +387,6 @@ phases::ID Driver::getFinalPhase(const DerivedArgList &DAL,
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__analyze)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_emit_cir)) ||
-             (PhaseArg = DAL.getLastArg(options::OPT_emit_cir_bc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
     FinalPhase = phases::Compile;
 
@@ -4453,10 +4452,13 @@ Action *Driver::ConstructPhaseAction(
       return C.MakeAction<AnalyzeJobAction>(Input, types::TY_Plist);
     if (Args.hasArg(options::OPT_emit_ast))
       return C.MakeAction<CompileJobAction>(Input, types::TY_AST);
-    if (Args.hasArg(options::OPT_emit_cir))
+    if (Args.hasArg(options::OPT_emit_cir)) {
+      // Like -emit-llvm, -c selects the binary form; bare -emit-cir and
+      // -emit-cir -S keep emitting text.
+      if (Args.hasArg(options::OPT_c) && !Args.hasArg(options::OPT_S))
+        return C.MakeAction<CompileJobAction>(Input, types::TY_CIRBC);
       return C.MakeAction<CompileJobAction>(Input, types::TY_CIR);
-    if (Args.hasArg(options::OPT_emit_cir_bc))
-      return C.MakeAction<CompileJobAction>(Input, types::TY_CIRBC);
+    }
     if (Args.hasArg(options::OPT_module_file_info))
       return C.MakeAction<CompileJobAction>(Input, types::TY_ModuleFile);
     if (Args.hasArg(options::OPT_verify_pch))
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 353a0bbee0813..210c1b2b80bb9 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -357,6 +357,9 @@ static void addDashXForInput(const ArgList &Args, const 
InputInfo &Input,
     case types::TY_PP_CXXModule:
       ClangType = "c++-cpp-output";
       break;
+    case types::TY_CIRBC:
+      ClangType = "cir";
+      break;
     default:
       ClangType = types::getTypeName(Input.getType());
       break;
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 4cca8acd515d7..a3acdc9728308 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -171,6 +171,8 @@ bool types::isAcceptedByClang(ID Id) {
   case TY_PP_CXXStdModule:
   case TY_AST: case TY_ModuleFile: case TY_PCH:
   case TY_LLVM_IR: case TY_LLVM_BC:
+  case TY_CIR:
+  case TY_CIRBC:
   case TY_API_INFO:
     return true;
   }
@@ -367,6 +369,8 @@ types::ID types::lookupTypeForExtension(llvm::StringRef 
Ext) {
       .Case("CPP", TY_CXX)
       .Case("c++", TY_CXX)
       .Case("C++", TY_CXX)
+      .Case("cir", TY_CIR)
+      .Case("cirbc", TY_CIRBC)
       .Case("cui", TY_PP_CUDA)
       .Case("cxx", TY_CXX)
       .Case("CXX", TY_CXX)
diff --git a/clang/test/CIR/Driver/emit-cir-bc.c 
b/clang/test/CIR/Driver/emit-cir-bc.c
index b77b7b497f257..78bc4a3b9a6c1 100644
--- a/clang/test/CIR/Driver/emit-cir-bc.c
+++ b/clang/test/CIR/Driver/emit-cir-bc.c
@@ -1,18 +1,28 @@
-// The driver forwards -emit-cir-bc to -cc1 like -emit-cir, stays in
-// the compile phase, and names the default output after the cir-bc
-// type.
+// -emit-cir follows the -emit-llvm model: -c selects the binary form,
+// bare -emit-cir and -emit-cir -S keep emitting text. -emit-cir-bc is
+// cc1-only.
 
-// RUN: %clang -### -fclangir -emit-cir-bc %s 2>&1 | FileCheck %s
-// CHECK: "-cc1"
-// CHECK-SAME: "-emit-cir-bc"
-// CHECK-SAME: "-o" "emit-cir-bc.cirbc"
+// RUN: %clang -### -fclangir -emit-cir -c %s 2>&1 | FileCheck %s 
--check-prefix=BC
+// BC: "-cc1"
+// BC-SAME: "-emit-cir-bc"
+// BC-SAME: "-o" "emit-cir-bc.cirbc"
 
-// RUN: %clang -ccc-print-phases -fclangir -emit-cir-bc %s 2>&1 | FileCheck %s 
--check-prefix=PHASES
+// RUN: %clang -ccc-print-phases -fclangir -emit-cir -c %s 2>&1 | FileCheck %s 
--check-prefix=PHASES
 // PHASES: compiler, {{.*}}, cir-bc
 
-// The flag implies the CIR pipeline without -fclangir.
-// RUN: %clang -### -emit-cir-bc %s 2>&1 | FileCheck %s 
--check-prefix=NOFCLANGIR
-// NOFCLANGIR: "-cc1"
-// NOFCLANGIR-SAME: "-emit-cir-bc"
+// RUN: %clang -### -fclangir -emit-cir %s 2>&1 | FileCheck %s 
--check-prefix=TEXT
+// RUN: %clang -### -fclangir -emit-cir -S %s 2>&1 | FileCheck %s 
--check-prefix=TEXT
+// TEXT: "-cc1"
+// TEXT-SAME: "-emit-cir"
+// TEXT-SAME: "-o" "emit-cir-bc.cir"
+
+// RUN: not %clang -fclangir -emit-cir-bc %s 2>&1 | FileCheck %s 
--check-prefix=REJECT
+// REJECT: unknown argument '-emit-cir-bc'
+
+// The driver accepts .cirbc inputs, so bytecode round-trips through it.
+// RUN: %clang -fclangir -emit-cir -c %s -o %t.cirbc
+// RUN: %clang -fclangir -x cir-bc -emit-cir %t.cirbc -o - | FileCheck %s 
--check-prefix=ROUNDTRIP
+// RUN: %clang -fclangir -emit-cir %t.cirbc -o - | FileCheck %s 
--check-prefix=ROUNDTRIP
+// ROUNDTRIP: cir.func {{.*}}@foo()
 
 void foo() {}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to