Skip to content

Conversation

@mmha
Copy link
Contributor

@mmha mmha commented Nov 7, 2025

Passing -emit-cir without -fclangir enables the CIR pipeline. This patch changes this to an error. Now -emit-cir requires -fclangir to be passed as well.

This is in preparation of a future patch that enables CIR as a source language in the driver. If a CIR module is passed on the command line this should also not implicitly enable the CIR pipeline for the rest of the compiler invocation (so C++ files passed on the same command line would be implicitly compiled using the CIR pipeline)

Passing -emit-cir without -fclangir enables the CIR pipeline. This patch changes this to an error. Now -emit-cir requires -fclangir to be passed as well.

This is in preparation of a future patch that enables CIR as a source language in the driver. If a CIR module is passed on the command line this should also not implicitly enable the CIR pipeline for the rest of the compiler invocation (so C++ files passed on the same command line would be implicitly compiled using the CIR pipeline)
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" ClangIR Anything related to the ClangIR project labels Nov 7, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2025

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-driver

Author: Morris Hafner (mmha)

Changes

Passing -emit-cir without -fclangir enables the CIR pipeline. This patch changes this to an error. Now -emit-cir requires -fclangir to be passed as well.

This is in preparation of a future patch that enables CIR as a source language in the driver. If a CIR module is passed on the command line this should also not implicitly enable the CIR pipeline for the rest of the compiler invocation (so C++ files passed on the same command line would be implicitly compiled using the CIR pipeline)


Full diff: https://github.com/llvm/llvm-project/pull/166916.diff

10 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+3)
  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+9-1)
  • (modified) clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (+12-4)
  • (modified) clang/test/CIR/CodeGen/builtin_prefetch.c (+2-2)
  • (modified) clang/test/CIR/CodeGen/dlti.c (+1-1)
  • (modified) clang/test/CIR/CodeGen/dlti_be.c (+1-1)
  • (modified) clang/test/CIR/CodeGen/module-asm.c (+1-1)
  • (added) clang/test/Driver/cir-flags-error.c (+11)
  • (added) clang/test/Driver/cir-input-without-fclangir.cir (+20)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 83980e3ac35b7..c47c2e5d42b90 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -887,6 +887,9 @@ def warn_missing_include_dirs : Warning<
 def err_drv_malformed_warning_suppression_mapping : Error<
   "failed to process suppression mapping file '%0': %1">;
 
+def err_drv_emit_cir_without_fclangir : Error<
+  "-emit-cir is only valid with -fclangir">;
+
 def warn_drv_openacc_without_cir
     : Warning<"OpenACC directives will result in no runtime behavior; use "
               "-fclangir to enable runtime effect">,
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 9e344160ff934..1ebea11dd5259 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -136,6 +136,9 @@ def err_fe_action_not_available : Error<
     "action %0 not compiled in">;
 def err_fe_cir_not_built : Error<"clang IR support not available, rebuild "
                                  "clang with -DCLANG_ENABLE_CIR=ON">;
+def err_fe_cir_disabled : Error<
+  "trying to compile CIR module %0 with clang IR disabled; use "
+  "-fclangir to enable CIR pipeline">;
 def err_fe_invalid_multiple_actions : Error<
     "'%0' action ignored; '%1' action specified previously">;
 def err_fe_invalid_alignment : Error<
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index be7c1d367e082..59dae34f0fd3d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3139,9 +3139,17 @@ 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_fclangir) || Args.hasArg(OPT_emit_cir))
+  if (Args.hasArg(OPT_fclangir))
     Opts.UseClangIRPipeline = true;
 
+#if CLANG_ENABLE_CIR
+  if (!Args.hasArg(OPT_fclangir) && Args.hasArg(OPT_emit_cir))
+    Diags.Report(diag::err_drv_emit_cir_without_fclangir);
+#else
+  if (Args.hasArg(OPT_emit_cir))
+    Diags.Report(diag::err_fe_cir_not_built);
+#endif
+
 #if CLANG_ENABLE_CIR
   if (Args.hasArg(OPT_clangir_disable_passes))
     Opts.ClangIRDisablePasses = true;
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index c8aad4daa1c10..25a89d465dcba 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -49,12 +49,20 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
   StringRef Action("unknown");
   (void)Action;
 
