[clang] [HLSL][Doc] Add doc about expected differences (PR #82395)

Chris B via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 20 11:03:11 PST 2024


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.bieneman at me.com>
Date: Tue, 20 Feb 2024 12:01:16 -0600
Subject: [PATCH 1/3] [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.bieneman at me.com>
Date: Tue, 20 Feb 2024 12:38:51 -0600
Subject: [PATCH 2/3] 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.bieneman at me.com>
Date: Tue, 20 Feb 2024 13:02:49 -0600
Subject: [PATCH 3/3] 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::
 



More information about the cfe-commits mailing list