[clang] [HLSL] Add validation for the -enable-16bit-types option (PR #85340)

Joshua Batista via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 15 12:54:00 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/3] 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/3] 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/3] 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;
+}
+



More information about the cfe-commits mailing list