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 + } +} 
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

2 participants