[clang] fde240c - [HLSL][clang][Driver] Parse target profile early to update Driver::TargetTriple.
Xiang Li via cfe-commits
cfe-commits at lists.llvm.org
Tue May 31 13:23:37 PDT 2022
Author: Xiang Li
Date: 2022-05-31T13:23:30-07:00
New Revision: fde240c9c328b8a824a064c8ccd91252516e6d41
URL: https://github.com/llvm/llvm-project/commit/fde240c9c328b8a824a064c8ccd91252516e6d41
DIFF: https://github.com/llvm/llvm-project/commit/fde240c9c328b8a824a064c8ccd91252516e6d41.diff
LOG: [HLSL][clang][Driver] Parse target profile early to update Driver::TargetTriple.
This is to avoid err_target_unknown_abi which is caused by use default TargetTriple instead of shader model target triple.
Reviewed By: beanz
Differential Revision: https://reviews.llvm.org/D125585
Added:
Modified:
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/lib/Driver/Driver.cpp
clang/lib/Driver/ToolChains/HLSL.cpp
clang/lib/Driver/ToolChains/HLSL.h
clang/test/Driver/dxc_fcgl.hlsl
clang/unittests/Driver/ToolChainTest.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 9f4864a33a33b..618e748da4441 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -666,6 +666,8 @@ def err_drv_target_variant_invalid : Error<
def err_drv_invalid_directx_shader_module : Error<
"invalid profile : %0">;
+def err_drv_dxc_missing_target_profile : Error<
+ "target profile option (-T) is missing">;
def err_drv_invalid_range_dxil_validator_version : Error<
"invalid validator version : %0\n"
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index aaef2e1ded327..3185ebcd46a4e 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -1236,11 +1236,19 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
T.setObjectFormat(llvm::Triple::COFF);
TargetTriple = T.str();
} else if (IsDXCMode()) {
- // clang-dxc target is build from target_profile option.
- // Just set OS to shader model to select HLSLToolChain.
- llvm::Triple T(TargetTriple);
- T.setOS(llvm::Triple::ShaderModel);
- TargetTriple = T.str();
+ // Build TargetTriple from target_profile option for clang-dxc.
+ if (const Arg *A = Args.getLastArg(options::OPT_target_profile)) {
+ StringRef TargetProfile = A->getValue();
+ if (auto Triple =
+ toolchains::HLSLToolChain::parseTargetProfile(TargetProfile))
+ TargetTriple = Triple.getValue();
+ else
+ Diag(diag::err_drv_invalid_directx_shader_module) << TargetProfile;
+
+ A->claim();
+ } else {
+ Diag(diag::err_drv_dxc_missing_target_profile);
+ }
}
if (const Arg *A = Args.getLastArg(options::OPT_target))
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index b62395b168ea4..c2b55fdde4b4c 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -64,12 +64,12 @@ bool isLegalShaderModel(Triple &T) {
return false;
}
-std::string tryParseProfile(StringRef Profile) {
+llvm::Optional<std::string> tryParseProfile(StringRef Profile) {
// [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
SmallVector<StringRef, 3> Parts;
Profile.split(Parts, "_");
if (Parts.size() != 3)
- return "";
+ return NoneType();
Triple::EnvironmentType Kind =
StringSwitch<Triple::EnvironmentType>(Parts[0])
@@ -84,17 +84,17 @@ std::string tryParseProfile(StringRef Profile) {
.Case("as", Triple::EnvironmentType::Amplification)
.Default(Triple::EnvironmentType::UnknownEnvironment);
if (Kind == Triple::EnvironmentType::UnknownEnvironment)
- return "";
+ return NoneType();
unsigned long long Major = 0;
if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
- return "";
+ return NoneType();
unsigned long long Minor = 0;
if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
Minor = OfflineLibMinor;
else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
- return "";
+ return NoneType();
// dxil-unknown-shadermodel-hull
llvm::Triple T;
@@ -105,7 +105,7 @@ std::string tryParseProfile(StringRef Profile) {
if (isLegalShaderModel(T))
return T.getTriple();
else
- return "";
+ return NoneType();
}
bool isLegalValidatorVersion(StringRef ValVersionStr, const Driver &D) {
@@ -138,21 +138,10 @@ HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
: ToolChain(D, Triple, Args) {}
-std::string
-HLSLToolChain::ComputeEffectiveClangTriple(const ArgList &Args,
- types::ID InputType) const {
- if (Arg *A = Args.getLastArg(options::OPT_target_profile)) {
- StringRef Profile = A->getValue();
- std::string Triple = tryParseProfile(Profile);
- if (Triple == "") {
- getDriver().Diag(diag::err_drv_invalid_directx_shader_module) << Profile;
- Triple = ToolChain::ComputeEffectiveClangTriple(Args, InputType);
- }
- A->claim();
- return Triple;
- } else {
- return ToolChain::ComputeEffectiveClangTriple(Args, InputType);
- }
+llvm::Optional<std::string>
+clang::driver::toolchains::HLSLToolChain::parseTargetProfile(
+ StringRef TargetProfile) {
+ return tryParseProfile(TargetProfile);
}
DerivedArgList *
diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h
index 7774db3762dd3..5573b0cc69e25 100644
--- a/clang/lib/Driver/ToolChains/HLSL.h
+++ b/clang/lib/Driver/ToolChains/HLSL.h
@@ -29,8 +29,8 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain {
llvm::opt::DerivedArgList *
TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch,
Action::OffloadKind DeviceOffloadKind) const override;
- std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args,
- types::ID InputType) const override;
+ static llvm::Optional<std::string>
+ parseTargetProfile(StringRef TargetProfile);
};
} // end namespace toolchains
diff --git a/clang/test/Driver/dxc_fcgl.hlsl b/clang/test/Driver/dxc_fcgl.hlsl
index d3eb2523199ca..782dfaa1e0e55 100644
--- a/clang/test/Driver/dxc_fcgl.hlsl
+++ b/clang/test/Driver/dxc_fcgl.hlsl
@@ -1,4 +1,4 @@
-// RUN: %clang_dxc -fcgl foo.hlsl -### %s 2>&1 | FileCheck %s
+// RUN: %clang_dxc -fcgl -T lib_6_7 foo.hlsl -### %s 2>&1 | FileCheck %s
// Make sure fcgl option flag which translated into "-S" "-emit-llvm" "-disable-llvm-passes".
// CHECK:"-S" "-emit-llvm" "-disable-llvm-passes"
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index c652b093dc993..f412c35695549 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -387,6 +387,28 @@ struct SimpleDiagnosticConsumer : public DiagnosticConsumer {
std::vector<SmallString<32>> Errors;
};
+static void validateTargetProfile(StringRef TargetProfile,
+ StringRef ExpectTriple, Driver &TheDriver,
+ DiagnosticsEngine &Diags) {
+ EXPECT_TRUE(TheDriver.BuildCompilation(
+ {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl"}));
+ EXPECT_STREQ(TheDriver.getTargetTriple().c_str(), ExpectTriple.data());
+ EXPECT_EQ(Diags.getNumErrors(), 0u);
+}
+
+static void validateTargetProfile(StringRef TargetProfile,
+ StringRef ExpectError, Driver &TheDriver,
+ DiagnosticsEngine &Diags,
+ SimpleDiagnosticConsumer *DiagConsumer,
+ unsigned NumOfErrors) {
+ EXPECT_TRUE(TheDriver.BuildCompilation(
+ {"clang", "--driver-mode=dxc", TargetProfile.data(), "foo.hlsl"}));
+ EXPECT_EQ(Diags.getNumErrors(), NumOfErrors);
+ EXPECT_STREQ(DiagConsumer->Errors.back().c_str(), ExpectError.data());
+ Diags.Clear();
+ DiagConsumer->clear();
+}
+
TEST(DxcModeTest, TargetProfileValidation) {
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
@@ -400,111 +422,40 @@ TEST(DxcModeTest, TargetProfileValidation) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
- std::unique_ptr<Compilation> C(
- TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"}));
- EXPECT_TRUE(C);
- EXPECT_TRUE(!C->containsError());
-
- auto &TC = C->getDefaultToolChain();
- bool ContainsError = false;
- auto Args = TheDriver.ParseArgStrings({"-Tvs_6_0"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- auto Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.0-vertex");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Ths_6_1"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.1-hull");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tds_6_2"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.2-domain");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tgs_6_3"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.3-geometry");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tps_6_4"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.4-pixel");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tcs_6_5"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.5-compute");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tms_6_6"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.6-mesh");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
- Args = TheDriver.ParseArgStrings({"-Tas_6_7"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.7-amplification");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
-
- Args = TheDriver.ParseArgStrings({"-Tlib_6_x"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "dxil--shadermodel6.15-library");
- EXPECT_EQ(Diags.getNumErrors(), 0u);
+ validateTargetProfile("-Tvs_6_0", "dxil--shadermodel6.0-vertex", TheDriver,
+ Diags);
+ validateTargetProfile("-Ths_6_1", "dxil--shadermodel6.1-hull", TheDriver,
+ Diags);
+ validateTargetProfile("-Tds_6_2", "dxil--shadermodel6.2-domain", TheDriver,
+ Diags);
+ validateTargetProfile("-Tds_6_2", "dxil--shadermodel6.2-domain", TheDriver,
+ Diags);
+ validateTargetProfile("-Tgs_6_3", "dxil--shadermodel6.3-geometry", TheDriver,
+ Diags);
+ validateTargetProfile("-Tps_6_4", "dxil--shadermodel6.4-pixel", TheDriver,
+ Diags);
+ validateTargetProfile("-Tcs_6_5", "dxil--shadermodel6.5-compute", TheDriver,
+ Diags);
+ validateTargetProfile("-Tms_6_6", "dxil--shadermodel6.6-mesh", TheDriver,
+ Diags);
+ validateTargetProfile("-Tas_6_7", "dxil--shadermodel6.7-amplification",
+ TheDriver, Diags);
+ validateTargetProfile("-Tlib_6_x", "dxil--shadermodel6.15-library", TheDriver,
+ Diags);
// Invalid tests.
- Args = TheDriver.ParseArgStrings({"-Tpss_6_1"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
- EXPECT_EQ(Diags.getNumErrors(), 1u);
- EXPECT_STREQ(DiagConsumer->Errors.back().c_str(),
- "invalid profile : pss_6_1");
- Diags.Clear();
- DiagConsumer->clear();
-
- Args = TheDriver.ParseArgStrings({"-Tps_6_x"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
- EXPECT_EQ(Diags.getNumErrors(), 2u);
- EXPECT_STREQ(DiagConsumer->Errors.back().c_str(), "invalid profile : ps_6_x");
- Diags.Clear();
- DiagConsumer->clear();
-
- Args = TheDriver.ParseArgStrings({"-Tlib_6_1"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
- EXPECT_EQ(Diags.getNumErrors(), 3u);
- EXPECT_STREQ(DiagConsumer->Errors.back().c_str(),
- "invalid profile : lib_6_1");
- Diags.Clear();
- DiagConsumer->clear();
-
- Args = TheDriver.ParseArgStrings({"-Tfoo"}, false, ContainsError);
- EXPECT_FALSE(ContainsError);
- Triple = TC.ComputeEffectiveClangTriple(Args);
- EXPECT_STREQ(Triple.c_str(), "unknown-unknown-shadermodel");
- EXPECT_EQ(Diags.getNumErrors(), 4u);
- EXPECT_STREQ(DiagConsumer->Errors.back().c_str(), "invalid profile : foo");
- Diags.Clear();
- DiagConsumer->clear();
+ validateTargetProfile("-Tpss_6_1", "invalid profile : pss_6_1", TheDriver,
+ Diags, DiagConsumer, 1);
+
+ validateTargetProfile("-Tps_6_x", "invalid profile : ps_6_x", TheDriver,
+ Diags, DiagConsumer, 2);
+ validateTargetProfile("-Tlib_6_1", "invalid profile : lib_6_1", TheDriver,
+ Diags, DiagConsumer, 3);
+ validateTargetProfile("-Tfoo", "invalid profile : foo", TheDriver, Diags,
+ DiagConsumer, 4);
+ validateTargetProfile("", "target profile option (-T) is missing", TheDriver,
+ Diags, DiagConsumer, 5);
}
TEST(DxcModeTest, ValidatorVersionValidation) {
@@ -520,8 +471,8 @@ TEST(DxcModeTest, ValidatorVersionValidation) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagConsumer);
Driver TheDriver("/bin/clang", "", Diags, "", InMemoryFileSystem);
- std::unique_ptr<Compilation> C(
- TheDriver.BuildCompilation({"clang", "--driver-mode=dxc", "foo.hlsl"}));
+ std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(
+ {"clang", "--driver-mode=dxc", "-Tlib_6_7", "foo.hlsl"}));
EXPECT_TRUE(C);
EXPECT_TRUE(!C->containsError());
More information about the cfe-commits
mailing list