+#if CLANG_ENABLE_CIR
   unsigned UseCIR = CI.getFrontendOpts().UseClangIRPipeline;
-  frontend::ActionKind Act = CI.getFrontendOpts().ProgramAction;
-  bool EmitsCIR = Act == EmitCIR;
 
-  if (!UseCIR && EmitsCIR)
-    llvm::report_fatal_error("-emit-cir and only valid when using -fclangir");
+  if (!UseCIR) {
+    FrontendInputFile *it =
+        llvm::find_if(CI.getFrontendOpts().Inputs, [](const auto &FIF) {
+          return FIF.getKind().getLanguage() == Language::CIR;
+        });
+    if (it != CI.getFrontendOpts().Inputs.end()) {
+      CI.getDiagnostics().Report(diag::err_fe_cir_disabled) << it->getFile();
+      return nullptr;
+    }
+  }
+#endif
 
   switch (CI.getFrontendOpts().ProgramAction) {
   case ASTDeclList:            return std::make_unique<ASTDeclListAction>();
diff --git a/clang/test/CIR/CodeGen/builtin_prefetch.c b/clang/test/CIR/CodeGen/builtin_prefetch.c
index cfe85b9ba8104..c38e179617b1d 100644
--- a/clang/test/CIR/CodeGen/builtin_prefetch.c
+++ b/clang/test/CIR/CodeGen/builtin_prefetch.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
 
 void foo(void *a) {
   __builtin_prefetch(a);        // rw=0, locality=3
diff --git a/clang/test/CIR/CodeGen/dlti.c b/clang/test/CIR/CodeGen/dlti.c
index 3fa15d2ab584f..0e58a37756b75 100644
--- a/clang/test/CIR/CodeGen/dlti.c
+++ b/clang/test/CIR/CodeGen/dlti.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s --check-prefix=LITTLE
 
 void foo() {}
diff --git a/clang/test/CIR/CodeGen/dlti_be.c b/clang/test/CIR/CodeGen/dlti_be.c
index 918124ac0a237..b41e75466fe5f 100644
--- a/clang/test/CIR/CodeGen/dlti_be.c
+++ b/clang/test/CIR/CodeGen/dlti_be.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-cir %s -o %t.cir
+// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s --check-prefix=BIG
 
 void foo() {}
diff --git a/clang/test/CIR/CodeGen/module-asm.c b/clang/test/CIR/CodeGen/module-asm.c
index e6cec5e0ee948..049a90f69d393 100644
--- a/clang/test/CIR/CodeGen/module-asm.c
+++ b/clang/test/CIR/CodeGen/module-asm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir 
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir 
 // RUN: FileCheck --input-file=%t.cir %s
 
 // CHECK:  cir.module_asm = [".globl bar", ".globl foo"]
diff --git a/clang/test/Driver/cir-flags-error.c b/clang/test/Driver/cir-flags-error.c
new file mode 100644
index 0000000000000..a76e3173fb33c
--- /dev/null
+++ b/clang/test/Driver/cir-flags-error.c
@@ -0,0 +1,11 @@
+// REQUIRES: cir-support
+
+// RUN: not %clang -emit-cir %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=EMIT_CIR_ERROR
+// EMIT_CIR_ERROR: error: -emit-cir is only valid with -fclangir
+
+// RUN: %clang -fclangir -emit-cir %s -o /dev/null 2>&1 | FileCheck %s --allow-empty -check-prefix=EMIT_CIR_OK
+// EMIT_CIR_OK-NOT: error: -emit-cir is only valid with -fclangir
+
+int main(void) {
+  return 0;
+}
diff --git a/clang/test/Driver/cir-input-without-fclangir.cir b/clang/test/Driver/cir-input-without-fclangir.cir
new file mode 100644
index 0000000000000..2c4354511a322
--- /dev/null
+++ b/clang/test/Driver/cir-input-without-fclangir.cir
@@ -0,0 +1,20 @@
+// RUN: not %clang %s -emit-llvm -o /dev/null 2>&1 | FileCheck %s -check-prefix=CIR_INPUT_ERROR
+// CIR_INPUT_ERROR: error: trying to compile CIR module {{.*}} with clang IR disabled; use -fclangir to enable CIR pipeline
+
+// RUN: %clang -fclangir %s -emit-llvm -o /dev/null 2>&1 | FileCheck %s --allow-empty -check-prefix=CIR_INPUT_OK
+// CIR_INPUT_OK-NOT: error: trying to compile CIR module
+
+// REQUIRES: x86-registered-target
+// REQUIRES: cir-support
+
+!s32i = !cir.int<s, 32>
+
+module attributes {cir.lang = #cir.lang<cxx>, cir.triple = "x86_64-unknown-linux-gnu"} {
+  cir.func @test_function() -> !s32i {
+    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
+    %1 = cir.const #cir.int<42> : !s32i
+    cir.store %1, %0 : !s32i, !cir.ptr<!s32i>
+    %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
+    cir.return %2 : !s32i
+  }
+}

@llvmbot
Copy link
Member

llvmbot commented Nov 7, 2025

@llvm/pr-subscribers-clangir

Author: Morris Hafner (mmha)

Changes

Passing -emit-cir without -fclangir enables the CIR pipeline. This patch changes this to an error. Now -emit-cir requires -fclangir to be passed as well.

This is in preparation of a future patch that enables CIR as a source language in the driver. If a CIR module is passed on the command line this should also not implicitly enable the CIR pipeline for the rest of the compiler invocation (so C++ files passed on the same command line would be implicitly compiled using the CIR pipeline)


Full diff: https://github.com/llvm/llvm-project/pull/166916.diff

10 Files Affected:

  • (modified) clang/include/clang/Basic/DiagnosticDriverKinds.td (+3)
  • (modified) clang/include/clang/Basic/DiagnosticFrontendKinds.td (+3)
  • (modified) clang/lib/Frontend/CompilerInvocation.cpp (+9-1)
  • (modified) clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp (+12-4)
  • (modified) clang/test/CIR/CodeGen/builtin_prefetch.c (+2-2)
  • (modified) clang/test/CIR/CodeGen/dlti.c (+1-1)
  • (modified) clang/test/CIR/CodeGen/dlti_be.c (+1-1)
  • (modified) clang/test/CIR/CodeGen/module-asm.c (+1-1)
  • (added) clang/test/Driver/cir-flags-error.c (+11)
  • (added) clang/test/Driver/cir-input-without-fclangir.cir (+20)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 83980e3ac35b7..c47c2e5d42b90 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -887,6 +887,9 @@ def warn_missing_include_dirs : Warning<
 def err_drv_malformed_warning_suppression_mapping : Error<
   "failed to process suppression mapping file '%0': %1">;
 
+def err_drv_emit_cir_without_fclangir : Error<
+  "-emit-cir is only valid with -fclangir">;
+
 def warn_drv_openacc_without_cir
     : Warning<"OpenACC directives will result in no runtime behavior; use "
               "-fclangir to enable runtime effect">,
diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 9e344160ff934..1ebea11dd5259 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -136,6 +136,9 @@ def err_fe_action_not_available : Error<
     "action %0 not compiled in">;
 def err_fe_cir_not_built : Error<"clang IR support not available, rebuild "
                                  "clang with -DCLANG_ENABLE_CIR=ON">;
+def err_fe_cir_disabled : Error<
+  "trying to compile CIR module %0 with clang IR disabled; use "
+  "-fclangir to enable CIR pipeline">;
 def err_fe_invalid_multiple_actions : Error<
     "'%0' action ignored; '%1' action specified previously">;
 def err_fe_invalid_alignment : Error<
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index be7c1d367e082..59dae34f0fd3d 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -3139,9 +3139,17 @@ 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_fclangir) || Args.hasArg(OPT_emit_cir))
+  if (Args.hasArg(OPT_fclangir))
     Opts.UseClangIRPipeline = true;
 
