diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6736,6 +6736,8 @@ def dxc_Group : OptionGroup<"">, Flags<[DXCOption]>, HelpText<"dxc compatibility options">; +class DXCFlag : Option<["/", "-"], name, KIND_FLAG>, + Group, Flags<[DXCOption, NoXarchOption]>; class DXCJoinedOrSeparate : Option<["/", "-"], name, KIND_JOINED_OR_SEPARATE>, Group, Flags<[DXCOption, NoXarchOption]>; @@ -6760,3 +6762,5 @@ "lib_6_3, lib_6_4, lib_6_5, lib_6_6, lib_6_7, lib_6_x," "ms_6_5, ms_6_6, ms_6_7," "as_6_5, as_6_6, as_6_7">; +def fcgl : DXCFlag<"fcgl">, + HelpText<"Generate high-level code only. Without any dxil related passes.">; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3470,7 +3470,9 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs, types::ID InputType) { - const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version}; + const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version, + options::OPT_S, options::OPT_emit_llvm, + options::OPT_disable_llvm_passes}; for (const auto &Arg : ForwardedArguments) if (const auto *A = Args.getLastArg(Arg)) diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -169,6 +169,15 @@ if (!isLegalValidatorVersion(ValVerStr, getDriver())) continue; } + if (A->getOption().getID() == options::OPT_fcgl) { + // Translate fcgl into -S -emit-llvm and -disable-llvm-passes. + DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_S)); + DAL->AddFlagArg(nullptr, Opts.getOption(options::OPT_emit_llvm)); + DAL->AddFlagArg(nullptr, + Opts.getOption(options::OPT_disable_llvm_passes)); + A->claim(); + continue; + } DAL->append(A); } // Add default validator version if not set. diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp --- a/clang/unittests/Driver/ToolChainTest.cpp +++ b/clang/unittests/Driver/ToolChainTest.cpp @@ -610,4 +610,45 @@ DiagConsumer->clear(); } +TEST(DxcModeTest, ValidatorFCGL) { + IntrusiveRefCntPtr DiagID(new DiagnosticIDs()); + + IntrusiveRefCntPtr InMemoryFileSystem( + new llvm::vfs::InMemoryFileSystem); + + InMemoryFileSystem->addFile("foo.hlsl", 0, + llvm::MemoryBuffer::getMemBuffer("\n")); + + auto *DiagConsumer = new SimpleDiagnosticConsumer; + IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); + DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer); + Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem); + std::unique_ptr C(TheDriver.BuildCompilation( + {"clang", "--driver-mode=dxc", "-fcgl", "foo.hlsl"})); + EXPECT_TRUE(C); + EXPECT_TRUE(!C->containsError()); + auto &Jobs = C->getJobs(); + EXPECT_EQ(Jobs.size(), 1); + if (Jobs.size() == 1) { + auto &Job = *Jobs.begin(); + auto &Args = Job.getArguments(); + // Make sure fcgl translated into -S -emit-llvm and -disable-llvm-passes. + bool HasS = false; + bool HasEmitLLVM = false; + bool HasDisableLLVMPasses = false; + for (auto *Arg : Args) { + StringRef Str(Arg); + if (Str == "-S") + HasS = true; + else if (Str == "-emit-llvm") + HasEmitLLVM = true; + else if (Str == "-disable-llvm-passes") + HasDisableLLVMPasses = true; + } + EXPECT_TRUE(HasS); + EXPECT_TRUE(HasEmitLLVM); + EXPECT_TRUE(HasDisableLLVMPasses); + } +} + } // end anonymous namespace.