-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[HLSL][SPIR-V] Add Vulkan to target triple #76749
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Natalie Chouinard (sudonatalie) ChangesAdd support for specifying the logical SPIR-V target environment in the triple as Vulkan. When compiling HLSL, this replaces the DirectX Shader Model with a Vulkan environment instead. Currently, the only supported combinations of SPIR-V version and Vulkan environment are:
Fixes #70051 Full diff: https://github.com/llvm/llvm-project/pull/76749.diff 7 Files Affected:
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 676f1a62b49dd0..2e5ac4f349c0fd 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -735,10 +735,10 @@ def err_drv_dxc_missing_target_profile : Error<
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<
- "shader %select{model|stage}0 is required in target '%1' for HLSL code generation">;
+ "%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_bad_shader_unsupported : Error<
- "shader %select{model|stage}0 '%1' in target '%2' is invalid for HLSL code generation">;
+ "%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. "
"Resulting DXIL will not be validated or signed for use in release environments.">,
InGroup<DXILValidation>;
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 9ab2b7c6093639..fa4a3bb1c82eed 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -17,6 +17,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "llvm/Support/Compiler.h"
+#include "llvm/Support/VersionTuple.h"
#include "llvm/TargetParser/Triple.h"
#include <optional>
@@ -301,8 +302,9 @@ class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo {
: BaseSPIRVTargetInfo(Triple, Opts) {
assert(Triple.getArch() == llvm::Triple::spirv &&
"Invalid architecture for Logical SPIR-V.");
- assert(Triple.getOS() == llvm::Triple::ShaderModel &&
- "Logical SPIR-V requires a valid ShaderModel.");
+ assert(Triple.getOS() == llvm::Triple::Vulkan &&
+ Triple.getVulkanVersion() != llvm::VersionTuple(0) &&
+ "Logical SPIR-V requires a valid Vulkan environment.");
assert(Triple.getEnvironment() >= llvm::Triple::Pixel &&
Triple.getEnvironment() <= llvm::Triple::Amplification &&
"Logical SPIR-V environment must be a valid shader stage.");
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 11f3f2c2d6425c..7e211ea24df2ae 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -4236,20 +4236,35 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
// TODO: Revisit restricting SPIR-V to logical once we've figured out how to
// handle PhysicalStorageBuffer64 memory model
if (T.isDXIL() || T.isSPIRVLogical()) {
- enum { ShaderModel, ShaderStage };
+ enum { ShaderModel, VulkanEnv, ShaderStage };
+ enum { OS, Environment };
+
+ int ExpectedOS = T.isSPIRVLogical() ? VulkanEnv : ShaderModel;
+
if (T.getOSName().empty()) {
Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
- << ShaderModel << T.str();
- } else if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
- Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
- << ShaderModel << T.getOSName() << T.str();
+ << ExpectedOS << OS << T.str();
} else if (T.getEnvironmentName().empty()) {
Diags.Report(diag::err_drv_hlsl_bad_shader_required_in_target)
- << ShaderStage << T.str();
+ << ShaderStage << Environment << T.str();
} else if (!T.isShaderStageEnvironment()) {
Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
<< ShaderStage << T.getEnvironmentName() << T.str();
}
+
+ if (T.isDXIL()) {
+ if (!T.isShaderModelOS() || T.getOSVersion() == VersionTuple(0)) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
+ << ShaderModel << T.getOSName() << T.str();
+ }
+ }
+
+ if (T.isSPIRVLogical()) {
+ if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
+ Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
+ << VulkanEnv << T.getOSName() << T.str();
+ }
+ }
} else
Diags.Report(diag::err_drv_hlsl_unsupported_target) << T.str();
}
diff --git a/clang/test/Driver/hlsl-lang-targets-spirv.hlsl b/clang/test/Driver/hlsl-lang-targets-spirv.hlsl
index e04d71263770bb..b86c2e01f8d80e 100644
--- a/clang/test/Driver/hlsl-lang-targets-spirv.hlsl
+++ b/clang/test/Driver/hlsl-lang-targets-spirv.hlsl
@@ -3,29 +3,39 @@
// Supported targets
//
// RUN: %clang -target dxil-unknown-shadermodel6.2-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
-// RUN: %clang -target spirv-unknown-shadermodel6.2-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
+// RUN: %clang -target spirv-unknown-vulkan-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
+// RUN: %clang -target spirv-unknown-vulkan1.2-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
+// RUN: %clang -target spirv-unknown-vulkan1.3-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
+// RUN: %clang -target spirv1.5-unknown-vulkan1.2-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
+// RUN: %clang -target spirv1.6-unknown-vulkan1.3-compute %s -S -o /dev/null 2>&1 | FileCheck --allow-empty --check-prefix=CHECK-VALID %s
-// Empty shader model
+// Empty Vulkan environment
//
// RUN: not %clang -target spirv %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-NO-OS %s
-// Invalid shader models
+// Invalid Vulkan environment
//
-// RUN: not %clang -target spirv--unknown %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-OS %s
+// RUN: not %clang -target spirv--shadermodel %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-OS %s
+// RUN: not %clang -target spirv-unknown-vulkan1.0-compute %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-OS %s
+// RUN: not %clang -target spirv1.5-unknown-vulkan1.3-compute %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-OS %s
+
+// Invalid SPIR-V version
+// RUN: not %clang -target spirv1.0-unknown-vulkan-compute %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-TARGET %s
// Empty shader stage
//
-// RUN: not %clang -target spirv--shadermodel6.2 %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-NO-ENV %s
+// RUN: not %clang -target spirv--vulkan %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-NO-ENV %s
// Invalid shader stages
//
-// RUN: not %clang -target spirv--shadermodel6.2-unknown %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-ENV %s
+// RUN: not %clang -target spirv--vulkan-unknown %s -S -o /dev/null 2>&1 | FileCheck --check-prefix=CHECK-BAD-ENV %s
// CHECK-VALID-NOT: error:
-// CHECK-NO-OS: error: shader model is required in target '{{.*}}' for HLSL code generation
-// CHECK-BAD-OS: error: shader model '{{.*}}' in target '{{.*}}' is invalid for HLSL code generation
-// CHECK-NO-ENV: error: shader stage is required in target '{{.*}}' for HLSL code generation
+// CHECK-NO-OS: error: Vulkan environment is required as OS in target '{{.*}}' for HLSL code generation
+// CHECK-BAD-OS: error: Vulkan environment '{{.*}}' in target '{{.*}}' is invalid for HLSL code generation
+// CHECK-NO-ENV: error: shader stage is required as environment in target '{{.*}}' for HLSL code generation
// CHECK-BAD-ENV: error: shader stage '{{.*}}' in target '{{.*}}' is invalid for HLSL code generation
+// CHECK-BAD-TARGET: error: HLSL code generation is unsupported for target '{{.*}}'
[shader("compute"), numthreads(1,1,1)]
void main() {}
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 47904621c0967f..4b3e87e1c3afce 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -164,6 +164,7 @@ class Triple {
SPIRVSubArch_v13,
SPIRVSubArch_v14,
SPIRVSubArch_v15,
+ SPIRVSubArch_v16,
};
enum VendorType {
UnknownVendor,
@@ -223,7 +224,8 @@ class Triple {
ShaderModel, // DirectX ShaderModel
LiteOS,
Serenity,
- LastOSType = Serenity
+ Vulkan, // Vulkan SPIR-V
+ LastOSType = Vulkan
};
enum EnvironmentType {
UnknownEnvironment,
@@ -409,6 +411,10 @@ class Triple {
/// Parse the version number as with getOSVersion.
VersionTuple getDriverKitVersion() const;
+ /// Parse the Vulkan version number from the OSVersion and SPIR-V version
+ /// (SubArch). This should only be called with Vulkan SPIR-V triples.
+ VersionTuple getVulkanVersion() const;
+
/// @}
/// @name Direct Component Access
/// @{
@@ -765,6 +771,8 @@ class Triple {
return getOS() == Triple::ShaderModel;
}
+ bool isVulkanOS() const { return getOS() == Triple::Vulkan; }
+
bool isShaderStageEnvironment() const {
EnvironmentType Env = getEnvironment();
return Env == Triple::Pixel || Env == Triple::Vertex ||
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index e93502187b5492..7e8642bdb71650 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/TargetParser/Triple.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
@@ -273,6 +274,7 @@ StringRef Triple::getOSTypeName(OSType Kind) {
case ZOS: return "zos";
case ShaderModel: return "shadermodel";
case LiteOS: return "liteos";
+ case Vulkan: return "vulkan";
}
llvm_unreachable("Invalid OSType");
@@ -550,8 +552,7 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Case("hsail64", Triple::hsail64)
.Case("spir", Triple::spir)
.Case("spir64", Triple::spir64)
- .Cases("spirv", "spirv1.0", "spirv1.1", "spirv1.2",
- "spirv1.3", "spirv1.4", "spirv1.5", Triple::spirv)
+ .Cases("spirv", "spirv1.5", "spirv1.6", Triple::spirv)
.Cases("spirv32", "spirv32v1.0", "spirv32v1.1", "spirv32v1.2",
"spirv32v1.3", "spirv32v1.4", "spirv32v1.5", Triple::spirv32)
.Cases("spirv64", "spirv64v1.0", "spirv64v1.1", "spirv64v1.2",
@@ -643,6 +644,7 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("shadermodel", Triple::ShaderModel)
.StartsWith("liteos", Triple::LiteOS)
.StartsWith("serenity", Triple::Serenity)
+ .StartsWith("vulkan", Triple::Vulkan)
.Default(Triple::UnknownOS);
}
@@ -727,6 +729,7 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
.EndsWith("v1.3", Triple::SPIRVSubArch_v13)
.EndsWith("v1.4", Triple::SPIRVSubArch_v14)
.EndsWith("v1.5", Triple::SPIRVSubArch_v15)
+ .EndsWith("v1.6", Triple::SPIRVSubArch_v16)
.Default(Triple::NoSubArch);
StringRef ARMSubArch = ARM::getCanonicalArchName(SubArchName);
@@ -1328,6 +1331,31 @@ VersionTuple Triple::getDriverKitVersion() const {
}
}
+VersionTuple Triple::getVulkanVersion() const {
+ if (getArch() != spirv || getOS() != Vulkan)
+ llvm_unreachable("invalid Vulkan SPIR-V triple");
+
+ VersionTuple VulkanVersion = getOSVersion();
+ SubArchType SpirvVersion = getSubArch();
+
+ llvm::DenseMap<VersionTuple, SubArchType> ValidVersionMap = {
+ // Vulkan 1.2 -> SPIR-V 1.5.
+ {VersionTuple(1, 2), SPIRVSubArch_v15},
+ // Vulkan 1.3 -> SPIR-V 1.6.
+ {VersionTuple(1, 3), SPIRVSubArch_v16}};
+
+ // If Vulkan version is unset, default to 1.2.
+ if (VulkanVersion == VersionTuple(0))
+ VulkanVersion = VersionTuple(1, 2);
+
+ if (ValidVersionMap.contains(VulkanVersion) &&
+ (ValidVersionMap.lookup(VulkanVersion) == SpirvVersion ||
+ SpirvVersion == NoSubArch))
+ return VulkanVersion;
+
+ return VersionTuple(0);
+}
+
void Triple::setTriple(const Twine &Str) {
*this = Triple(Str);
}
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index d3bde2986ea2cd..a4b96b664061ce 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -319,130 +319,116 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::UnknownOS, T.getOS());
- T = Triple("spirv-unknown-shadermodel-pixel");
+ T = Triple("spirv-unknown-vulkan-pixel");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Pixel, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-vertex");
+ T = Triple("spirv-unknown-vulkan-vertex");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Vertex, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-geometry");
+ T = Triple("spirv-unknown-vulkan-geometry");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Geometry, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-library");
+ T = Triple("spirv-unknown-vulkan-library");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Library, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-raygeneration");
+ T = Triple("spirv-unknown-vulkan-raygeneration");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::RayGeneration, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-intersection");
+ T = Triple("spirv-unknown-vulkan-intersection");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Intersection, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-anyhit");
+ T = Triple("spirv-unknown-vulkan-anyhit");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::AnyHit, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-closesthit");
+ T = Triple("spirv-unknown-vulkan-closesthit");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::ClosestHit, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-miss");
+ T = Triple("spirv-unknown-vulkan-miss");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Miss, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-callable");
+ T = Triple("spirv-unknown-vulkan-callable");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Callable, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-mesh");
+ T = Triple("spirv-unknown-vulkan-mesh");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Mesh, T.getEnvironment());
- T = Triple("spirv-unknown-shadermodel-amplification");
+ T = Triple("spirv-unknown-vulkan-amplification");
EXPECT_EQ(Triple::spirv, T.getArch());
EXPECT_EQ(Triple::NoSubArch, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Amplification, T.getEnvironment());
- T = Triple("spirv1.0-unknown-shadermodel-compute");
- EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v10, T.getSubArch());
- EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
- EXPECT_EQ(Triple::Compute, T.getEnvironment());
-
- T = Triple("spirv1.1-unknown-shadermodel-compute");
+ T = Triple("spirv1.5-unknown-vulkan1.2-compute");
EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v11, T.getSubArch());
- EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
- EXPECT_EQ(Triple::Compute, T.getEnvironment());
-
- T = Triple("spirv1.2-unknown-shadermodel-compute");
- EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v12, T.getSubArch());
- EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
- EXPECT_EQ(Triple::Compute, T.getEnvironment());
-
- T = Triple("spirv1.3-unknown-shadermodel-compute");
- EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v13, T.getSubArch());
- EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
- EXPECT_EQ(Triple::Compute, T.getEnvironment());
-
- T = Triple("spirv1.4-unknown-shadermodel-compute");
- EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v14, T.getSubArch());
+ EXPECT_EQ(Triple::SPIRVSubArch_v15, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 2), T.getVulkanVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());
- T = Triple("spirv1.5-unknown-shadermodel-compute");
+ T = Triple("spirv1.6-unknown-vulkan1.3-compute");
EXPECT_EQ(Triple::spirv, T.getArch());
- EXPECT_EQ(Triple::SPIRVSubArch_v15, T.getSubArch());
+ EXPECT_EQ(Triple::SPIRVSubArch_v16, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
- EXPECT_EQ(Triple::ShaderModel, T.getOS());
+ EXPECT_EQ(Triple::Vulkan, T.getOS());
+ EXPECT_EQ(VersionTuple(1, 3), T.getVulkanVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());
T = Triple("x86_64-unknown-fuchsia");
|
You can test this locally with the following command:git-clang-format --diff 656bf13004d62b8f8360d8d496bb1e6e08407c22 c531a84c8f43ca923c3630b8d60cfee46986364d -- clang/lib/Basic/Targets/SPIR.h clang/lib/Frontend/CompilerInvocation.cpp llvm/include/llvm/TargetParser/Triple.h llvm/lib/TargetParser/Triple.cpp llvm/unittests/TargetParser/TripleTest.cpp View the diff from clang-format here.diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 1f8c7a060e..fc6a9276e4 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -194,7 +194,7 @@ public:
IOS,
KFreeBSD,
Linux,
- Lv2, // PS3
+ Lv2, // PS3
MacOSX,
NetBSD,
OpenBSD,
@@ -204,18 +204,18 @@ public:
ZOS,
Haiku,
RTEMS,
- NaCl, // Native Client
+ NaCl, // Native Client
AIX,
- CUDA, // NVIDIA CUDA
- NVCL, // NVIDIA OpenCL
- AMDHSA, // AMD HSA Runtime
+ CUDA, // NVIDIA CUDA
+ NVCL, // NVIDIA OpenCL
+ AMDHSA, // AMD HSA Runtime
PS4,
PS5,
ELFIAMCU,
- TvOS, // Apple tvOS
- WatchOS, // Apple watchOS
- DriverKit, // Apple DriverKit
- XROS, // Apple XROS
+ TvOS, // Apple tvOS
+ WatchOS, // Apple watchOS
+ DriverKit, // Apple DriverKit
+ XROS, // Apple XROS
Mesa3D,
AMDPAL, // AMD PAL Runtime
HermitCore, // HermitCore Unikernel/Multikernel
@@ -225,7 +225,7 @@ public:
ShaderModel, // DirectX ShaderModel
LiteOS,
Serenity,
- Vulkan, // Vulkan SPIR-V
+ Vulkan, // Vulkan SPIR-V
LastOSType = Vulkan
};
enum EnvironmentType {
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 3212ba77de..646a4a4a2e 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -275,7 +275,8 @@ StringRef Triple::getOSTypeName(OSType Kind) {
case ShaderModel: return "shadermodel";
case LiteOS: return "liteos";
case XROS: return "xros";
- case Vulkan: return "vulkan";
+ case Vulkan:
+ return "vulkan";
}
llvm_unreachable("Invalid OSType");
@@ -497,81 +498,82 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
}
static Triple::ArchType parseArch(StringRef ArchName) {
- auto AT = StringSwitch<Triple::ArchType>(ArchName)
- .Cases("i386", "i486", "i586", "i686", Triple::x86)
- // FIXME: Do we need to support these?
- .Cases("i786", "i886", "i986", Triple::x86)
- .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
- .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
- .Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
- .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
- .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
- .Case("xscale", Triple::arm)
- .Case("xscaleeb", Triple::armeb)
- .Case("aarch64", Triple::aarch64)
- .Case("aarch64_be", Triple::aarch64_be)
- .Case("aarch64_32", Triple::aarch64_32)
- .Case("arc", Triple::arc)
- .Case("arm64", Triple::aarch64)
- .Case("arm64_32", Triple::aarch64_32)
- .Case("arm64e", Triple::aarch64)
- .Case("arm64ec", Triple::aarch64)
- .Case("arm", Triple::arm)
- .Case("armeb", Triple::armeb)
- .Case("thumb", Triple::thumb)
- .Case("thumbeb", Triple::thumbeb)
- .Case("avr", Triple::avr)
- .Case("m68k", Triple::m68k)
- .Case("msp430", Triple::msp430)
- .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6",
- "mipsr6", Triple::mips)
- .Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el",
- Triple::mipsel)
- .Cases("mips64", "mips64eb", "mipsn32", "mipsisa64r6",
- "mips64r6", "mipsn32r6", Triple::mips64)
- .Cases("mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el",
- "mipsn32r6el", Triple::mips64el)
- .Case("r600", Triple::r600)
- .Case("amdgcn", Triple::amdgcn)
- .Case("riscv32", Triple::riscv32)
- .Case("riscv64", Triple::riscv64)
- .Case("hexagon", Triple::hexagon)
- .Cases("s390x", "systemz", Triple::systemz)
- .Case("sparc", Triple::sparc)
- .Case("sparcel", Triple::sparcel)
- .Cases("sparcv9", "sparc64", Triple::sparcv9)
- .Case("tce", Triple::tce)
- .Case("tcele", Triple::tcele)
- .Case("xcore", Triple::xcore)
- .Case("nvptx", Triple::nvptx)
- .Case("nvptx64", Triple::nvptx64)
- .Case("le32", Triple::le32)
- .Case("le64", Triple::le64)
- .Case("amdil", Triple::amdil)
- .Case("amdil64", Triple::amdil64)
- .Case("hsail", Triple::hsail)
- .Case("hsail64", Triple::hsail64)
- .Case("spir", Triple::spir)
- .Case("spir64", Triple::spir64)
- .Cases("spirv", "spirv1.5", "spirv1.6", Triple::spirv)
- .Cases("spirv32", "spirv32v1.0", "spirv32v1.1", "spirv32v1.2",
- "spirv32v1.3", "spirv32v1.4", "spirv32v1.5", Triple::spirv32)
- .Cases("spirv64", "spirv64v1.0", "spirv64v1.1", "spirv64v1.2",
- "spirv64v1.3", "spirv64v1.4", "spirv64v1.5", Triple::spirv64)
- .StartsWith("kalimba", Triple::kalimba)
- .Case("lanai", Triple::lanai)
- .Case("renderscript32", Triple::renderscript32)
- .Case("renderscript64", Triple::renderscript64)
- .Case("shave", Triple::shave)
- .Case("ve", Triple::ve)
- .Case("wasm32", Triple::wasm32)
- .Case("wasm64", Triple::wasm64)
- .Case("csky", Triple::csky)
- .Case("loongarch32", Triple::loongarch32)
- .Case("loongarch64", Triple::loongarch64)
- .Case("dxil", Triple::dxil)
- .Case("xtensa", Triple::xtensa)
- .Default(Triple::UnknownArch);
+ auto AT =
+ StringSwitch<Triple::ArchType>(ArchName)
+ .Cases("i386", "i486", "i586", "i686", Triple::x86)
+ // FIXME: Do we need to support these?
+ .Cases("i786", "i886", "i986", Triple::x86)
+ .Cases("amd64", "x86_64", "x86_64h", Triple::x86_64)
+ .Cases("powerpc", "powerpcspe", "ppc", "ppc32", Triple::ppc)
+ .Cases("powerpcle", "ppcle", "ppc32le", Triple::ppcle)
+ .Cases("powerpc64", "ppu", "ppc64", Triple::ppc64)
+ .Cases("powerpc64le", "ppc64le", Triple::ppc64le)
+ .Case("xscale", Triple::arm)
+ .Case("xscaleeb", Triple::armeb)
+ .Case("aarch64", Triple::aarch64)
+ .Case("aarch64_be", Triple::aarch64_be)
+ .Case("aarch64_32", Triple::aarch64_32)
+ .Case("arc", Triple::arc)
+ .Case("arm64", Triple::aarch64)
+ .Case("arm64_32", Triple::aarch64_32)
+ .Case("arm64e", Triple::aarch64)
+ .Case("arm64ec", Triple::aarch64)
+ .Case("arm", Triple::arm)
+ .Case("armeb", Triple::armeb)
+ .Case("thumb", Triple::thumb)
+ .Case("thumbeb", Triple::thumbeb)
+ .Case("avr", Triple::avr)
+ .Case("m68k", Triple::m68k)
+ .Case("msp430", Triple::msp430)
+ .Cases("mips", "mipseb", "mipsallegrex", "mipsisa32r6", "mipsr6",
+ Triple::mips)
+ .Cases("mipsel", "mipsallegrexel", "mipsisa32r6el", "mipsr6el",
+ Triple::mipsel)
+ .Cases("mips64", "mips64eb", "mipsn32", "mipsisa64r6", "mips64r6",
+ "mipsn32r6", Triple::mips64)
+ .Cases("mips64el", "mipsn32el", "mipsisa64r6el", "mips64r6el",
+ "mipsn32r6el", Triple::mips64el)
+ .Case("r600", Triple::r600)
+ .Case("amdgcn", Triple::amdgcn)
+ .Case("riscv32", Triple::riscv32)
+ .Case("riscv64", Triple::riscv64)
+ .Case("hexagon", Triple::hexagon)
+ .Cases("s390x", "systemz", Triple::systemz)
+ .Case("sparc", Triple::sparc)
+ .Case("sparcel", Triple::sparcel)
+ .Cases("sparcv9", "sparc64", Triple::sparcv9)
+ .Case("tce", Triple::tce)
+ .Case("tcele", Triple::tcele)
+ .Case("xcore", Triple::xcore)
+ .Case("nvptx", Triple::nvptx)
+ .Case("nvptx64", Triple::nvptx64)
+ .Case("le32", Triple::le32)
+ .Case("le64", Triple::le64)
+ .Case("amdil", Triple::amdil)
+ .Case("amdil64", Triple::amdil64)
+ .Case("hsail", Triple::hsail)
+ .Case("hsail64", Triple::hsail64)
+ .Case("spir", Triple::spir)
+ .Case("spir64", Triple::spir64)
+ .Cases("spirv", "spirv1.5", "spirv1.6", Triple::spirv)
+ .Cases("spirv32", "spirv32v1.0", "spirv32v1.1", "spirv32v1.2",
+ "spirv32v1.3", "spirv32v1.4", "spirv32v1.5", Triple::spirv32)
+ .Cases("spirv64", "spirv64v1.0", "spirv64v1.1", "spirv64v1.2",
+ "spirv64v1.3", "spirv64v1.4", "spirv64v1.5", Triple::spirv64)
+ .StartsWith("kalimba", Triple::kalimba)
+ .Case("lanai", Triple::lanai)
+ .Case("renderscript32", Triple::renderscript32)
+ .Case("renderscript64", Triple::renderscript64)
+ .Case("shave", Triple::shave)
+ .Case("ve", Triple::ve)
+ .Case("wasm32", Triple::wasm32)
+ .Case("wasm64", Triple::wasm64)
+ .Case("csky", Triple::csky)
+ .Case("loongarch32", Triple::loongarch32)
+ .Case("loongarch64", Triple::loongarch64)
+ .Case("dxil", Triple::dxil)
+ .Case("xtensa", Triple::xtensa)
+ .Default(Triple::UnknownArch);
// Some architectures require special parsing logic just to compute the
// ArchType result.
@@ -607,48 +609,48 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
static Triple::OSType parseOS(StringRef OSName) {
return StringSwitch<Triple::OSType>(OSName)
- .StartsWith("darwin", Triple::Darwin)
- .StartsWith("dragonfly", Triple::DragonFly)
- .StartsWith("freebsd", Triple::FreeBSD)
- .StartsWith("fuchsia", Triple::Fuchsia)
- .StartsWith("ios", Triple::IOS)
- .StartsWith("kfreebsd", Triple::KFreeBSD)
- .StartsWith("linux", Triple::Linux)
- .StartsWith("lv2", Triple::Lv2)
- .StartsWith("macos", Triple::MacOSX)
- .StartsWith("netbsd", Triple::NetBSD)
- .StartsWith("openbsd", Triple::OpenBSD)
- .StartsWith("solaris", Triple::Solaris)
- .StartsWith("uefi", Triple::UEFI)
- .StartsWith("win32", Triple::Win32)
- .StartsWith("windows", Triple::Win32)
- .StartsWith("zos", Triple::ZOS)
- .StartsWith("haiku", Triple::Haiku)
- .StartsWith("rtems", Triple::RTEMS)
- .StartsWith("nacl", Triple::NaCl)
- .StartsWith("aix", Triple::AIX)
- .StartsWith("cuda", Triple::CUDA)
- .StartsWith("nvcl", Triple::NVCL)
- .StartsWith("amdhsa", Triple::AMDHSA)
- .StartsWith("ps4", Triple::PS4)
- .StartsWith("ps5", Triple::PS5)
- .StartsWith("elfiamcu", Triple::ELFIAMCU)
- .StartsWith("tvos", Triple::TvOS)
- .StartsWith("watchos", Triple::WatchOS)
- .StartsWith("driverkit", Triple::DriverKit)
- .StartsWith("xros", Triple::XROS)
- .StartsWith("visionos", Triple::XROS)
- .StartsWith("mesa3d", Triple::Mesa3D)
- .StartsWith("amdpal", Triple::AMDPAL)
- .StartsWith("hermit", Triple::HermitCore)
- .StartsWith("hurd", Triple::Hurd)
- .StartsWith("wasi", Triple::WASI)
- .StartsWith("emscripten", Triple::Emscripten)
- .StartsWith("shadermodel", Triple::ShaderModel)
- .StartsWith("liteos", Triple::LiteOS)
- .StartsWith("serenity", Triple::Serenity)
- .StartsWith("vulkan", Triple::Vulkan)
- .Default(Triple::UnknownOS);
+ .StartsWith("darwin", Triple::Darwin)
+ .StartsWith("dragonfly", Triple::DragonFly)
+ .StartsWith("freebsd", Triple::FreeBSD)
+ .StartsWith("fuchsia", Triple::Fuchsia)
+ .StartsWith("ios", Triple::IOS)
+ .StartsWith("kfreebsd", Triple::KFreeBSD)
+ .StartsWith("linux", Triple::Linux)
+ .StartsWith("lv2", Triple::Lv2)
+ .StartsWith("macos", Triple::MacOSX)
+ .StartsWith("netbsd", Triple::NetBSD)
+ .StartsWith("openbsd", Triple::OpenBSD)
+ .StartsWith("solaris", Triple::Solaris)
+ .StartsWith("uefi", Triple::UEFI)
+ .StartsWith("win32", Triple::Win32)
+ .StartsWith("windows", Triple::Win32)
+ .StartsWith("zos", Triple::ZOS)
+ .StartsWith("haiku", Triple::Haiku)
+ .StartsWith("rtems", Triple::RTEMS)
+ .StartsWith("nacl", Triple::NaCl)
+ .StartsWith("aix", Triple::AIX)
+ .StartsWith("cuda", Triple::CUDA)
+ .StartsWith("nvcl", Triple::NVCL)
+ .StartsWith("amdhsa", Triple::AMDHSA)
+ .StartsWith("ps4", Triple::PS4)
+ .StartsWith("ps5", Triple::PS5)
+ .StartsWith("elfiamcu", Triple::ELFIAMCU)
+ .StartsWith("tvos", Triple::TvOS)
+ .StartsWith("watchos", Triple::WatchOS)
+ .StartsWith("driverkit", Triple::DriverKit)
+ .StartsWith("xros", Triple::XROS)
+ .StartsWith("visionos", Triple::XROS)
+ .StartsWith("mesa3d", Triple::Mesa3D)
+ .StartsWith("amdpal", Triple::AMDPAL)
+ .StartsWith("hermit", Triple::HermitCore)
+ .StartsWith("hurd", Triple::Hurd)
+ .StartsWith("wasi", Triple::WASI)
+ .StartsWith("emscripten", Triple::Emscripten)
+ .StartsWith("shadermodel", Triple::ShaderModel)
+ .StartsWith("liteos", Triple::LiteOS)
+ .StartsWith("serenity", Triple::Serenity)
+ .StartsWith("vulkan", Triple::Vulkan)
+ .Default(Triple::UnknownOS);
}
static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) {
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for the logic, and choices. Just some small nits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will wait for a +1 from @llvm-beanz or @bogner since I modified the error messages slightly for DXIL too
@@ -1,4 +1,4 @@ | |||
// REQUIRES: dxil-registered-target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test wasn't being run for me before. I think this change is correct?
Add support for specifying the logical SPIR-V target environment in the triple as Vulkan. When compiling HLSL, this replaces the DirectX Shader Model with a Vulkan environment instead. Currently, the only supported combinations of SPIR-V version and Vulkan environment are: - Vulkan 1.2 and SPIR-V 1.5 - Vulkan 1.3 and SPIR-V 1.6 Fixes llvm#70051
a3db470
to
c531a84
Compare
Rebased due to conflicts. I'm going to go ahead and merge this today to make the next dependent change easier to review, but DXIL folks please still feel free to follow-up if there are any concerns. (Also, ignoring the code formatter bot since it seems to be an existing intentional formatting choice in the file that doesn't play nicely with clang-format yet) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for my delayed review. LGTM.
Rebased again and local |
Add support for specifying the logical SPIR-V target environment in the triple as Vulkan. When compiling HLSL, this replaces the DirectX Shader Model with a Vulkan environment instead.
Currently, the only supported combinations of SPIR-V version and Vulkan environment are:
Fixes #70051