llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-hlsl

Author: Steven Perron (s-perron)

<details>
<summary>Changes</summary>

This commit implements DXC's `-fspv-extension` options. It is
implemented by replaced it with the equivalent `-spirv-ext` option. Note
that if the option is not used, that is the same as enabling all
extension, so `-spirv-ext=all` is used.

Fixes https://github.com/llvm/llvm-project/issues/137647


---
Full diff: https://github.com/llvm/llvm-project/pull/137985.diff


3 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+5) 
- (modified) clang/lib/Driver/ToolChains/HLSL.cpp (+45) 
- (added) clang/test/Driver/dxc_fspv_extension.hlsl (+25) 


``````````diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index a9f4083920663..a9e9ca5cc2c95 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -9213,6 +9213,11 @@ def metal : DXCFlag<"metal">, HelpText<"Generate Metal 
library">;
 def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>,
   HelpText<"Specify the target environment">,
   Values<"vulkan1.2, vulkan1.3">;
+def fspv_extension_EQ
+    : Joined<["-"], "fspv-extension=">,
+      Group<dxc_Group>,
+      HelpText<"Specify the available SPIR-V extensions. If this option is not 
"
+               "specificed, then all extensions are available.">;
 def no_wasm_opt : Flag<["--"], "no-wasm-opt">,
   Group<m_Group>,
   HelpText<"Disable the wasm-opt optimizer">,
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp 
b/clang/lib/Driver/ToolChains/HLSL.cpp
index 59e9050af8a76..b71e27c20043a 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -13,6 +13,7 @@
 #include "clang/Driver/Job.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/TargetParser/Triple.h"
+#include <regex>
 
 using namespace clang::driver;
 using namespace clang::driver::tools;
@@ -173,6 +174,39 @@ bool isLegalValidatorVersion(StringRef ValVersionStr, 
const Driver &D) {
   return true;
 }
 
+std::string getSpirvExtArg(ArrayRef<std::string> SpvExtensionArgs) {
+  if (SpvExtensionArgs.empty()) {
+    return "-spirv-ext=all";
+  }
+
+  std::string LlvmOption =
+      (Twine("-spirv-ext=+") + SpvExtensionArgs.front()).str();
+  SpvExtensionArgs = SpvExtensionArgs.slice(1);
+  for (auto Extension : SpvExtensionArgs) {
+    LlvmOption = (Twine(LlvmOption) + ",+" + Extension).str();
+  }
+  return LlvmOption;
+}
+
+bool isValidSPIRVExtensionName(const std::string &str) {
+  std::regex pattern("SPV_[a-zA-Z0-9_]+");
+  return std::regex_match(str, pattern);
+}
+
+// SPIRV extension names are of the form `SPV_[a-zA-Z0-9_]+`. We want to
+// disallow obviously invalid names to avoid issues when parsing `spirv-ext`.
+bool checkExtensionArgsAreValid(ArrayRef<std::string> SpvExtensionArgs,
+                                const Driver &Driver) {
+  bool AllValid = true;
+  for (auto Extension : SpvExtensionArgs) {
+    if (!isValidSPIRVExtensionName(Extension)) {
+      Driver.Diag(diag::err_drv_invalid_value)
+          << "-fspv_extension" << Extension;
+      AllValid = false;
+    }
+  }
+  return AllValid;
+}
 } // namespace
 
 void tools::hlsl::Validator::ConstructJob(Compilation &C, const JobAction &JA,
@@ -301,6 +335,17 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, 
StringRef BoundArch,
     DAL->append(A);
   }
 
+  if (getArch() == llvm::Triple::spirv) {
+    std::vector<std::string> SpvExtensionArgs =
+        Args.getAllArgValues(options::OPT_fspv_extension_EQ);
+    if (checkExtensionArgsAreValid(SpvExtensionArgs, getDriver())) {
+      std::string LlvmOption = getSpirvExtArg(SpvExtensionArgs);
+      DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_mllvm),
+                          LlvmOption);
+    }
+    Args.claimAllArgs(options::OPT_fspv_extension_EQ);
+  }
+
   if (!DAL->hasArg(options::OPT_O_Group)) {
     DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
   }
diff --git a/clang/test/Driver/dxc_fspv_extension.hlsl 
b/clang/test/Driver/dxc_fspv_extension.hlsl
new file mode 100644
index 0000000000000..0a9d321b8d95e
--- /dev/null
+++ b/clang/test/Driver/dxc_fspv_extension.hlsl
@@ -0,0 +1,25 @@
+// If there is no `-fspv-extension`, enable all extensions.
+// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s 2>&1 | FileCheck %s 
-check-prefix=ALL
+// ALL: "-spirv-ext=all"
+
+// Convert the `-fspv-extension` into `spirv-ext`.
+// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=SPV_TEST1 2>&1 | 
FileCheck %s -check-prefix=TEST1
+// TEST1: "-spirv-ext=+SPV_TEST1"
+
+// Merge multiple extensions into a single `spirv-ext` option.
+// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=SPV_TEST1 
-fspv-extension=SPV_TEST2 2>&1 | FileCheck %s -check-prefix=TEST2
+// TEST2: "-spirv-ext=+SPV_TEST1,+SPV_TEST2"
+
+// Check for the error message if the extension name is not properly formed.
+// RUN: not %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=TEST1 
-fspv-extension=SPV_GOOD -fspv-extension=TEST2 2>&1 | FileCheck %s 
-check-prefix=FAIL
+// FAIL: invalid value 'TEST1' in '-fspv_extension'
+// FAIL: invalid value 'TEST2' in '-fspv_extension'
+
+// If targeting DXIL, the `-spirv-ext` should not be passed to the backend.
+// RUN: %clang_dxc -Tlib_6_7 -### %s 2>&1 | FileCheck %s -check-prefix=DXIL
+// DXIL-NOT: spirv-ext
+
+// If targeting DXIL, the `-fspv-extension` option is meaningless, and there 
should be a warning.
+// RUN: %clang_dxc -Tlib_6_7 -### %s -fspv-extension=SPV_TEST 2>&1 | FileCheck 
%s -check-prefix=WARN
+// WARN: warning: argument unused during compilation: 
'-fspv-extension=SPV_TEST'
+// WARN-NOT: spirv-ext

``````````

</details>


https://github.com/llvm/llvm-project/pull/137985
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to