Skip to content

Commit 66f6929

Browse files
[HLSL][Doc] Add doc about expected differences (#82395)
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. --------- Co-authored-by: S. Bharadwaj Yadavalli <[email protected]>
1 parent c1e9883 commit 66f6929

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
2+
Expected Differences vs DXC and FXC
3+
===================================
4+
5+
.. contents::
6+
:local:
7+
8+
Introduction
9+
============
10+
11+
HLSL currently has two reference compilers, the `DirectX Shader Compiler (DXC)
12+
<https://github.com/microsoft/DirectXShaderCompiler/>`_ and the
13+
`Effect-Compiler (FXC) <https://learn.microsoft.com/en-us/windows/win32/direct3dtools/fxc>`_.
14+
The two reference compilers do not fully agree. Some known disagreements in the
15+
references are tracked on
16+
`DXC's GitHub
17+
<https://github.com/microsoft/DirectXShaderCompiler/issues?q=is%3Aopen+is%3Aissue+label%3Afxc-disagrees>`_,
18+
but many more are known to exist.
19+
20+
HLSL as implemented by Clang will also not fully match either of the reference
21+
implementations, it is instead being written to match the `draft language
22+
specification <https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf>`_.
23+
24+
This document is a non-exhaustive collection the known differences between
25+
Clang's implementation of HLSL and the existing reference compilers.
26+
27+
General Principles
28+
------------------
29+
30+
Most of the intended differences between Clang and the earlier reference
31+
compilers are focused on increased consistency and correctness. Both reference
32+
compilers do not always apply language rules the same in all contexts.
33+
34+
Clang also deviates from the reference compilers by providing different
35+
diagnostics, both in terms of the textual messages and the contexts in which
36+
diagnostics are produced. While striving for a high level of source
37+
compatibility with conforming HLSL code, Clang may produce earlier and more
38+
robust diagnostics for incorrect code or reject code that a reference compiler
39+
incorrectly accepted.
40+
41+
Language Version
42+
================
43+
44+
Clang targets language compatibility for HLSL 2021 as implemented by DXC.
45+
Language features that were removed in earlier versions of HLSL may be added on
46+
a case-by-case basis, but are not planned for the initial implementation.
47+
48+
Overload Resolution
49+
===================
50+
51+
Clang's HLSL implementation adopts C++ overload resolution rules as proposed for
52+
HLSL 202x based on proposal
53+
`0007 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0007-const-instance-methods.md>`_
54+
and
55+
`0008 <https://github.com/microsoft/hlsl-specs/blob/main/proposals/0008-non-member-operator-overloading.md>`_.
56+
57+
Clang's implementation extends standard overload resolution rules to HLSL
58+
library functionality. This causes subtle changes in overload resolution
59+
behavior between Clang and DXC. Some examples include:
60+
61+
.. code-block:: c++
62+
63+
void halfOrInt16(half H);
64+
void halfOrInt16(uint16_t U);
65+
void halfOrInt16(int16_t I);
66+
67+
void takesDoubles(double, double, double);
68+
69+
cbuffer CB {
70+
uint U;
71+
int I;
72+
float X, Y, Z;
73+
double3 A, B;
74+
}
75+
76+
export void call() {
77+
halfOrInt16(U); // DXC: Fails with call ambiguous between int16_t and uint16_t overloads
78+
// Clang: Resolves to halfOrInt16(uint16_t).
79+
halfOrInt16(I); // All: Resolves to halfOrInt16(int16_t).
80+
half H;
81+
#ifndef IGNORE_ERRORS
82+
// asfloat16 is a builtin with overloads for half, int16_t, and uint16_t.
83+
H = asfloat16(I); // DXC: Fails to resolve overload for int.
84+
// Clang: Resolves to asfloat16(int16_t).
85+
H = asfloat16(U); // DXC: Fails to resolve overload for int.
86+
// Clang: Resolves to asfloat16(uint16_t).
87+
#endif
88+
H = asfloat16(0x01); // DXC: Resolves to asfloat16(half).
89+
// Clang: Resolves to asfloat16(uint16_t).
90+
91+
takesDoubles(X, Y, Z); // Works on all compilers
92+
#ifndef IGNORE_ERRORS
93+
fma(X, Y, Z); // DXC: Fails to resolve no known conversion from float to double.
94+
// Clang: Resolves to fma(double,double,double).
95+
#endif
96+
97+
double D = dot(A, B); // DXC: Resolves to dot(double3, double3), fails DXIL Validation.
98+
// FXC: Expands to compute double dot product with fmul/fadd
99+
// Clang: Resolves to dot(float3, float3), emits conversion warnings.
100+
101+
}
102+
103+
.. note::
104+
105+
In Clang, a conscious decision was made to exclude the ``dot(vector<double,N>, vector<double,N>)``
106+
overload and allow overload resolution to resolve the
107+
``vector<float,N>`` overload. This approach provides ``-Wconversion``
108+
diagnostic notifying the user of the conversion rather than silently altering
109+
precision relative to the other overloads (as FXC does) or generating code
110+
that will fail validation (as DXC does).

clang/docs/HLSL/HLSLDocs.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ HLSL Design and Implementation
1111
.. toctree::
1212
:maxdepth: 1
1313

14+
ExpectedDifferences
1415
HLSLIRReference
1516
ResourceTypes
1617
EntryFunctions

0 commit comments

Comments
 (0)