[clang] [HLSL] Add validation for the -enable-16bit-types option (PR #85340)
Joshua Batista via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 18 15:41:30 PDT 2024
https://github.com/bob80905 updated https://github.com/llvm/llvm-project/pull/85340
>From 3cdcfa4e63550b9677c8ffe2f33eab85899b2c45 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 14 Mar 2024 17:04:12 -0700
Subject: [PATCH 1/5] add test
---
.../clang/Basic/DiagnosticDriverKinds.td | 3 +-
clang/lib/Driver/ToolChains/HLSL.cpp | 86 ++++++++++++++++---
2 files changed, 74 insertions(+), 15 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index e33a1f4c45b949..fae9132bd0a9c9 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -753,7 +753,8 @@ def err_drv_hlsl_unsupported_target : Error<
"HLSL code generation is unsupported for target '%0'">;
def err_drv_hlsl_bad_shader_required_in_target : Error<
"%select{shader model|Vulkan environment|shader stage}0 is required as %select{OS|environment}1 in target '%2' for HLSL code generation">;
-
+def err_drv_hlsl_enable_16bit_types_option_invalid: Error<
+ "enable_16bit_types option only valid when target shader model [-T] is >= 6.2 and Hlsl Version [-HV] is >= 2021">;
def err_drv_hlsl_bad_shader_unsupported : Error<
"%select{shader model|Vulkan environment|shader stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
def warn_drv_dxc_missing_dxv : Warning<"dxv not found. "
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index 05aac9caa7fb29..bf8fc42a27816c 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -66,15 +66,48 @@ bool isLegalShaderModel(Triple &T) {
return false;
}
-std::optional<std::string> tryParseProfile(StringRef Profile) {
- // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
+struct ShaderModel {
+ StringRef TargetKind;
+ unsigned Major;
+ unsigned Minor;
+ bool OfflineLibMinor = false;
+};
+
+std::optional<ShaderModel> GetShaderModelFromString(StringRef Profile) {
SmallVector<StringRef, 3> Parts;
Profile.split(Parts, "_");
if (Parts.size() != 3)
return std::nullopt;
+ unsigned long long Major = 0;
+ if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
+ return std::nullopt;
+
+ unsigned long long Minor = 0;
+ bool isOfflineLibMinor = false;
+ if (Parts[0] == "lib" && Parts[2] == "x")
+ isOfflineLibMinor = true;
+ else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
+ return std::nullopt;
+
+ ShaderModel ret;
+ ret.TargetKind = Parts[0];
+ ret.Major = Major;
+ ret.Minor = Minor;
+ ret.OfflineLibMinor = isOfflineLibMinor;
+
+ return ret;
+}
+
+std::optional<std::string> tryParseProfile(StringRef Profile) {
+ std::optional<ShaderModel> SM = GetShaderModelFromString(Profile);
+ if (!SM.has_value()) {
+ return std::nullopt;
+ }
+ // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
+
Triple::EnvironmentType Kind =
- StringSwitch<Triple::EnvironmentType>(Parts[0])
+ StringSwitch<Triple::EnvironmentType>(SM.value().TargetKind)
.Case("ps", Triple::EnvironmentType::Pixel)
.Case("vs", Triple::EnvironmentType::Vertex)
.Case("gs", Triple::EnvironmentType::Geometry)
@@ -88,21 +121,11 @@ std::optional<std::string> tryParseProfile(StringRef Profile) {
if (Kind == Triple::EnvironmentType::UnknownEnvironment)
return std::nullopt;
- unsigned long long Major = 0;
- if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
- return std::nullopt;
-
- unsigned long long Minor = 0;
- if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
- Minor = OfflineLibMinor;
- else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
- return std::nullopt;
-
// dxil-unknown-shadermodel-hull
llvm::Triple T;
T.setArch(Triple::ArchType::dxil);
T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
- VersionTuple(Major, Minor).getAsString());
+ VersionTuple(SM.value().Major, SM.value().Minor).getAsString());
T.setEnvironment(Kind);
if (isLegalShaderModel(T))
return T.getTriple();
@@ -258,6 +281,41 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
// FIXME: add validation for enable_16bit_types should be after HLSL 2018 and
// shader model 6.2.
// See: https://github.com/llvm/llvm-project/issues/57876
+ if (DAL->hasArg(options::OPT_fnative_half_type)) {
+
+ bool HVArgIsValid = true;
+ bool TPArgIsValid = true;
+
+ const StringRef HVArg =
+ DAL->getLastArgValue(options::OPT_std_EQ, "hlsl2021");
+
+ const StringRef TPArg =
+ DAL->getLastArgValue(options::OPT_target_profile, "");
+ std::optional<ShaderModel> parsedTargetProfile =
+ GetShaderModelFromString(TPArg);
+
+ unsigned long long HV_year;
+ StringRef HV_year_str = HVArg.drop_front(4);
+ if (HV_year_str != "202x") {
+ llvm::getAsUnsignedInteger(HV_year_str, 0, HV_year);
+ if (HV_year < 2021)
+ HVArgIsValid = false;
+ }
+
+ if (!parsedTargetProfile.has_value())
+ return DAL;
+ else {
+ if (parsedTargetProfile.value().Major < 6 ||
+ (parsedTargetProfile.value().Major == 6 &&
+ parsedTargetProfile.value().Minor < 2))
+ TPArgIsValid = false;
+ }
+
+ // if the HLSL Version is not at least 2021, or the shader model is not at
+ // least 6.2, then enable-16bit-types is an invalid flag.
+ if (!(HVArgIsValid && TPArgIsValid))
+ getDriver().Diag(diag::err_drv_hlsl_enable_16bit_types_option_invalid);
+ }
return DAL;
}
>From a92520b33b0f84fdab984ce9506c98bf82096e5c Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Thu, 14 Mar 2024 17:17:04 -0700
Subject: [PATCH 2/5] add helpful comment that a condition is unreachable
---
clang/lib/Driver/ToolChains/HLSL.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index bf8fc42a27816c..0b7b101f4a8cb9 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -303,6 +303,8 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
}
if (!parsedTargetProfile.has_value())
+ // This should be unreachable, target profile validation happens
+ // before this point.
return DAL;
else {
if (parsedTargetProfile.value().Major < 6 ||
>From a32796eaf527f34dd440f9b31c272d4b033f8f59 Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Fri, 15 Mar 2024 12:53:47 -0700
Subject: [PATCH 3/5] add test, remove fixme comment
---
clang/lib/Driver/ToolChains/HLSL.cpp | 4 +---
.../enable_16bit_types_validation.hlsl | 19 +++++++++++++++++++
2 files changed, 20 insertions(+), 3 deletions(-)
create mode 100644 clang/test/Options/enable_16bit_types_validation.hlsl
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index 0b7b101f4a8cb9..35422df2b34fea 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -278,9 +278,7 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
if (!DAL->hasArg(options::OPT_O_Group)) {
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
}
- // FIXME: add validation for enable_16bit_types should be after HLSL 2018 and
- // shader model 6.2.
- // See: https://github.com/llvm/llvm-project/issues/57876
+
if (DAL->hasArg(options::OPT_fnative_half_type)) {
bool HVArgIsValid = true;
diff --git a/clang/test/Options/enable_16bit_types_validation.hlsl b/clang/test/Options/enable_16bit_types_validation.hlsl
new file mode 100644
index 00000000000000..ad97e68cc60abf
--- /dev/null
+++ b/clang/test/Options/enable_16bit_types_validation.hlsl
@@ -0,0 +1,19 @@
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 2016 %s 2>&1 -### | FileCheck -check-prefix=both_invalid %s
+// RUN: not %clang_dxc -enable-16bit-types -T lib_6_4 -HV 2017 %s 2>&1 -### | FileCheck -check-prefix=HV_invalid %s
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=TP_invalid %s
+// RUN: %clang_dxc -enable-16bit-types -T lib_6_4 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=valid %ss
+
+
+// both_invalid: error: enable_16bit_types option only valid when target shader model [-T] is >= 6.2 and Hlsl Version [-HV] is >= 2021
+// HV_invalid: error: enable_16bit_types option only valid when target shader model [-T] is >= 6.2 and Hlsl Version [-HV] is >= 2021
+// TP_invalid: error: enable_16bit_types option only valid when target shader model [-T] is >= 6.2 and Hlsl Version [-HV] is >= 2021
+// valid: "dxil-unknown-shadermodel6.4-library"
+// valid-SAME: "-std=hlsl2021"
+// valid-SAME: "-fnative-half-type"
+
+[numthreads(1,1,1)]
+void main()
+{
+ return;
+}
+
>From dd726977e23b8670cbf208b505524d00c958d32e Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 18 Mar 2024 13:50:36 -0700
Subject: [PATCH 4/5] fix test typo
---
clang/test/Options/enable_16bit_types_validation.hlsl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/Options/enable_16bit_types_validation.hlsl b/clang/test/Options/enable_16bit_types_validation.hlsl
index ad97e68cc60abf..205383c01b5ae4 100644
--- a/clang/test/Options/enable_16bit_types_validation.hlsl
+++ b/clang/test/Options/enable_16bit_types_validation.hlsl
@@ -1,7 +1,7 @@
// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 2016 %s 2>&1 -### | FileCheck -check-prefix=both_invalid %s
// RUN: not %clang_dxc -enable-16bit-types -T lib_6_4 -HV 2017 %s 2>&1 -### | FileCheck -check-prefix=HV_invalid %s
// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=TP_invalid %s
-// RUN: %clang_dxc -enable-16bit-types -T lib_6_4 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=valid %ss
+// RUN: %clang_dxc -enable-16bit-types -T lib_6_4 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=valid %s
// both_invalid: error: enable_16bit_types option only valid when target shader model [-T] is >= 6.2 and Hlsl Version [-HV] is >= 2021
>From 6b2f0dfd24e9a8ab32a1d1353a693571444e610f Mon Sep 17 00:00:00 2001
From: Joshua Batista <jbatista at microsoft.com>
Date: Mon, 18 Mar 2024 15:41:14 -0700
Subject: [PATCH 5/5] move implementation to compilerinvocation, adjust test
---
clang/lib/Driver/ToolChains/HLSL.cpp | 88 +++----------------
clang/lib/Frontend/CompilerInvocation.cpp | 12 +++
.../enable_16bit_types_validation.hlsl | 6 +-
3 files changed, 29 insertions(+), 77 deletions(-)
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp
index 35422df2b34fea..1169b5d8c92dd6 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -66,48 +66,15 @@ bool isLegalShaderModel(Triple &T) {
return false;
}
-struct ShaderModel {
- StringRef TargetKind;
- unsigned Major;
- unsigned Minor;
- bool OfflineLibMinor = false;
-};
-
-std::optional<ShaderModel> GetShaderModelFromString(StringRef Profile) {
+std::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 std::nullopt;
- unsigned long long Major = 0;
- if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
- return std::nullopt;
-
- unsigned long long Minor = 0;
- bool isOfflineLibMinor = false;
- if (Parts[0] == "lib" && Parts[2] == "x")
- isOfflineLibMinor = true;
- else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
- return std::nullopt;
-
- ShaderModel ret;
- ret.TargetKind = Parts[0];
- ret.Major = Major;
- ret.Minor = Minor;
- ret.OfflineLibMinor = isOfflineLibMinor;
-
- return ret;
-}
-
-std::optional<std::string> tryParseProfile(StringRef Profile) {
- std::optional<ShaderModel> SM = GetShaderModelFromString(Profile);
- if (!SM.has_value()) {
- return std::nullopt;
- }
- // [ps|vs|gs|hs|ds|cs|ms|as]_[major]_[minor]
-
Triple::EnvironmentType Kind =
- StringSwitch<Triple::EnvironmentType>(SM.value().TargetKind)
+ StringSwitch<Triple::EnvironmentType>(Parts[0])
.Case("ps", Triple::EnvironmentType::Pixel)
.Case("vs", Triple::EnvironmentType::Vertex)
.Case("gs", Triple::EnvironmentType::Geometry)
@@ -121,11 +88,21 @@ std::optional<std::string> tryParseProfile(StringRef Profile) {
if (Kind == Triple::EnvironmentType::UnknownEnvironment)
return std::nullopt;
+ unsigned long long Major = 0;
+ if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
+ return std::nullopt;
+
+ unsigned long long Minor = 0;
+ if (Parts[2] == "x" && Kind == Triple::EnvironmentType::Library)
+ Minor = OfflineLibMinor;
+ else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
+ return std::nullopt;
+
// dxil-unknown-shadermodel-hull
llvm::Triple T;
T.setArch(Triple::ArchType::dxil);
T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
- VersionTuple(SM.value().Major, SM.value().Minor).getAsString());
+ VersionTuple(Major, Minor).getAsString());
T.setEnvironment(Kind);
if (isLegalShaderModel(T))
return T.getTriple();
@@ -279,43 +256,6 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
}
- if (DAL->hasArg(options::OPT_fnative_half_type)) {
-
- bool HVArgIsValid = true;
- bool TPArgIsValid = true;
-
- const StringRef HVArg =
- DAL->getLastArgValue(options::OPT_std_EQ, "hlsl2021");
-
- const StringRef TPArg =
- DAL->getLastArgValue(options::OPT_target_profile, "");
- std::optional<ShaderModel> parsedTargetProfile =
- GetShaderModelFromString(TPArg);
-
- unsigned long long HV_year;
- StringRef HV_year_str = HVArg.drop_front(4);
- if (HV_year_str != "202x") {
- llvm::getAsUnsignedInteger(HV_year_str, 0, HV_year);
- if (HV_year < 2021)
- HVArgIsValid = false;
- }
-
- if (!parsedTargetProfile.has_value())
- // This should be unreachable, target profile validation happens
- // before this point.
- return DAL;
- else {
- if (parsedTargetProfile.value().Major < 6 ||
- (parsedTargetProfile.value().Major == 6 &&
- parsedTargetProfile.value().Minor < 2))
- TPArgIsValid = false;
- }
-
- // if the HLSL Version is not at least 2021, or the shader model is not at
- // least 6.2, then enable-16bit-types is an invalid flag.
- if (!(HVArgIsValid && TPArgIsValid))
- getDriver().Diag(diag::err_drv_hlsl_enable_16bit_types_option_invalid);
- }
return DAL;
}
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 451bdb9386f587..39ab0679342476 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4258,6 +4258,18 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
} else {
llvm_unreachable("expected DXIL or SPIR-V target");
}
+ // validate that if fnative-half-type is given, that
+ // the language standard is at least hlsl2021, and that
+ // the target shader model is at least 6.2
+ if (Args.getLastArg(OPT_fnative_half_type)) {
+ bool LangStdArgIsValid = Opts.LangStd >= LangStandard::lang_hlsl2021;
+ bool TPArgIsValid = T.getOSVersion() >= VersionTuple(6, 2);
+
+ // if the HLSL Version is not at least 2021, or the shader model is not
+ // at least 6.2, then enable-16bit-types is an invalid flag.
+ if (!(LangStdArgIsValid && TPArgIsValid))
+ Diags.Report(diag::err_drv_hlsl_enable_16bit_types_option_invalid);
+ }
} else
Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
}
diff --git a/clang/test/Options/enable_16bit_types_validation.hlsl b/clang/test/Options/enable_16bit_types_validation.hlsl
index 205383c01b5ae4..6d5d2e51e68b25 100644
--- a/clang/test/Options/enable_16bit_types_validation.hlsl
+++ b/clang/test/Options/enable_16bit_types_validation.hlsl
@@ -1,6 +1,6 @@
-// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 2016 %s 2>&1 -### | FileCheck -check-prefix=both_invalid %s
-// RUN: not %clang_dxc -enable-16bit-types -T lib_6_4 -HV 2017 %s 2>&1 -### | FileCheck -check-prefix=HV_invalid %s
-// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=TP_invalid %s
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 -HV 2016 %s 2>&1 | FileCheck -check-prefix=both_invalid %s
+// RUN: not %clang_dxc -enable-16bit-types -T lib_6_4 -HV 2017 %s 2>&1 | FileCheck -check-prefix=HV_invalid %s
+// RUN: not %clang_dxc -enable-16bit-types -T cs_6_0 /HV 2021 %s 2>&1 | FileCheck -check-prefix=TP_invalid %s
// RUN: %clang_dxc -enable-16bit-types -T lib_6_4 /HV 2021 %s 2>&1 -### | FileCheck -check-prefix=valid %s
More information about the cfe-commits
mailing list