+#if CLANG_ENABLE_CIR
+  if (!Args.hasArg(OPT_fclangir) && Args.hasArg(OPT_emit_cir))
+    Diags.Report(diag::err_drv_emit_cir_without_fclangir);
+#else
+  if (Args.hasArg(OPT_emit_cir))
+    Diags.Report(diag::err_fe_cir_not_built);
+#endif
+
 #if CLANG_ENABLE_CIR
   if (Args.hasArg(OPT_clangir_disable_passes))
     Opts.ClangIRDisablePasses = true;
diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index c8aad4daa1c10..25a89d465dcba 100644
--- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -49,12 +49,20 @@ CreateFrontendBaseAction(CompilerInstance &CI) {
   StringRef Action("unknown");
   (void)Action;
 
+#if CLANG_ENABLE_CIR
   unsigned UseCIR = CI.getFrontendOpts().UseClangIRPipeline;
-  frontend::ActionKind Act = CI.getFrontendOpts().ProgramAction;
-  bool EmitsCIR = Act == EmitCIR;
 
-  if (!UseCIR && EmitsCIR)
-    llvm::report_fatal_error("-emit-cir and only valid when using -fclangir");
+  if (!UseCIR) {
+    FrontendInputFile *it =
+        llvm::find_if(CI.getFrontendOpts().Inputs, [](const auto &FIF) {
+          return FIF.getKind().getLanguage() == Language::CIR;
+        });
+    if (it != CI.getFrontendOpts().Inputs.end()) {
+      CI.getDiagnostics().Report(diag::err_fe_cir_disabled) << it->getFile();
+      return nullptr;
+    }
+  }
+#endif
 
   switch (CI.getFrontendOpts().ProgramAction) {
   case ASTDeclList:            return std::make_unique<ASTDeclListAction>();
diff --git a/clang/test/CIR/CodeGen/builtin_prefetch.c b/clang/test/CIR/CodeGen/builtin_prefetch.c
index cfe85b9ba8104..c38e179617b1d 100644
--- a/clang/test/CIR/CodeGen/builtin_prefetch.c
+++ b/clang/test/CIR/CodeGen/builtin_prefetch.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s -check-prefix=CIR
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=LLVM
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s -check-prefix=OGCG
 
 void foo(void *a) {
   __builtin_prefetch(a);        // rw=0, locality=3
diff --git a/clang/test/CIR/CodeGen/dlti.c b/clang/test/CIR/CodeGen/dlti.c
index 3fa15d2ab584f..0e58a37756b75 100644
--- a/clang/test/CIR/CodeGen/dlti.c
+++ b/clang/test/CIR/CodeGen/dlti.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s --check-prefix=LITTLE
 
 void foo() {}
diff --git a/clang/test/CIR/CodeGen/dlti_be.c b/clang/test/CIR/CodeGen/dlti_be.c
index 918124ac0a237..b41e75466fe5f 100644
--- a/clang/test/CIR/CodeGen/dlti_be.c
+++ b/clang/test/CIR/CodeGen/dlti_be.c
@@ -1,5 +1,5 @@
 // REQUIRES: aarch64-registered-target
-// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-cir %s -o %t.cir
+// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -fclangir -emit-cir %s -o %t.cir
 // RUN: FileCheck --input-file=%t.cir %s --check-prefix=BIG
 
 void foo() {}
diff --git a/clang/test/CIR/CodeGen/module-asm.c b/clang/test/CIR/CodeGen/module-asm.c
index e6cec5e0ee948..049a90f69d393 100644
--- a/clang/test/CIR/CodeGen/module-asm.c
+++ b/clang/test/CIR/CodeGen/module-asm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-cir %s -o %t.cir 
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir 
 // RUN: FileCheck --input-file=%t.cir %s
 
 // CHECK:  cir.module_asm = [".globl bar", ".globl foo"]
diff --git a/clang/test/Driver/cir-flags-error.c b/clang/test/Driver/cir-flags-error.c
new file mode 100644
index 0000000000000..a76e3173fb33c
--- /dev/null
+++ b/clang/test/Driver/cir-flags-error.c
@@ -0,0 +1,11 @@
+// REQUIRES: cir-support
+
+// RUN: not %clang -emit-cir %s -o /dev/null 2>&1 | FileCheck %s -check-prefix=EMIT_CIR_ERROR
+// EMIT_CIR_ERROR: error: -emit-cir is only valid with -fclangir
+
+// RUN: %clang -fclangir -emit-cir %s -o /dev/null 2>&1 | FileCheck %s --allow-empty -check-prefix=EMIT_CIR_OK
+// EMIT_CIR_OK-NOT: error: -emit-cir is only valid with -fclangir
+
+int main(void) {
+  return 0;
+}
diff --git a/clang/test/Driver/cir-input-without-fclangir.cir b/clang/test/Driver/cir-input-without-fclangir.cir
new file mode 100644
index 0000000000000..2c4354511a322
--- /dev/null
+++ b/clang/test/Driver/cir-input-without-fclangir.cir
@@ -0,0 +1,20 @@
+// RUN: not %clang %s -emit-llvm -o /dev/null 2>&1 | FileCheck %s -check-prefix=CIR_INPUT_ERROR
+// CIR_INPUT_ERROR: error: trying to compile CIR module {{.*}} with clang IR disabled; use -fclangir to enable CIR pipeline
+
+// RUN: %clang -fclangir %s -emit-llvm -o /dev/null 2>&1 | FileCheck %s --allow-empty -check-prefix=CIR_INPUT_OK
+// CIR_INPUT_OK-NOT: error: trying to compile CIR module
+
+// REQUIRES: x86-registered-target
+// REQUIRES: cir-support
+
+!s32i = !cir.int<s, 32>
+
+module attributes {cir.lang = #cir.lang<cxx>, cir.triple = "x86_64-unknown-linux-gnu"} {
+  cir.func @test_function() -> !s32i {
+    %0 = cir.alloca !s32i, !cir.ptr<!s32i>, ["__retval"] {alignment = 4 : i64}
+    %1 = cir.const #cir.int<42> : !s32i
+    cir.store %1, %0 : !s32i, !cir.ptr<!s32i>
+    %2 = cir.load %0 : !cir.ptr<!s32i>, !s32i
+    cir.return %2 : !s32i
+  }
+}

Copy link
Contributor

@andykaylor andykaylor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the use case you're preparing for here. If I have this command line:

clang -emit-cir foo.cpp bar.cir

This will produce an error, saying I can't use -emit-cir without -fclangir, right? What's the case where this is useful?

if (!Args.hasArg(OPT_fclangir) && Args.hasArg(OPT_emit_cir))
Diags.Report(diag::err_drv_emit_cir_without_fclangir);
#else
if (Args.hasArg(OPT_emit_cir))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also report an error if -fclangir is used in this case. Currently, we silently do nothing.

@mmha
Copy link
Contributor Author

mmha commented Nov 7, 2025

I mostly wondered about the expected behavior in these cases:

clang foo.cpp bar.cir
clang -emit-cir foo.cpp bar.cir
clang -emit-llvm foo.cpp bar.cir

I wouldn't want the presence of a .cir file to implicitly change the pipeline of the other files. But in ExecuteCompilerInvocation.cpp we need to decide whether to enable CIR or not based on all input files. So I was looking for ways to make the enablement of CIR more explicit.

To me -emit-cir means "dump the IR" and not "change the pipeline, then dump the IR". I think it's better to require two separate flags. If no CIR is generated during compilation this shouldn't do anything, just like -emit-ast errors out for LLVM IR files.

This patch isn't necessary for enable CIR as a source lang but note the llvm::report_fatal_error("-emit-cir and only valid when using -fclangir"); line I deleted. This was dead code but the string suggests this was the intended behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category ClangIR Anything related to the ClangIR project

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants