https://github.com/llvm-beanz updated https://github.com/llvm/llvm-project/pull/82395
>From 558dd6182a4dc6fc5c5383358cac422289a7a90b Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Tue, 20 Feb 2024 12:01:16 -0600 Subject: [PATCH 1/6] [HLSL][Doc] Add doc about expected differences This document covers expected differences between Clang and the HLSL reference compiler implementations (FXC & DXC). The document is not intended to be exhaustive, but it should be a best effort to cover known cases. This document should document both the behavioral difference and the explanation of why Clang differs. The initail document covers known overload resolution differences. --- clang/docs/HLSL/ExpectedDifferences.rst | 108 ++++++++++++++++++++++++ clang/docs/HLSL/HLSLDocs.rst | 1 + 2 files changed, 109 insertions(+) create mode 100644 clang/docs/HLSL/ExpectedDifferences.rst diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst new file mode 100644 index 00000000000000..f1d52b52092466 --- /dev/null +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -0,0 +1,108 @@ + +Expected Differences vs DXC and FXC +=================================== + +.. contents:: + :local: + +Introduction +============ + +HLSL currently has two reference compilers, the `DirectX Shader Compiler (DXC) +<https://github.com/microsoft/DirectXShaderCompiler/>`_ and the +`Effect-Compiler (FXC) <https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc>`_. +The two reference compilers do not fully agree. Some known disagreements in the +references are tracked on +`DXC's GitHub +<https://github.com/microsoft/DirectXShaderCompiler/issues?q=is%3Aopen+is%3Aissue+label%3Afxc-disagrees>`_, +but many more are known to exist. + +HLSL as implemented by Clang will also not fully match either of the reference +implementations, it is instead being written to match the `draft language +specification <https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf>`_. + +This document is a non-exhaustive collection the known differences between +Clang's implementation of HLSL and the existing reference compilers. + +General Principles +------------------ + +Most of the intended differences between Clang and the earlier reference +compilers are focused on increased consistency and correctness. Both reference +compilers do not always apply language rules the same in all contexts. + +Clang also deviates from the reference compilers by providing different +diagnostics, both in terms of the textual messages and the contexts in which +diagnostics are produced. While striving for a high level of source +compatibility with conforming HLSL code, Clang may produce earlier and more +robust diagnostics for incorrect code or reject code that a reference compiler +incorrectly accepted. + +Language Version +================ + +Clang targets language compatibility for HLSL 2021 as implemented by DXC. +Language features that were removed in earlier versions of HLSL may be added on +a case-by-case basis, but are not planned for the initial implementation. + +Overload Resolution +=================== + +Clang's HLSL implementation adopts C++ overload resolution rules as proposed for +HLSL 202x based on proposal +`0007 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0007-const-instance-methods.md>`_ +and +`0008 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md>`_. + +Clang's implementation extends standard overload resolution rules to HLSL +library functionality. This causes subtle changes in overload resolution +behavior between Clang and DXC. Some examples include: + +.. code-block:: c++ + + void halfOrInt16(half H); + void halfOrInt16(uint16_t I); + + void takesDoubles(double, double, double); + + cbuffer CB { + uint U; + uint I; + float X, Y, Z; + double3 A, B; + } + + export void call() { + halfOrInt16(U); // All: Resolves to halfOrInt16(uint16_t). + halfOrInt16(I); // All: Resolves to halfOrInt16(uint16_t). + #ifndef IGNORE_ERRORS + half H = asfloat16(I); // DXC: Fails to resolve overload for int. + // Clang: Resolves to halfOrInt16(uint16_t). + half H = asfloat16(U); // DXC: Fails to resolve overload for int. + // Clang: Resolves to halfOrInt16(uint16_t). + #endif + half H = asfloat16(0x01); // DXC: Resolves to halfOrInt16(half). + // Clang: Resolves to halfOrInt16(uint16_t). + + takesDoubles(X, Y, Z); // Works on all compilers + #ifndef IGNORE_ERRORS + fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to double. + // Clang: Resolces to fma(double,double,double). + #endif + + double D = dot(A, B); // DXC: Resolves to dot(double3, double3), fails DXIL Validation. + // FXC: Expands to compute double dot product with fmul/fadd + // Clang: Resolves to dot(float3, float3), emits conversion warnings. + + } + +`Compiler Explorer <https://godbolt.org/z/1qz6sn713>`_ + +.. note:: + + In Clang a conscious decision was made to exclude the ``dot(vector<double,N>, + vector<double,N>)`` overload and allow overload resolution to resolve the + ``vector<float,N>`` overload. This approach provides ``-Wconversion`` + diagnostic notifying the user of the conversion rather than silently altering + precision relative to the other overloads (as FXC does) or generating code + that will fail validation (as DXC does). diff --git a/clang/docs/HLSL/HLSLDocs.rst b/clang/docs/HLSL/HLSLDocs.rst index 1f232129548d0b..97b2425f013b34 100644 --- a/clang/docs/HLSL/HLSLDocs.rst +++ b/clang/docs/HLSL/HLSLDocs.rst @@ -11,6 +11,7 @@ HLSL Design and Implementation .. toctree:: :maxdepth: 1 + ExpectedDifferences HLSLIRReference ResourceTypes EntryFunctions >From 4db3f1205b81ec3f2900a09311235cac09a96a1d Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Tue, 20 Feb 2024 12:38:51 -0600 Subject: [PATCH 2/6] Fix typo in comments --- clang/docs/HLSL/ExpectedDifferences.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index f1d52b52092466..ac3846a5da121d 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -77,12 +77,12 @@ behavior between Clang and DXC. Some examples include: halfOrInt16(I); // All: Resolves to halfOrInt16(uint16_t). #ifndef IGNORE_ERRORS half H = asfloat16(I); // DXC: Fails to resolve overload for int. - // Clang: Resolves to halfOrInt16(uint16_t). + // Clang: Resolves to asfloat16(uint16_t). half H = asfloat16(U); // DXC: Fails to resolve overload for int. - // Clang: Resolves to halfOrInt16(uint16_t). + // Clang: Resolves to asfloat16(uint16_t). #endif - half H = asfloat16(0x01); // DXC: Resolves to halfOrInt16(half). - // Clang: Resolves to halfOrInt16(uint16_t). + half H = asfloat16(0x01); // DXC: Resolves to asfloat16(half). + // Clang: Resolves to asfloat16(uint16_t). takesDoubles(X, Y, Z); // Works on all compilers #ifndef IGNORE_ERRORS >From 046f4be042bf659548160eac3ad32557491bcbb9 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Tue, 20 Feb 2024 13:02:49 -0600 Subject: [PATCH 3/6] Fix another code typo and the godbolt link --- clang/docs/HLSL/ExpectedDifferences.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index ac3846a5da121d..5832e66666f470 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -67,7 +67,7 @@ behavior between Clang and DXC. Some examples include: cbuffer CB { uint U; - uint I; + int I; float X, Y, Z; double3 A, B; } @@ -96,7 +96,7 @@ behavior between Clang and DXC. Some examples include: } -`Compiler Explorer <https://godbolt.org/z/1qz6sn713>`_ +`Compiler Explorer <https://godbolt.org/z/a9q74E95T>`_ .. note:: >From 959c83747faecd8897cede0bb8331e428b39d95c Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Tue, 20 Feb 2024 14:36:11 -0600 Subject: [PATCH 4/6] One more set of fixes to the code sample and comments --- clang/docs/HLSL/ExpectedDifferences.rst | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index 5832e66666f470..647c87b29b637e 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -75,14 +75,15 @@ behavior between Clang and DXC. Some examples include: export void call() { halfOrInt16(U); // All: Resolves to halfOrInt16(uint16_t). halfOrInt16(I); // All: Resolves to halfOrInt16(uint16_t). + half H; #ifndef IGNORE_ERRORS - half H = asfloat16(I); // DXC: Fails to resolve overload for int. - // Clang: Resolves to asfloat16(uint16_t). - half H = asfloat16(U); // DXC: Fails to resolve overload for int. - // Clang: Resolves to asfloat16(uint16_t). + H = asfloat16(I); // DXC: Fails to resolve overload for int. + // Clang: Resolves to asfloat16(uint16_t). + H = asfloat16(U); // DXC: Fails to resolve overload for int. + // Clang: Resolves to asfloat16(uint16_t). #endif - half H = asfloat16(0x01); // DXC: Resolves to asfloat16(half). - // Clang: Resolves to asfloat16(uint16_t). + H = asfloat16(0x01); // DXC: Resolves to asfloat16(half). + // Clang: Resolves to asfloat16(uint16_t). takesDoubles(X, Y, Z); // Works on all compilers #ifndef IGNORE_ERRORS @@ -96,8 +97,6 @@ behavior between Clang and DXC. Some examples include: } -`Compiler Explorer <https://godbolt.org/z/a9q74E95T>`_ - .. note:: In Clang a conscious decision was made to exclude the ``dot(vector<double,N>, >From b32591e3581e805db9166f0b47fc5a0c10c015dd Mon Sep 17 00:00:00 2001 From: Chris B <cbiene...@microsoft.com> Date: Tue, 20 Feb 2024 17:57:46 -0600 Subject: [PATCH 5/6] Update clang/docs/HLSL/ExpectedDifferences.rst Co-authored-by: S. Bharadwaj Yadavalli <bharadwaj.yadava...@microsoft.com> --- clang/docs/HLSL/ExpectedDifferences.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index 647c87b29b637e..c65f37fbb5eddd 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -99,8 +99,8 @@ behavior between Clang and DXC. Some examples include: .. note:: - In Clang a conscious decision was made to exclude the ``dot(vector<double,N>, - vector<double,N>)`` overload and allow overload resolution to resolve the + In Clang, a conscious decision was made to exclude the ``dot(vector<double,N>, vector<double,N>)`` + overload and allow overload resolution to resolve the ``vector<float,N>`` overload. This approach provides ``-Wconversion`` diagnostic notifying the user of the conversion rather than silently altering precision relative to the other overloads (as FXC does) or generating code >From 6c2253c0a61f1d4ba7d7c570dea0f4858c553692 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Wed, 21 Feb 2024 12:13:56 -0600 Subject: [PATCH 6/6] One last set of comment fixes --- clang/docs/HLSL/ExpectedDifferences.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/clang/docs/HLSL/ExpectedDifferences.rst b/clang/docs/HLSL/ExpectedDifferences.rst index c65f37fbb5eddd..60001b22dc7920 100644 --- a/clang/docs/HLSL/ExpectedDifferences.rst +++ b/clang/docs/HLSL/ExpectedDifferences.rst @@ -61,7 +61,8 @@ behavior between Clang and DXC. Some examples include: .. code-block:: c++ void halfOrInt16(half H); - void halfOrInt16(uint16_t I); + void halfOrInt16(uint16_t U); + void halfOrInt16(int16_t I); void takesDoubles(double, double, double); @@ -73,12 +74,14 @@ behavior between Clang and DXC. Some examples include: } export void call() { - halfOrInt16(U); // All: Resolves to halfOrInt16(uint16_t). - halfOrInt16(I); // All: Resolves to halfOrInt16(uint16_t). + halfOrInt16(U); // DXC: Fails with call ambiguous between int16_t and uint16_t overloads + // Clang: Resolves to halfOrInt16(uint16_t). + halfOrInt16(I); // All: Resolves to halfOrInt16(int16_t). half H; #ifndef IGNORE_ERRORS + // asfloat16 is a builtin with overloads for half, int16_t, and uint16_t. H = asfloat16(I); // DXC: Fails to resolve overload for int. - // Clang: Resolves to asfloat16(uint16_t). + // Clang: Resolves to asfloat16(int16_t). H = asfloat16(U); // DXC: Fails to resolve overload for int. // Clang: Resolves to asfloat16(uint16_t). #endif @@ -88,7 +91,7 @@ behavior between Clang and DXC. Some examples include: takesDoubles(X, Y, Z); // Works on all compilers #ifndef IGNORE_ERRORS fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to double. - // Clang: Resolces to fma(double,double,double). + // Clang: Resolves to fma(double,double,double). #endif double D = dot(A, B); // DXC: Resolves to dot(double3, double3), fails DXIL Validation. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits