[clang] [HLSL] Rewrite a small subset of HLSL intrinsics into TableGen (PR #188362)

Deric C. via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 24 14:56:57 PDT 2026


https://github.com/Icohedron created https://github.com/llvm/llvm-project/pull/188362

Partially addresses https://github.com/llvm/llvm-project/issues/188345. This PR rewrites a small subset of the HLSL intrinsics into TableGen as a reference or example for later intrinsic rewrites.

The subset of intrinsics were chosen for the following reasons:

- `abs` has two sets of overloads split between aliasing the clang `builtin __builtin_elementwise_abs` and inline identity functions on unsigned integer types. It also operates on 16-bit types and the half type to demonstrate the automatic inclusion of `#ifdef __HLSL_ENABLE_16_BIT` guards and `_HLSL_AVAILABILITY(shadermodel, 6.2)` for 16-bit integer types, and `_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)` for half types.

- `and` demonstrates creating overloads with matrix types, and the ability to restrict the `Varying` type to only booleans.

- `cross` aliases two different clang builtins (`__builtin_hlsl_crossf32` and `__builtin_hlsl_crossf16`) and demonstrates the use of fixed vector-type arguments.

- `dot` has overloads for all vector types except for double-typed vectors, so the double-typed variant is split into its own scalar-only overload. It also demonstrates the use of `VaryingElemType` to always return the element type for the current overload.

- `dot2add` demonstrates the use of `DetailFunc` to create an inline function that calls `__detail::dot2add_impl(A, B, C)`. It also demonstrates the use of fixed-type arguments and return type (both scalar and vector), and the use of the `Availability` field to set the minimum shader model requirement.

- `GroupMemoryBarrierWithGroupSync` demonstrates creating an overload with void return type and no arguments, as well as being a wave function that needs to be annotated with `__attribute__((convergent))` by setting the `IsConvergent` field to 1.

- `isinf` demonstrates the use of `VaryingShape<T>` to specify a return type that is of the same shape as the Varying type for the current overload but with a fixed element type (`BoolTy` in this case).

- The defining of `refract` in TableGen instead of templates introduces some significant changes to error messages and also introduces a new offload test suite failure in the fp16 test because a call to `refract(x, y, 0.5)` where x and y are half-typed vectors is ambiguous due to 0.5 being a 32-bit float literal.

The generated `hlsl_alias_intrinsic_gen.inc` and `hlsl_inline_intrinsic_gen.inc` files for this PR can be viewed with this GitHub gist: https://gist.github.com/Icohedron/5ca4e1cc7e811ae72b091472478e9222
They can also be found in the build folder after building Clang, under the paths `lib/clang/23/include/hlsl/hlsl_alias_intrinsics_gen.inc` and `lib/clang/23/include/hlsl/hlsl_inline_intrinsics_gen.inc`.

Assisted-by: GitHub Copilot

>From d5af8c0c51310bc79957d5858a7ee461392aa1bd Mon Sep 17 00:00:00 2001
From: Deric Cheung <cheung.deric at gmail.com>
Date: Tue, 24 Mar 2026 14:40:08 -0700
Subject: [PATCH] Rewrite a subset of HLSL intrinsics into TableGen

Assisted-by: GitHub Copilot
---
 clang/include/clang/Basic/HLSLIntrinsics.td   | 163 ++++++++-
 .../lib/Headers/hlsl/hlsl_alias_intrinsics.h  | 310 ------------------
 clang/lib/Headers/hlsl/hlsl_intrinsics.h      |  74 -----
 .../test/SemaHLSL/BuiltIns/cross-errors.hlsl  |  12 +-
 .../SemaHLSL/BuiltIns/dot2add-errors.hlsl     |   4 +-
 .../SemaHLSL/BuiltIns/refract-errors.hlsl     |  58 ++--
 6 files changed, 192 insertions(+), 429 deletions(-)

diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index b205491e6ca78..8811f747f3452 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -313,8 +313,163 @@ class HLSLOneArgInlineBuiltin<string name> : HLSLBuiltin<name> {
 // Intrinsic definitions (sorted alphabetically by function name)
 //===----------------------------------------------------------------------===//
 
-// TODO: Convert hand-written overloads from hlsl_intrinsics.h and
-//       hlsl_alias_intrinsics.h into TableGen below.
-//       Include "hlsl_alias_intrinsics_gen.inc" in hlsl_alias_intrinsics.h
-//       Include "hlsl_inline_intrinsics_gen.inc" in hlsl_intrinsics.h
+// Returns the absolute value of the input value, Val.
+def hlsl_abs : HLSLOneArgBuiltin<"abs", "__builtin_elementwise_abs"> {
+  let Doc = [{
+\fn T abs(T Val)
+\brief Returns the absolute value of the input value, \a Val.
+\param Val The input value.
+}];
+  let VaryingTypes = SignedTypes;
+  let VaryingMatDims = [];
+}
+
+// Unsigned abs is a constexpr identity — unsigned values are already non-negative.
+def hlsl_abs_unsigned : HLSLOneArgInlineBuiltin<"abs"> {
+  let ParamNames = ["V"];
+  let Body = "return V;";
+  let IsConstexpr = 1;
+  let VaryingTypes = UnsignedIntTypes;
+  let VaryingMatDims = [];
+}
+
+// Returns the boolean AND of two bool values or vectors.
+def hlsl_and : HLSLTwoArgBuiltin<"and", "__builtin_hlsl_and"> {
+  let Doc = [{
+\fn bool and(bool x, bool y)
+\brief Logically ands two boolean vectors or matrices elementwise and
+produces a bool vector or matrix output.
+}];
+  let VaryingTypes = [BoolTy];
+}
+
+// Returns the cross product of two floating-point, 3D vectors.
+// Two separate defs are needed because the float and half variants alias
+// different builtins (__builtin_hlsl_crossf32 vs __builtin_hlsl_crossf16).
+def hlsl_cross_float : HLSLBuiltin<"cross", "__builtin_hlsl_crossf32"> {
+  let Doc = [{
+\fn T cross(T x, T y)
+\brief Returns the cross product of two floating-point, 3D vectors.
+\param x [in] The first floating-point, 3D vector.
+\param y [in] The second floating-point, 3D vector.
+
+Result is the cross product of x and y, i.e., the resulting
+components are, in order :
+x[1] * y[2] - y[1] * x[2]
+x[2] * y[0] - y[2] * x[0]
+x[0] * y[1] - y[0] * x[1]
+}];
+  let Args = [VectorType<FloatTy, 3>, VectorType<FloatTy, 3>];
+  let ReturnType = VectorType<FloatTy, 3>;
+}
+
+def hlsl_cross_half : HLSLBuiltin<"cross", "__builtin_hlsl_crossf16"> {
+  let Args = [VectorType<HalfTy, 3>, VectorType<HalfTy, 3>];
+  let ReturnType = VectorType<HalfTy, 3>;
+}
+
+// Returns the dot product (a scalar value) of X and Y.
+def hlsl_dot : HLSLTwoArgBuiltin<"dot", "__builtin_hlsl_dot"> {
+  let Doc = [{
+\fn K dot(T X, T Y)
+\brief Return the dot product (a scalar value) of \a X and \a Y.
+\param X The X input value.
+\param Y The Y input value.
+}];
+  let ReturnType = VaryingElemType;
+  let VaryingTypes = NumericTypesNoDbl;
+  let VaryingMatDims = [];
+}
+
+// double dot only has scalar overload (no vectors).
+def hlsl_dot_double : HLSLBuiltin<"dot", "__builtin_hlsl_dot"> {
+  let Args = [Varying, Varying];
+  let ReturnType = VaryingElemType;
+  let VaryingTypes = [DoubleTy];
+  let VaryingScalar = 1;
+}
+
+// Dot product of 2 half vectors plus a float scalar.
+def hlsl_dot2add : HLSLBuiltin<"dot2add"> {
+  let Doc = [{
+\fn float dot2add(half2 A, half2 B, float C)
+\brief Dot product of 2 vector of type half and add a float scalar value.
+\param A The first input value to dot product.
+\param B The second input value to dot product.
+\param C The input value added to the dot product.
+}];
+  let DetailFunc = "dot2add_impl";
+  let ParamNames = ["A", "B", "C"];
+  let Args = [VectorType<HalfTy, 2>, VectorType<HalfTy, 2>, FloatTy];
+  let ReturnType = FloatTy;
+  let Availability = SM6_4;
+}
+
+// Blocks execution of all threads in a group until all group shared accesses
+// have been completed and all threads in the group have reached this call.
+def hlsl_group_memory_barrier_with_group_sync :
+    HLSLBuiltin<"GroupMemoryBarrierWithGroupSync",
+                "__builtin_hlsl_group_memory_barrier_with_group_sync"> {
+  let Doc = [{
+\fn void GroupMemoryBarrierWithGroupSync(void)
+\brief Blocks execution of all threads in a group until all group shared
+accesses have been completed and all threads in the group have reached this
+call.
+}];
+  let IsConvergent = 1;
+}
+
+// Determines if the specified value x is infinite.
+def hlsl_isinf : HLSLOneArgBuiltin<"isinf", "__builtin_hlsl_elementwise_isinf"> {
+  let Doc = [{
+\fn T isinf(T x)
+\brief Determines if the specified value \a x is infinite.
+\param x The specified input value.
+
+Returns a value of the same size as the input, with a value set
+to True if the x parameter is +INF or -INF. Otherwise, False.
+}];
+  let ReturnType = VaryingShape<BoolTy>;
+  let VaryingTypes = [HalfTy, FloatTy];
+  let VaryingMatDims = [];
+}
+
+// Returns a refraction vector using an entering ray, a surface normal, and
+// a refraction index.
+def hlsl_refract : HLSLBuiltin<"refract"> {
+  let Doc = [{
+\fn T refract(T I, T N, T eta)
+\brief Returns a refraction using an entering ray, \a I, a surface
+normal, \a N and refraction index \a eta
+\param I The entering ray.
+\param N The surface normal.
+\param eta The refraction index.
+
+The return value is a floating-point vector that represents the refraction
+using the refraction index, \a eta, for the direction of the entering ray,
+\a I, off a surface with the normal \a N.
+
+This function calculates the refraction vector using the following formulas:
+k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
+if k < 0.0 the result is 0.0
+otherwise, the result is eta * I - (eta * dot(N, I) + sqrt(k)) * N
+
+I and N must already be normalized in order to achieve the desired result.
+
+I and N must be a scalar or vector whose component type is
+floating-point.
+
+eta must be a 16-bit or 32-bit floating-point scalar.
+
+Result type, the type of I, and the type of N must all be the same type.
+}];
+  let DetailFunc = "refract_impl";
+  let ParamNames = ["I", "N", "eta"];
+  let Args = [Varying, Varying, VaryingElemType];
+  let ReturnType = Varying;
+  let VaryingTypes = [HalfTy, FloatTy];
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = [];
+}
 
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index 76fca33ae0c13..90e681b55fa12 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -41,97 +41,6 @@ namespace hlsl {
 // Generated by clang-tblgen from HLSLIntrinsics.td (alias intrinsics).
 #include "hlsl_alias_intrinsics_gen.inc"
 
-//===----------------------------------------------------------------------===//
-// abs builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn T abs(T Val)
-/// \brief Returns the absolute value of the input value, \a Val.
-/// \param Val The input value.
-
-#ifdef __HLSL_ENABLE_16_BIT
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int16_t abs(int16_t);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int16_t2 abs(int16_t2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int16_t3 abs(int16_t3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int16_t4 abs(int16_t4);
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-constexpr uint16_t abs(uint16_t V) { return V; }
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-constexpr uint16_t2 abs(uint16_t2 V) { return V; }
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-constexpr uint16_t3 abs(uint16_t3 V) { return V; }
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-constexpr uint16_t4 abs(uint16_t4 V) { return V; }
-#endif
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-half abs(half);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-half2 abs(half2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-half3 abs(half3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-half4 abs(half4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int abs(int);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int2 abs(int2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int3 abs(int3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int4 abs(int4);
-
-constexpr uint abs(uint V) { return V; }
-constexpr uint2 abs(uint2 V) { return V; }
-constexpr uint3 abs(uint3 V) { return V; }
-constexpr uint4 abs(uint4 V) { return V; }
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-float abs(float);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-float2 abs(float2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-float3 abs(float3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-float4 abs(float4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int64_t abs(int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int64_t2 abs(int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int64_t3 abs(int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-int64_t4 abs(int64_t4);
-
-constexpr uint64_t abs(uint64_t V) { return V; }
-constexpr uint64_t2 abs(uint64_t2 V) { return V; }
-constexpr uint64_t3 abs(uint64_t3 V) { return V; }
-constexpr uint64_t4 abs(uint64_t4 V) { return V; }
-
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-double abs(double);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-double2 abs(double2);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-double3 abs(double3);
-_HLSL_BUILTIN_ALIAS(__builtin_elementwise_abs)
-double4 abs(double4);
-
 //===----------------------------------------------------------------------===//
 // acos builtins
 //===----------------------------------------------------------------------===//
@@ -295,60 +204,6 @@ bool all(double3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_all)
 bool all(double4);
 
-//===----------------------------------------------------------------------===//
-// and builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn bool and(bool x, bool y)
-/// \brief Logically ands two boolean vectors or matrices elementwise and
-/// produces a bool vector or matrix output.
-
-// TODO: Clean up clang-format marker once we've resolved
-//       https://github.com/llvm/llvm-project/issues/127851
-//
-// clang-format off
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool and(bool x, bool y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool2 and(bool2 x, bool2 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool3 and(bool3 x, bool3 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool4 and(bool4 x, bool4 y);
-
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool1x2 and(bool1x2 x, bool1x2 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool1x3 and(bool1x3 x, bool1x3 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool1x4 and(bool1x4 x, bool1x4 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool2x1 and(bool2x1 x, bool2x1 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool2x2 and(bool2x2 x, bool2x2 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool2x3 and(bool2x3 x, bool2x3 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool2x4 and(bool2x4 x, bool2x4 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool3x1 and(bool3x1 x, bool3x1 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool3x2 and(bool3x2 x, bool3x2 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool3x3 and(bool3x3 x, bool3x3 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool3x4 and(bool3x4 x, bool3x4 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool4x1 and(bool4x1 x, bool4x1 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool4x2 and(bool4x2 x, bool4x2 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool4x3 and(bool4x3 x, bool4x3 y);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
-bool4x4 and(bool4x4 x, bool4x4 y);
-// clang-format on
-
 //===----------------------------------------------------------------------===//
 // any builtins
 //===----------------------------------------------------------------------===//
@@ -912,104 +767,6 @@ float3 degrees(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_degrees)
 float4 degrees(float4);
 
-//===----------------------------------------------------------------------===//
-// dot product builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn K dot(T X, T Y)
-/// \brief Return the dot product (a scalar value) of \a X and \a Y.
-/// \param X The X input value.
-/// \param Y The Y input value.
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-half dot(half, half);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-half dot(half2, half2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-half dot(half3, half3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-half dot(half4, half4);
-
-#ifdef __HLSL_ENABLE_16_BIT
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int16_t dot(int16_t, int16_t);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int16_t dot(int16_t2, int16_t2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int16_t dot(int16_t3, int16_t3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int16_t dot(int16_t4, int16_t4);
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint16_t dot(uint16_t, uint16_t);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint16_t dot(uint16_t2, uint16_t2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint16_t dot(uint16_t3, uint16_t3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint16_t dot(uint16_t4, uint16_t4);
-#endif
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-float dot(float, float);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-float dot(float2, float2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-float dot(float3, float3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-float dot(float4, float4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-double dot(double, double);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int dot(int, int);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int dot(int2, int2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int dot(int3, int3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int dot(int4, int4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint dot(uint, uint);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint dot(uint2, uint2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint dot(uint3, uint3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint dot(uint4, uint4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int64_t dot(int64_t, int64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int64_t dot(int64_t2, int64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int64_t dot(int64_t3, int64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-int64_t dot(int64_t4, int64_t4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint64_t dot(uint64_t, uint64_t);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint64_t dot(uint64_t2, uint64_t2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint64_t dot(uint64_t3, uint64_t3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot)
-uint64_t dot(uint64_t4, uint64_t4);
-
 //===----------------------------------------------------------------------===//
 // dot4add builtins
 //===----------------------------------------------------------------------===//
@@ -1267,39 +1024,6 @@ float3 frac(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac)
 float4 frac(float4);
 
-//===----------------------------------------------------------------------===//
-// isinf builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn T isinf(T x)
-/// \brief Determines if the specified value \a x  is infinite.
-/// \param x The specified input value.
-///
-/// Returns a value of the same size as the input, with a value set
-/// to True if the x parameter is +INF or -INF. Otherwise, False.
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool isinf(half);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool2 isinf(half2);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool3 isinf(half3);
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool4 isinf(half4);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool isinf(float);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool2 isinf(float2);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool3 isinf(float3);
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf)
-bool4 isinf(float4);
-
 //===----------------------------------------------------------------------===//
 // isnan builtins
 //===----------------------------------------------------------------------===//
@@ -2019,28 +1743,6 @@ uint64_t3 reversebits(uint64_t3);
 _HLSL_BUILTIN_ALIAS(__builtin_elementwise_bitreverse)
 uint64_t4 reversebits(uint64_t4);
 
-//===----------------------------------------------------------------------===//
-// cross builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn T cross(T x, T y)
-/// \brief Returns the cross product of two floating-point, 3D vectors.
-/// \param x [in] The first floating-point, 3D vector.
-/// \param y [in] The second floating-point, 3D vector.
-///
-/// Result is the cross product of x and y, i.e., the resulting
-/// components are, in order :
-/// x[1] * y[2] - y[1] * x[2]
-/// x[2] * y[0] - y[2] * x[0]
-/// x[0] * y[1] - y[0] * x[1]
-
-_HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_crossf16)
-half3 cross(half3, half3);
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_crossf32)
-float3 cross(float3, float3);
-
 //===----------------------------------------------------------------------===//
 // rcp builtins
 //===----------------------------------------------------------------------===//
@@ -3773,18 +3475,6 @@ float3 radians(float3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_radians)
 float4 radians(float4);
 
-//===----------------------------------------------------------------------===//
-// GroupMemoryBarrierWithGroupSync builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn void GroupMemoryBarrierWithGroupSync(void)
-/// \brief Blocks execution of all threads in a group until all group shared
-/// accesses have been completed and all threads in the group have reached this
-/// call.
-
-_HLSL_BUILTIN_ALIAS(__builtin_hlsl_group_memory_barrier_with_group_sync)
-__attribute__((convergent)) void GroupMemoryBarrierWithGroupSync(void);
-
 //===----------------------------------------------------------------------===//
 // ddx_coarse builtin
 //===----------------------------------------------------------------------===//
diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
index 6a37a50064411..95d77eed41853 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -178,21 +178,6 @@ const inline float distance(__detail::HLSL_FIXED_VECTOR<float, N> X,
   return __detail::distance_vec_impl(X, Y);
 }
 
-//===----------------------------------------------------------------------===//
-// dot2add builtins
-//===----------------------------------------------------------------------===//
-
-/// \fn float dot2add(half2 A, half2 B, float C)
-/// \brief Dot product of 2 vector of type half and add a float scalar value.
-/// \param A The first input value to dot product.
-/// \param B The second input value to dot product.
-/// \param C The input value added to the dot product.
-
-_HLSL_AVAILABILITY(shadermodel, 6.4)
-const inline float dot2add(half2 A, half2 B, float C) {
-  return __detail::dot2add_impl(A, B, C);
-}
-
 //===----------------------------------------------------------------------===//
 // dst builtins
 //===----------------------------------------------------------------------===//
@@ -563,65 +548,6 @@ reflect(__detail::HLSL_FIXED_VECTOR<float, L> I,
   return __detail::reflect_vec_impl(I, N);
 }
 
-//===----------------------------------------------------------------------===//
-// refract builtin
-//===----------------------------------------------------------------------===//
-
-/// \fn T refract(T I, T N, T eta)
-/// \brief Returns a refraction using an entering ray, \a I, a surface
-/// normal, \a N and refraction index \a eta
-/// \param I The entering ray.
-/// \param N The surface normal.
-/// \param eta The refraction index.
-///
-/// The return value is a floating-point vector that represents the refraction
-/// using the refraction index, \a eta, for the direction of the entering ray,
-/// \a I, off a surface with the normal \a N.
-///
-/// This function calculates the refraction vector using the following formulas:
-/// k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
-/// if k < 0.0 the result is 0.0
-/// otherwise, the result is eta * I - (eta * dot(N, I) + sqrt(k)) * N
-///
-/// I and N must already be normalized in order to achieve the desired result.
-///
-/// I and N must be a scalar or vector whose component type is
-/// floating-point.
-///
-/// eta must be a 16-bit or 32-bit floating-point scalar.
-///
-/// Result type, the type of I, and the type of N must all be the same type.
-
-template <typename T>
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-const inline __detail::enable_if_t<__detail::is_arithmetic<T>::Value &&
-                                       __detail::is_same<half, T>::value,
-                                   T> refract(T I, T N, T eta) {
-  return __detail::refract_impl(I, N, eta);
-}
-
-template <typename T>
-const inline __detail::enable_if_t<
-    __detail::is_arithmetic<T>::Value && __detail::is_same<float, T>::value, T>
-refract(T I, T N, T eta) {
-  return __detail::refract_impl(I, N, eta);
-}
-
-template <int L>
-_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
-const inline __detail::HLSL_FIXED_VECTOR<half, L> refract(
-    __detail::HLSL_FIXED_VECTOR<half, L> I,
-    __detail::HLSL_FIXED_VECTOR<half, L> N, half eta) {
-  return __detail::refract_impl(I, N, eta);
-}
-
-template <int L>
-const inline __detail::HLSL_FIXED_VECTOR<float, L>
-refract(__detail::HLSL_FIXED_VECTOR<float, L> I,
-        __detail::HLSL_FIXED_VECTOR<float, L> N, float eta) {
-  return __detail::refract_impl(I, N, eta);
-}
-
 //===----------------------------------------------------------------------===//
 // smoothstep builtin
 //===----------------------------------------------------------------------===//
diff --git a/clang/test/SemaHLSL/BuiltIns/cross-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/cross-errors.hlsl
index 2c3e8d1560c87..c9bd1bdd3cb8e 100644
--- a/clang/test/SemaHLSL/BuiltIns/cross-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/cross-errors.hlsl
@@ -4,8 +4,8 @@ void test_too_few_arg()
 {
   return cross();
   // expected-error at -1 {{no matching function for call to 'cross'}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 0 were provided}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 0 were provided}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function not viable: requires 2 arguments, but 0 were provided}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function not viable: requires 2 arguments, but 0 were provided}}
 }
 
 void test_too_few_arg_f32()
@@ -24,8 +24,8 @@ void test_too_many_arg(float3 p0)
 {
   return cross(p0, p0, p0);
   // expected-error at -1 {{no matching function for call to 'cross'}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function not viable: requires 2 arguments, but 3 were provided}}
 }
 
 void test_too_many_arg_f32(float3 p0)
@@ -56,6 +56,6 @@ void test_ambiguous(int p0)
 {
   return cross(p0,p0);
   // expected-error at -1 {{call to 'cross' is ambiguous}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function}}
-  // expected-note at hlsl/hlsl_alias_intrinsics.h:* {{candidate function}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function}}
+  // expected-note at hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function}}
 }
diff --git a/clang/test/SemaHLSL/BuiltIns/dot2add-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/dot2add-errors.hlsl
index 84333ba08b9b8..e576f73669002 100644
--- a/clang/test/SemaHLSL/BuiltIns/dot2add-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/dot2add-errors.hlsl
@@ -3,11 +3,11 @@
 float test_too_few_arg() {
   return dot2add();
   // expected-error at -1 {{no matching function for call to 'dot2add'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 3 arguments, but 0 were provided}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* {{candidate function not viable: requires 3 arguments, but 0 were provided}}
 }
 
 float test_too_many_arg(half2 p1, half2 p2, float p3) {
   return dot2add(p1, p2, p3, p1);
   // expected-error at -1 {{no matching function for call to 'dot2add'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function not viable: requires 3 arguments, but 4 were provided}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* {{candidate function not viable: requires 3 arguments, but 4 were provided}}
 }
diff --git a/clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl
index fce41a4a46d38..8d9949f52aeb0 100644
--- a/clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/refract-errors.hlsl
@@ -3,64 +3,56 @@
 float test_no_second_arg(float3 p0) {
   return refract(p0);
   // expected-error at -1 {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 1 was provided}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 8 {{candidate function not viable: requires 3 arguments, but 1 was provided}}
 }
 
 float test_no_third_arg(float3 p0) {
   return refract(p0, p0);
   // expected-error at -1 {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 2 were provided}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 8 {{candidate function not viable: requires 3 arguments, but 2 were provided}}
 }
 
 float test_too_many_arg(float2 p0) {
   return refract(p0, p0, p0, p0);
   // expected-error at -1 {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate function template not viable: requires 3 arguments, but 4 were provided}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 8 {{candidate function not viable: requires 3 arguments, but 4 were provided}}
 }
 
 float test_double_inputs(double p0, double p1, double p2) {
   return refract(p0, p1, p2);
-  // expected-error at -1  {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
+  // expected-error at -1  {{call to 'refract' is ambiguous}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 2 {{candidate function}}
 }
 
 float test_int_inputs(int p0, int p1, int p2) {
   return refract(p0, p1, p2);
-  // expected-error at -1  {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
+  // expected-error at -1  {{call to 'refract' is ambiguous}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 2 {{candidate function}}
 }
 
 float1 test_vec1_inputs(float1 p0, float1 p1, float1 p2) {
   return refract(p0, p1, p2);
-  // expected-error at -1  {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with T = float1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, vector<float, 1>>'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 1]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
+  // expected-warning at -1 {{implicit conversion turns vector to scalar: 'float1' (aka 'vector<float, 1>') to 'float'}}
+  // expected-warning at -2 {{implicit conversion turns vector to scalar: 'float1' (aka 'vector<float, 1>') to 'float'}}
+  // expected-warning at -3 {{implicit conversion turns vector to scalar: 'float1' (aka 'vector<float, 1>') to 'float'}}
 }
 
 typedef float float5 __attribute__((ext_vector_type(5)));
 
-float5 test_vec5_inputs(float5 p0, float5 p1,  float p2) {
+float5 test_vec5_inputs(float5 p0, float5 p1, float p2) {
   return refract(p0, p1, p2);
-  // expected-error at -1  {{no matching function for call to 'refract'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: deduced conflicting types for parameter 'T' ('float5' (vector of 5 'float' values) vs. 'float')}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: deduced conflicting types for parameter 'T' ('float5' (vector of 5 'float' values) vs. 'float')}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, half>'}}
-  // expected-note at hlsl/hlsl_intrinsics.h:* {{candidate template ignored: substitution failure [with L = 5]: no type named 'Type' in 'hlsl::__detail::enable_if<false, float>'}}
+  // expected-error at -1  {{call to 'refract' is ambiguous}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 4 {{candidate function}}
+}
+
+half3 test_half_inputs_with_float(half3 p0, half3 p1, float p3) {
+  return refract(p0, p1, p3);
+  // expected-error at -1  {{call to 'refract' is ambiguous}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 6 {{candidate function}}
+}
+
+half3 test_half_inputs_with_float_literal(half3 p0, half3 p1) {
+  return refract(p0, p1, 0.5);
+  // expected-error at -1  {{call to 'refract' is ambiguous}}
+  // expected-note at hlsl/hlsl_inline_intrinsics_gen.inc:* 6 {{candidate function}}
 }



More information about the cfe-commits mailing list