https://github.com/bcardosolopes updated https://github.com/llvm/llvm-project/pull/214904
>From 5d776418dd01b380e854a8e78eff62ce9d828f89 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes <[email protected]> Date: Fri, 7 Aug 2026 17:44:25 -0700 Subject: [PATCH 1/2] [CIR] Honor -fno-clangir -fno-clangir was a no-op whenever -fclangir also appeared on the command line, in either order: the CIR pipeline ran regardless. Options.td already declares clangir as a BoolFOption with a NegFlag, so last-wins semantics were intended and the generated marshalling implements them correctly. Two consumers bypassed it: - The driver tested Args.hasArg(OPT_fclangir), a presence check that never looks at the negation, and forwarded -fclangir to -cc1 unconditionally. - ParseFrontendArgs then set Opts.UseClangIRPipeline = true under the same presence check, clobbering the value the marshalling had already computed from both flags a few lines earlier. Use hasFlag() in the driver, and drop the redundant frontend override. -emit-cir still forces the pipeline on, since it is an action that requires it. Beyond the stated flag semantics, this matters for A/B testing: appending -fno-clangir to a -fclangir build to produce a "CIR off" arm silently produced a second CIR build instead. --- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- clang/lib/Frontend/CompilerInvocation.cpp | 5 ++++- clang/test/CIR/Driver/clangir.c | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 85fe99dbf8b69..ec1ad05497751 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -5332,7 +5332,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, } } - if (Args.hasArg(options::OPT_fclangir)) + if (Args.hasFlag(options::OPT_fclangir, options::OPT_fno_clangir, false)) CmdArgs.push_back("-fclangir"); if (IsOpenMPDevice) { diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 6562cb3a9b135..4f319f11e7cb6 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3172,7 +3172,10 @@ 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)) + // -fclangir/-fno-clangir are marshalled into Opts.UseClangIRPipeline above, + // which already gives them last-wins semantics; don't clobber that here. + // -emit-cir is an action that implies the pipeline regardless. + if (Args.hasArg(OPT_emit_cir)) Opts.UseClangIRPipeline = true; #if CLANG_ENABLE_CIR diff --git a/clang/test/CIR/Driver/clangir.c b/clang/test/CIR/Driver/clangir.c index afbe6c6d2388f..d8419d8812f62 100644 --- a/clang/test/CIR/Driver/clangir.c +++ b/clang/test/CIR/Driver/clangir.c @@ -15,4 +15,27 @@ // LLVMIR: "-cc1" // LLVMIR-SAME: "-fclangir" +// -fclangir and -fno-clangir are last-wins, in either order. + +// RUN: %clang -### -fclangir -fno-clangir -S %s 2>&1 | FileCheck %s --check-prefix=NEG +// RUN: %clang -### -fno-clangir -S %s 2>&1 | FileCheck %s --check-prefix=NEG +// NEG: "-cc1" +// NEG-NOT: "-fclangir" + +// RUN: %clang -### -fno-clangir -fclangir -S %s 2>&1 | FileCheck %s --check-prefix=POS +// POS: "-cc1" +// POS-SAME: "-fclangir" + +// The frontend must honor the negation too, not just the driver. -fopenacc +// warns only when the CIR pipeline is off, which makes UseClangIRPipeline +// observable at -cc1. + +// RUN: %clang_cc1 -fopenacc -fclangir -fno-clangir -emit-llvm-only %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CC1-OFF +// CC1-OFF: use -fclangir to enable runtime effect + +// RUN: %clang_cc1 -fopenacc -fno-clangir -fclangir -emit-llvm-only %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CC1-ON --allow-empty +// CC1-ON-NOT: use -fclangir to enable runtime effect + void foo() {} >From 872fcfa58d449dee32757c4abb8997750b0d99b5 Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes <[email protected]> Date: Mon, 10 Aug 2026 10:39:57 -0700 Subject: [PATCH 2/2] [CIR] Drop the -fno-clangir marshalling comment Addresses review feedback on the -fno-clangir fix: the comment restated what the BoolFOption marshalling already does, so it was noise. --- clang/lib/Frontend/CompilerInvocation.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 4f319f11e7cb6..8b6b64be38709 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3172,9 +3172,6 @@ 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"; - // -fclangir/-fno-clangir are marshalled into Opts.UseClangIRPipeline above, - // which already gives them last-wins semantics; don't clobber that here. - // -emit-cir is an action that implies the pipeline regardless. if (Args.hasArg(OPT_emit_cir)) Opts.UseClangIRPipeline = true; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
