diff --git a/tools/clang/unittests/HLSLExec/LongVectors.cpp b/tools/clang/unittests/HLSLExec/LongVectors.cpp index 58507d569a..4b21206c7c 100644 --- a/tools/clang/unittests/HLSLExec/LongVectors.cpp +++ b/tools/clang/unittests/HLSLExec/LongVectors.cpp @@ -883,12 +883,33 @@ CAST_OP(OpType::CastToFloat64, double, (CastToFloat64(A))); // specs. An example with this spec for sin and cos is available here: // https://microsoft.github.io/DirectX-Specs/d3d/archive/D3D11_3_FunctionalSpec.htm#22.10.20 -struct TrigonometricValidation { +template struct TrigonometricValidation { ValidationConfig ValidationConfig = ValidationConfig::Epsilon(0.0008f); }; +// Half precision trig functions have a larger tolerance due to their lower +// precision. Note that the D3D spec +// does not mention half precision trig functions. +template struct TrigonometricValidation { + ValidationConfig ValidationConfig = ValidationConfig::Epsilon(0.003f); +}; + +// For the half precision trig functions with an infinite range in either +// direction we use 2 ULPs of tolerance instead. +template <> struct TrigonometricValidation { + ValidationConfig ValidationConfig = ValidationConfig::Ulp(2.0f); +}; + +template <> struct TrigonometricValidation { + ValidationConfig ValidationConfig = ValidationConfig::Ulp(2.0f); +}; + +template <> struct TrigonometricValidation { + ValidationConfig ValidationConfig = ValidationConfig::Ulp(2.0f); +}; + #define TRIG_OP(OP, IMPL) \ - template struct Op : TrigonometricValidation { \ + template struct Op : TrigonometricValidation { \ T operator()(T A) { return IMPL; } \ }