https://github.com/Icohedron updated 
https://github.com/llvm/llvm-project/pull/187610

>From 6d71771e9220af9b9c1f80b772352745f6634e99 Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Thu, 19 Mar 2026 15:16:17 -0700
Subject: [PATCH 1/2] Implement TableGen for builtin HLSL intrinsics

Assisted-by: GitHub Copilot (powered by Claude Opus 4.6)
---
 clang/include/clang/Basic/HLSLIntrinsics.td   | 480 ++++++++++++++
 clang/lib/Headers/CMakeLists.txt              |  15 +-
 .../lib/Headers/hlsl/hlsl_alias_intrinsics.h  | 311 +---------
 clang/lib/Headers/hlsl/hlsl_intrinsics.h      |  77 +--
 .../test/SemaHLSL/BuiltIns/cross-errors.hlsl  |  12 +-
 .../SemaHLSL/BuiltIns/dot2add-errors.hlsl     |   4 +-
 .../SemaHLSL/BuiltIns/refract-errors.hlsl     |  58 +-
 clang/utils/TableGen/CMakeLists.txt           |   1 +
 clang/utils/TableGen/HLSLEmitter.cpp          | 585 ++++++++++++++++++
 clang/utils/TableGen/TableGen.cpp             |  14 +
 clang/utils/TableGen/TableGenBackends.h       |   5 +
 11 files changed, 1136 insertions(+), 426 deletions(-)
 create mode 100644 clang/include/clang/Basic/HLSLIntrinsics.td
 create mode 100644 clang/utils/TableGen/HLSLEmitter.cpp

diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td 
b/clang/include/clang/Basic/HLSLIntrinsics.td
new file mode 100644
index 0000000000000..4676d9b3b611e
--- /dev/null
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -0,0 +1,480 @@
+//===--- HLSLIntrinsics.td - HLSL intrinsic declarations ---*- tablegen 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines HLSL intrinsic functions in tablegen. The HLSLEmitter
+// backend processes these definitions and generates two .inc files:
+//   - hlsl_alias_intrinsics_gen.inc: builtin alias declarations using
+//     _HLSL_BUILTIN_ALIAS, included by hlsl_alias_intrinsics.h.
+//   - hlsl_inline_intrinsics_gen.inc: inline function definitions (detail
+//     helper calls and literal bodies), included by hlsl_intrinsics.h.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Argument and return type base classes
+//===----------------------------------------------------------------------===//
+
+// Base class for argument and return type positions.
+class HLSLArgType;
+
+// Base class for return type positions.
+class HLSLReturnType;
+
+// Void return type.
+def VoidTy : HLSLReturnType;
+
+//===----------------------------------------------------------------------===//
+// HLSL element types
+//===----------------------------------------------------------------------===//
+
+// Represents a concrete HLSL scalar element type.
+// Can be used directly as an argument or return type for a fixed scalar
+// (e.g., FloatTy in Args produces a 'float' argument).
+class HLSLType<string name> : HLSLArgType, HLSLReturnType {
+  string Name = name;
+  string TypeName = name;
+
+  // When set, overloads using this type are guarded by
+  // #ifdef __HLSL_ENABLE_16_BIT and emitted with
+  // _HLSL_AVAILABILITY(shadermodel, 6.2), or the intrinsic's Availability
+  // if it is greater.
+  bit Is16Bit = 0;
+
+  // When set, overloads using this type are emitted with
+  // _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) instead of _HLSL_AVAILABILITY.
+  // This macro expands to an availability attribute only when
+  // __HLSL_ENABLE_16_BIT is defined (i.e. half is a true 16-bit float);
+  // otherwise it expands to nothing since half is an alias for float.
+  // If the intrinsic's Availability is >= SM6.2, _HLSL_AVAILABILITY is used
+  // instead because 16-bit support is already implied.
+  bit IsConditionally16Bit = 0;
+}
+
+def BoolTy   : HLSLType<"bool">;
+def HalfTy   : HLSLType<"half">   { let IsConditionally16Bit = 1; }
+def FloatTy  : HLSLType<"float">;
+def DoubleTy : HLSLType<"double">;
+def Int16Ty  : HLSLType<"int16_t">  { let Is16Bit = 1; }
+def UInt16Ty : HLSLType<"uint16_t"> { let Is16Bit = 1; }
+def IntTy    : HLSLType<"int">;
+def UIntTy   : HLSLType<"uint">;
+def Int64Ty  : HLSLType<"int64_t">;
+def UInt64Ty : HLSLType<"uint64_t">;
+def UInt32Ty : HLSLType<"uint32_t">;
+
+//===----------------------------------------------------------------------===//
+// Element type groups
+//===----------------------------------------------------------------------===//
+
+defvar AllFloatTypes = [HalfTy, FloatTy, DoubleTy];
+defvar SignedIntTypes = [Int16Ty, IntTy, Int64Ty];
+defvar UnsignedIntTypes = [UInt16Ty, UIntTy, UInt64Ty];
+defvar AllIntTypes = [Int16Ty, UInt16Ty, IntTy, UIntTy,
+                      Int64Ty, UInt64Ty];
+defvar SignedTypes = [Int16Ty, HalfTy, IntTy, FloatTy,
+                      Int64Ty, DoubleTy];
+defvar AllNumericTypes = [Int16Ty, UInt16Ty, HalfTy, IntTy, UIntTy,
+                          FloatTy, Int64Ty, UInt64Ty, DoubleTy];
+defvar AllTypesWithBool = [BoolTy, Int16Ty, UInt16Ty, HalfTy,
+                           IntTy, UIntTy, FloatTy, Int64Ty,
+                           UInt64Ty, DoubleTy];
+defvar NumericTypesNoDbl = [Int16Ty, UInt16Ty, HalfTy, IntTy, UIntTy,
+                            FloatTy, Int64Ty, UInt64Ty];
+
+//===----------------------------------------------------------------------===//
+// Argument/return types
+//
+// These classes are usable in both argument and return type positions.
+//===----------------------------------------------------------------------===//
+
+// The varying type — expanded per VaryingTypes.
+// As an argument: the arg type varies with each overload.
+// As a return type: returns the same type as the varying arg.
+def Varying : HLSLArgType, HLSLReturnType;
+
+// The scalar element of the varying type.
+// As an argument: always the scalar element type regardless of overload shape.
+// As a return type: returns the scalar element type (e.g., float dot(float3, 
float3)).
+def VaryingElemType : HLSLArgType, HLSLReturnType;
+
+// The varying shape with a fixed element type.
+// As an argument: same shape as Varying but with the given element type.
+// As a return type: same shape as the varying arg but with the given element 
type.
+// For example, VaryingShape<UIntTy> with a float3 overload produces uint3.
+class VaryingShape<HLSLType ty> : HLSLArgType, HLSLReturnType {
+  HLSLType ElementType = ty;
+}
+
+// A concrete vector type (e.g., VectorType<UIntTy, 4> -> uint4).
+// As an argument: the arg is always this vector type.
+// As a return type: always returns this vector type, ignoring argument shape.
+class VectorType<HLSLType ty, int size> : HLSLArgType, HLSLReturnType {
+  HLSLType ElementType = ty;
+  int Size = size;
+}
+
+//===----------------------------------------------------------------------===//
+// Shader model versions
+//===----------------------------------------------------------------------===//
+
+// Represents a shader model version
+class ShaderModel<int major, int minor> {
+  int Major = major;
+  int Minor = minor;
+}
+
+// Sentinel: no shader model requirement.
+def NoSM  : ShaderModel<0, 0>;
+
+// Valid Shader Model records
+foreach i = 0...9 in {
+  def SM6_ #i : ShaderModel<6, i>;
+}
+
+//===----------------------------------------------------------------------===//
+// Matrix dimension records
+//===----------------------------------------------------------------------===//
+
+class MatDim<int rows, int cols> {
+  int Rows = rows;
+  int Cols = cols;
+}
+
+foreach r = 1...4 in
+  foreach c = 1...4 in
+    def Mat#r#"x"#c : MatDim<r, c>;
+
+// All non-1x1 matrix dimensions (1x2 through 4x4).
+defvar AllMatDims = [Mat1x2, Mat1x3, Mat1x4,
+                     Mat2x1, Mat2x2, Mat2x3, Mat2x4,
+                     Mat3x1, Mat3x2, Mat3x3, Mat3x4,
+                     Mat4x1, Mat4x2, Mat4x3, Mat4x4];
+
+//===----------------------------------------------------------------------===//
+// HLSLBuiltin class
+//===----------------------------------------------------------------------===//
+
+class HLSLBuiltin<string name, string builtin = ""> {
+  string Name = name;
+
+  // When set, generates a _HLSL_BUILTIN_ALIAS(Builtin) declaration that
+  // aliases the named Clang builtin. Mutually exclusive with DetailFunc
+  // and Body.
+  string Builtin = builtin;
+
+  // Doxygen documentation comment emitted before overloads in generated code.
+  string Doc = "";
+
+  // When set, generates an inline function body calling
+  // __detail::DetailFunc(args...) instead of _HLSL_BUILTIN_ALIAS(Builtin).
+  // Parameters are named p0, p1, p2, ... by default, or use ParamNames to
+  // specify custom names. Mutually exclusive with Body and Builtin.
+  string DetailFunc = "";
+
+  // When set, generates an inline function with this literal body text.
+  // Intended for single-statement functions. Multi-line functions should
+  // instead be defined as a helper and called with DetailFunc.
+  // Parameters are named p0, p1, p2, ... by default, or use ParamNames to
+  // specify custom names. Mutually exclusive with DetailFunc and Builtin.
+  code Body = "";
+
+  // Determines how the return type is derived for each overload.
+  HLSLReturnType ReturnType = VoidTy;
+
+  // Argument list. Each entry is either:
+  //   Varying     - type varies with VaryingTypes (expanded per type)
+  //   HLSLType    - a fixed scalar type at that position (e.g., UIntTy)
+  //   VectorType  - a fixed vector type at that position
+  // The number of arguments is deduced from the length of this list.
+  // Examples:
+  //   [Varying]                              -> func(T)
+  //   [Varying, Varying, Varying]            -> func(T, T, T)
+  //   [Varying, UInt32Ty]                    -> func(T, uint32_t)
+  //   [UIntTy, UIntTy, IntTy]                -> func(uint, uint, int)
+  //   []                                     -> func()
+  list<HLSLArgType> Args = [];
+
+  // Custom parameter names for generated functions.
+  // When empty, inline functions (Body or DetailFunc) use p0, p1, p2, ...
+  // and alias functions omit parameter names.
+  list<string> ParamNames = [];
+
+  // When set, emits 'constexpr' instead of 'inline' for inline functions
+  // (i.e., functions using Body or DetailFunc).
+  bit IsConstexpr = 0;
+
+  // Whether the function has the convergent attribute
+  bit IsConvergent = 0;
+
+  // Argument element types — drives overload expansion.
+  // One overload set is generated per type (scalar + vectors + matrices).
+  // Only used when Args contains Varying entries.
+  list<HLSLType> VaryingTypes = [];
+
+  // Whether to generate scalar overloads for Varying typed arguments.
+  bit VaryingScalar = 0;
+
+  // Vector sizes to generate for Varying typed arguments (e.g., [2,3,4]).
+  list<int> VaryingVecSizes = [];
+
+  // Matrix dimensions to generate for Varying typed arguments.
+  list<MatDim> VaryingMatDims = [];
+
+  // Default shader model availability version for all types.
+  // Use NoSM for no availability requirement.
+  ShaderModel Availability = NoSM;
+}
+
+//===----------------------------------------------------------------------===//
+// HLSLBuiltin helper subclasses
+//===----------------------------------------------------------------------===//
+
+// T func(T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLOneArgBuiltin<string name, string builtin>
+    : HLSLBuiltin<name, builtin> {
+  let Args = [Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// T func(T, T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLTwoArgBuiltin<string name, string builtin>
+    : HLSLBuiltin<name, builtin> {
+  let Args = [Varying, Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// T func(T, T, T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLThreeArgBuiltin<string name, string builtin>
+    : HLSLBuiltin<name, builtin> {
+  let Args = [Varying, Varying, Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// Detail function base: generates inline function bodies calling
+// __detail::DetailFunc(args...) instead of _HLSL_BUILTIN_ALIAS.
+class HLSLDetail<string name, string detail> : HLSLBuiltin<name> {
+  let DetailFunc = detail;
+}
+
+// T func(T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLOneArgDetail<string name, string detail>
+    : HLSLDetail<name, detail> {
+  let Args = [Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// T func(T, T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLTwoArgDetail<string name, string detail>
+    : HLSLDetail<name, detail> {
+  let Args = [Varying, Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// T func(T, T, T) with scalar + vec2/3/4 + matrix overloads.
+class HLSLThreeArgDetail<string name, string detail>
+    : HLSLDetail<name, detail> {
+  let Args = [Varying, Varying, Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+// Inline body variant: T func(T) with a literal inline body (no builtin 
alias).
+// Body must be specified (e.g., let Body = "return p0;").
+class HLSLOneArgInlineBuiltin<string name> : HLSLBuiltin<name> {
+  let Args = [Varying];
+  let ReturnType = Varying;
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = AllMatDims;
+}
+
+//===----------------------------------------------------------------------===//
+// Intrinsic definitions (sorted alphabetically by function name)
+//===----------------------------------------------------------------------===//
+
+// 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>;
+  // Do not specify Availability = SM6_2 here because HalfTy is a 32-bit float
+  // and is therefore available before SM6_2 if 16-bit types is not enabled.
+  // Because HalfTy IsConditionally16Bit, the emitter will automatically 
specify
+  // _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) with this overload.
+}
+
+// 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 Args = [VectorType<HalfTy, 2>, VectorType<HalfTy, 2>, FloatTy];
+  let ReturnType = FloatTy;
+  let ParamNames = ["A", "B", "C"];
+  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 Args = [Varying, Varying, VaryingElemType];
+  let ReturnType = Varying;
+  let VaryingTypes = [HalfTy, FloatTy];
+  let VaryingScalar = 1;
+  let VaryingVecSizes = [2, 3, 4];
+  let VaryingMatDims = [];
+  let ParamNames = ["I", "N", "eta"];
+}
+
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index c6c299bb61af3..702eca4d4690f 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -504,6 +504,16 @@ if(RISCV IN_LIST LLVM_TARGETS_TO_BUILD)
     )
 endif()
 
+# Generate HLSL intrinsic overloads
+if(CLANG_ENABLE_HLSL)
+  clang_generate_header(-gen-hlsl-alias-intrinsics HLSLIntrinsics.td
+                        hlsl/hlsl_alias_intrinsics_gen.inc)
+  clang_generate_header(-gen-hlsl-inline-intrinsics HLSLIntrinsics.td
+                        hlsl/hlsl_inline_intrinsics_gen.inc)
+  set(hlsl_generated_files
+    "${CMAKE_CURRENT_BINARY_DIR}/hlsl/hlsl_alias_intrinsics_gen.inc"
+    "${CMAKE_CURRENT_BINARY_DIR}/hlsl/hlsl_inline_intrinsics_gen.inc")
+endif()
 
 # Check if the generated headers are included in a target specific lists
 # Currently, all generated headers are target specific.
@@ -511,7 +521,8 @@ set(all_target_specific_generated_files
   ${arm_common_generated_files}
   ${arm_only_generated_files}
   ${aarch64_only_generated_files}
-  ${riscv_generated_files})
+  ${riscv_generated_files}
+  ${hlsl_generated_files})
 foreach( f ${generated_files} )
   if (NOT ${f} IN_LIST all_target_specific_generated_files)
     message(WARNING "${f} is a generated header but it is not included in any "
@@ -579,7 +590,7 @@ add_header_target("x86-resource-headers" "${x86_files}")
 add_header_target("gpu-resource-headers" "${gpu_files}")
 
 # Other header groupings
-add_header_target("hlsl-resource-headers" ${hlsl_files})
+add_header_target("hlsl-resource-headers" 
"${hlsl_files};${hlsl_generated_files}")
 add_header_target("spirv-resource-headers" ${spirv_files})
 add_header_target("opencl-resource-headers" ${opencl_files})
 add_header_target("llvm-libc-resource-headers" ${llvm_libc_wrapper_files})
diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index c2e4d74af6873..35a95a17768f7 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -38,96 +38,8 @@ namespace hlsl {
 #define _HLSL_16BIT_AVAILABILITY_SHADERMODEL_DEFAULT()
 #endif
 
-//===----------------------------------------------------------------------===//
-// 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);
+// Generated by clang-tblgen from HLSLIntrinsics.td (alias intrinsics).
+#include "hlsl_alias_intrinsics_gen.inc"
 
 
//===----------------------------------------------------------------------===//
 // acos builtins
@@ -292,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
 
//===----------------------------------------------------------------------===//
@@ -909,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
 
//===----------------------------------------------------------------------===//
@@ -1264,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
 
//===----------------------------------------------------------------------===//
@@ -2016,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
 
//===----------------------------------------------------------------------===//
@@ -3736,18 +3441,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 25d36f5483943..95d77eed41853 100644
--- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h
@@ -13,6 +13,9 @@
 
 namespace hlsl {
 
+// Generated by clang-tblgen from HLSLIntrinsics.td (detail/inline intrinsics).
+#include "hlsl_inline_intrinsics_gen.inc"
+
 
//===----------------------------------------------------------------------===//
 // asfloat builtins
 
//===----------------------------------------------------------------------===//
@@ -175,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
 
//===----------------------------------------------------------------------===//
@@ -560,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@-1 {{no matching function for call to 'cross'}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function not 
viable: requires 2 arguments, but 0 were provided}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function not 
viable: requires 2 arguments, but 0 were provided}}
+  // expected-note@hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function 
not viable: requires 2 arguments, but 0 were provided}}
+  // expected-note@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@-1 {{no matching function for call to 'cross'}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function not 
viable: requires 2 arguments, but 3 were provided}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function not 
viable: requires 2 arguments, but 3 were provided}}
+  // expected-note@hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function 
not viable: requires 2 arguments, but 3 were provided}}
+  // expected-note@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@-1 {{call to 'cross' is ambiguous}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function}}
-  // expected-note@hlsl/hlsl_alias_intrinsics.h:* {{candidate function}}
+  // expected-note@hlsl/hlsl_alias_intrinsics_gen.inc:* {{candidate function}}
+  // expected-note@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@-1 {{no matching function for call to 'dot2add'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires 3 arguments, but 0 were provided}}
+  // expected-note@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@-1 {{no matching function for call to 'dot2add'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function not viable: 
requires 3 arguments, but 4 were provided}}
+  // expected-note@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@-1 {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 1 was provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 1 was provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 1 was provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 1 was provided}}
+  // expected-note@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@-1 {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 2 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 2 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 2 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 2 were provided}}
+  // expected-note@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@-1 {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 4 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 4 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 4 were provided}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate function template not 
viable: requires 3 arguments, but 4 were provided}}
+  // expected-note@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@-1  {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
+  // expected-error@-1  {{call to 'refract' is ambiguous}}
+  // expected-note@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@-1  {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored}}
+  // expected-error@-1  {{call to 'refract' is ambiguous}}
+  // expected-note@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@-1  {{no matching function for call to 'refract'}}
-  // expected-note@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@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@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@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@-1 {{implicit conversion turns vector to scalar: 
'float1' (aka 'vector<float, 1>') to 'float'}}
+  // expected-warning@-2 {{implicit conversion turns vector to scalar: 
'float1' (aka 'vector<float, 1>') to 'float'}}
+  // expected-warning@-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@-1  {{no matching function for call to 'refract'}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: 
deduced conflicting types for parameter 'T' ('float5' (vector of 5 'float' 
values) vs. 'float')}}
-  // expected-note@hlsl/hlsl_intrinsics.h:* {{candidate template ignored: 
deduced conflicting types for parameter 'T' ('float5' (vector of 5 'float' 
values) vs. 'float')}}
-  // expected-note@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@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@-1  {{call to 'refract' is ambiguous}}
+  // expected-note@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@-1  {{call to 'refract' is ambiguous}}
+  // expected-note@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@-1  {{call to 'refract' is ambiguous}}
+  // expected-note@hlsl/hlsl_inline_intrinsics_gen.inc:* 6 {{candidate 
function}}
 }
diff --git a/clang/utils/TableGen/CMakeLists.txt 
b/clang/utils/TableGen/CMakeLists.txt
index 14f13824e9575..8b5e00c189cb9 100644
--- a/clang/utils/TableGen/CMakeLists.txt
+++ b/clang/utils/TableGen/CMakeLists.txt
@@ -21,6 +21,7 @@ add_tablegen(clang-tblgen CLANG
   ClangSACheckersEmitter.cpp
   ClangSyntaxEmitter.cpp
   ClangTypeNodesEmitter.cpp
+  HLSLEmitter.cpp
   MveEmitter.cpp
   NeonEmitter.cpp
   RISCVVEmitter.cpp
diff --git a/clang/utils/TableGen/HLSLEmitter.cpp 
b/clang/utils/TableGen/HLSLEmitter.cpp
new file mode 100644
index 0000000000000..6505f0402a709
--- /dev/null
+++ b/clang/utils/TableGen/HLSLEmitter.cpp
@@ -0,0 +1,585 @@
+//===--- HLSLEmitter.cpp - HLSL intrinsic header generator 
----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This tablegen backend generates hlsl_alias_intrinsics_gen.inc (alias
+// overloads) and hlsl_inline_intrinsics_gen.inc (inline/detail overloads) for
+// HLSL intrinsic functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/TableGen/Record.h"
+
+using namespace llvm;
+
+namespace {
+
+/// Minimum shader model version that supports 16-bit types.
+constexpr StringLiteral SM6_2 = "6.2";
+
+//===----------------------------------------------------------------------===//
+// Type name helpers
+//===----------------------------------------------------------------------===//
+
+static std::string getVectorTypeName(StringRef ElemType, unsigned N) {
+  return (ElemType + Twine(N)).str();
+}
+
+static std::string getMatrixTypeName(StringRef ElemType, unsigned Rows,
+                                     unsigned Cols) {
+  return (ElemType + Twine(Rows) + "x" + Twine(Cols)).str();
+}
+
+/// Get the fixed type name string for a VectorType or HLSLType record.
+static std::string getFixedTypeName(const Record *R) {
+  if (R->isSubClassOf("VectorType"))
+    return getVectorTypeName(
+        R->getValueAsDef("ElementType")->getValueAsString("Name"),
+        R->getValueAsInt("Size"));
+  assert(R->isSubClassOf("HLSLType"));
+  return R->getValueAsString("Name").str();
+}
+
+/// For a VectorType, return its ElementType record; for an HLSLType, return
+/// the record itself (it is already a scalar element type).
+static const Record *getElementTypeRecord(const Record *R) {
+  if (R->isSubClassOf("VectorType"))
+    return R->getValueAsDef("ElementType");
+  assert(R->isSubClassOf("HLSLType"));
+  return R;
+}
+
+//===----------------------------------------------------------------------===//
+// Type information
+//===----------------------------------------------------------------------===//
+
+/// Classifies how a type varies across overloads.
+enum TypeKindEnum {
+  TK_Varying = 0,      ///< Type matches the full varying type (e.g. float3).
+  TK_ElemType = 1,     ///< Type is the scalar element type (e.g. float).
+  TK_VaryingShape = 2, ///< Type uses the varying shape with a fixed element.
+  TK_FixedType = 3,    ///< Type is a fixed concrete type (e.g. "half2").
+  TK_Void = 4          ///< Type is void (only valid for return types).
+};
+
+/// Metadata describing how a type (argument or return) varies across 
overloads.
+struct TypeInfo {
+  /// Classification of how this type varies across overloads.
+  TypeKindEnum Kind = TK_Varying;
+
+  /// Fixed type name (e.g. "half2") for types with a concrete type that does
+  /// not vary across overloads. Empty for varying types.
+  std::string FixedType;
+
+  /// Element type name for TK_VaryingShape types (e.g. "bool" for
+  /// VaryingShape<BoolTy>). Empty for other type kinds.
+  StringRef ShapeElemType;
+
+  /// Explicit parameter name (e.g. "eta"). Empty to use the default "p0",
+  /// "p1", ... naming. Only meaningful for argument types.
+  StringRef Name;
+
+  /// Construct a TypeInfo from a TableGen record.
+  static TypeInfo resolve(const Record *Rec) {
+    TypeInfo TI;
+    if (Rec->getName() == "VoidTy") {
+      TI.Kind = TK_Void;
+    } else if (Rec->getName() == "Varying") {
+      TI.Kind = TK_Varying;
+    } else if (Rec->getName() == "VaryingElemType") {
+      TI.Kind = TK_ElemType;
+    } else if (Rec->isSubClassOf("VaryingShape")) {
+      TI.Kind = TK_VaryingShape;
+      TI.ShapeElemType =
+          Rec->getValueAsDef("ElementType")->getValueAsString("Name");
+    } else if (Rec->isSubClassOf("VectorType") ||
+               Rec->isSubClassOf("HLSLType")) {
+      TI.Kind = TK_FixedType;
+      TI.FixedType = getFixedTypeName(Rec);
+    } else {
+      llvm_unreachable("unhandled record for type resolution");
+    }
+    return TI;
+  }
+
+  /// Resolve this type to a concrete type name string.
+  /// \p ElemType is the scalar element type for the current overload.
+  /// \p FormatVarying formats a scalar element type into the shaped type name.
+  std::string
+  toTypeString(StringRef ElemType,
+               function_ref<std::string(StringRef)> FormatVarying) const {
+    switch (Kind) {
+    case TK_Void:
+      return "void";
+    case TK_Varying:
+      return FormatVarying(ElemType);
+    case TK_ElemType:
+      return ElemType.str();
+    case TK_VaryingShape:
+      return FormatVarying(ShapeElemType);
+    case TK_FixedType:
+      assert(!FixedType.empty() && "TK_FixedType requires non-empty 
FixedType");
+      return FixedType;
+    }
+    llvm_unreachable("unhandled TypeKindEnum");
+  }
+};
+
+//===----------------------------------------------------------------------===//
+// Availability helpers
+//===----------------------------------------------------------------------===//
+
+static void emitAvailability(raw_ostream &OS, StringRef Version,
+                             bool Use16Bit = false) {
+  if (Use16Bit) {
+    OS << "_HLSL_16BIT_AVAILABILITY(shadermodel, " << Version << ")\n";
+  } else {
+    OS << "_HLSL_AVAILABILITY(shadermodel, " << Version << ")\n";
+  }
+}
+static std::string getVersionString(const Record *SM) {
+  unsigned Major = SM->getValueAsInt("Major");
+  unsigned Minor = SM->getValueAsInt("Minor");
+  if (Major == 0 && Minor == 0)
+    return "";
+  return (Twine(Major) + "." + Twine(Minor)).str();
+}
+
+//===----------------------------------------------------------------------===//
+// Type work item — describes one element type to emit overloads for
+//===----------------------------------------------------------------------===//
+
+/// A single entry in the worklist of types to process for an intrinsic.
+struct TypeWorkItem {
+  /// Element type name (e.g. "half", "float"). Empty for fixed-arg-only
+  /// intrinsics with no type expansion.
+  StringRef ElemType;
+
+  /// Version string for the availability attribute (e.g. "6.2"). Empty if
+  /// no availability annotation is needed.
+  StringRef Availability;
+
+  /// If true, emit _HLSL_16BIT_AVAILABILITY instead of _HLSL_AVAILABILITY.
+  bool Use16BitAvail = false;
+
+  /// If true, wrap overloads in #ifdef __HLSL_ENABLE_16_BIT / #endif.
+  bool NeedsIfdefGuard = false;
+};
+
+/// Fixed canonical ordering for overload types. Types are grouped as:
+///   0: conditionally-16-bit (half)
+///   1-2: 16-bit integers (int16_t, uint16_t) — ifdef-guarded
+///   3+: regular types (bool, int, uint, int64_t, uint64_t, float, double)
+/// Within each group, signed precedes unsigned, smaller precedes larger,
+/// and integer types precede floating-point types.
+static int getTypeSortPriority(const Record *ET) {
+  return StringSwitch<int>(ET->getValueAsString("Name"))
+      .Case("half", 0)
+      .Case("int16_t", 1)
+      .Case("uint16_t", 2)
+      .Case("bool", 3)
+      .Case("int", 4)
+      .Case("uint", 5)
+      .Case("uint32_t", 6)
+      .Case("int64_t", 7)
+      .Case("uint64_t", 8)
+      .Case("float", 9)
+      .Case("double", 10)
+      .Default(11);
+}
+
+//===----------------------------------------------------------------------===//
+// Overload context — shared state across all overloads of one intrinsic
+//===----------------------------------------------------------------------===//
+
+/// Shared state for emitting all overloads of a single HLSL intrinsic.
+struct OverloadContext {
+  /// Output stream to write generated code to.
+  raw_ostream &OS;
+
+  /// Builtin name for _HLSL_BUILTIN_ALIAS (e.g. "__builtin_hlsl_dot").
+  /// Empty for inline/detail intrinsics.
+  StringRef Builtin;
+
+  /// __detail helper function to call (e.g. "refract_impl").
+  /// Empty for alias and inline-body intrinsics.
+  StringRef DetailFunc;
+
+  /// Literal inline function body (e.g. "return p0;").
+  /// Empty for alias and detail intrinsics.
+  StringRef Body;
+
+  /// The HLSL function name to emit (e.g. "dot", "refract").
+  StringRef FuncName;
+
+  /// Metadata describing the return type and its variation behavior.
+  TypeInfo RetType;
+
+  /// Per-argument metadata describing type and variation behavior.
+  SmallVector<TypeInfo, 4> Args;
+
+  /// Whether to emit the function as constexpr.
+  bool IsConstexpr = false;
+
+  /// Whether to emit the __attribute__((convergent)) annotation.
+  bool IsConvergent = false;
+
+  /// Whether any fixed arg has a 16-bit integer type (e.g. int16_t).
+  bool Uses16BitType = false;
+
+  /// Whether any fixed arg has a conditionally-16-bit type (half).
+  bool UsesConditionally16BitType = false;
+
+  explicit OverloadContext(raw_ostream &OS) : OS(OS) {}
+};
+
+/// Emit a complete function declaration or definition with pre-resolved types.
+static void emitDeclaration(const OverloadContext &Ctx, StringRef RetType,
+                            ArrayRef<std::string> ArgTypes) {
+  raw_ostream &OS = Ctx.OS;
+  bool IsDetail = !Ctx.DetailFunc.empty();
+  bool IsInline = !Ctx.Body.empty();
+  bool HasBody = IsDetail || IsInline;
+
+  bool EmitNames = HasBody || llvm::any_of(Ctx.Args, [](const TypeInfo &A) {
+                     return !A.Name.empty();
+                   });
+
+  auto GetParamName = [&](unsigned I) -> std::string {
+    if (!Ctx.Args[I].Name.empty())
+      return Ctx.Args[I].Name.str();
+    return ("p" + Twine(I)).str();
+  };
+
+  if (!HasBody)
+    OS << "_HLSL_BUILTIN_ALIAS(" << Ctx.Builtin << ")\n";
+  if (Ctx.IsConvergent)
+    OS << "__attribute__((convergent)) ";
+  if (HasBody)
+    OS << (Ctx.IsConstexpr ? "constexpr " : "inline ");
+  OS << RetType << " " << Ctx.FuncName << "(";
+
+  for (unsigned I = 0, N = ArgTypes.size(); I < N; ++I) {
+    if (I > 0)
+      OS << ", ";
+    OS << ArgTypes[I];
+    if (EmitNames)
+      OS << " " << GetParamName(I);
+  }
+
+  if (IsDetail) {
+    OS << ") {\n  return __detail::" << Ctx.DetailFunc << "(";
+    for (unsigned I = 0, N = ArgTypes.size(); I < N; ++I) {
+      if (I > 0)
+        OS << ", ";
+      OS << GetParamName(I);
+    }
+    OS << ");\n}\n";
+  } else if (IsInline) {
+    OS << ") { " << Ctx.Body << " }\n";
+  } else {
+    OS << ");\n";
+  }
+}
+
+/// Emit a single overload declaration by resolving all types through
+/// \p FormatVarying, which maps element types to their shaped form.
+static void emitOverload(const OverloadContext &Ctx, StringRef ElemType,
+                         function_ref<std::string(StringRef)> FormatVarying) {
+  std::string RetType = Ctx.RetType.toTypeString(ElemType, FormatVarying);
+  SmallVector<std::string> ArgTypes;
+  for (const TypeInfo &TI : Ctx.Args)
+    ArgTypes.push_back(TI.toTypeString(ElemType, FormatVarying));
+  emitDeclaration(Ctx, RetType, ArgTypes);
+}
+
+/// Emit a scalar overload for the given element type.
+static void emitScalarOverload(const OverloadContext &Ctx, StringRef ElemType) 
{
+  emitOverload(Ctx, ElemType, [](StringRef ET) { return ET.str(); });
+}
+
+/// Emit a vector overload for the given element type and vector size.
+static void emitVectorOverload(const OverloadContext &Ctx, StringRef ElemType,
+                               unsigned VecSize) {
+  emitOverload(Ctx, ElemType, [VecSize](StringRef ET) {
+    return getVectorTypeName(ET, VecSize);
+  });
+}
+
+/// Emit a matrix overload for the given element type and matrix dimensions.
+static void emitMatrixOverload(const OverloadContext &Ctx, StringRef ElemType,
+                               unsigned Rows, unsigned Cols) {
+  emitOverload(Ctx, ElemType, [Rows, Cols](StringRef ET) {
+    return getMatrixTypeName(ET, Rows, Cols);
+  });
+}
+
+//===----------------------------------------------------------------------===//
+// Main emission logic
+//===----------------------------------------------------------------------===//
+
+/// Build an OverloadContext from an HLSLBuiltin record.
+static void buildOverloadContext(const Record *R, OverloadContext &Ctx) {
+  Ctx.Builtin = R->getValueAsString("Builtin");
+  Ctx.DetailFunc = R->getValueAsString("DetailFunc");
+  Ctx.Body = R->getValueAsString("Body");
+  Ctx.FuncName = R->getValueAsString("Name");
+  Ctx.IsConstexpr = R->getValueAsBit("IsConstexpr");
+  Ctx.IsConvergent = R->getValueAsBit("IsConvergent");
+
+  // Note use of 16-bit fixed types in the overload context.
+  auto Update16BitFlags = [&Ctx](const Record *Rec) {
+    const Record *ElemTy = getElementTypeRecord(Rec);
+    Ctx.Uses16BitType |= ElemTy->getValueAsBit("Is16Bit");
+    Ctx.UsesConditionally16BitType |=
+        ElemTy->getValueAsBit("IsConditionally16Bit");
+  };
+
+  // Resolve return and argument types.
+  const Record *RetRec = R->getValueAsDef("ReturnType");
+  Ctx.RetType = TypeInfo::resolve(RetRec);
+  if (Ctx.RetType.Kind == TK_FixedType)
+    Update16BitFlags(RetRec);
+
+  std::vector<const Record *> ArgRecords = R->getValueAsListOfDefs("Args");
+  std::vector<StringRef> ParamNames = R->getValueAsListOfStrings("ParamNames");
+
+  for (const auto &[I, Arg] : llvm::enumerate(ArgRecords)) {
+    TypeInfo TI = TypeInfo::resolve(Arg);
+    if (I < ParamNames.size())
+      TI.Name = ParamNames[I];
+    if (TI.Kind == TK_FixedType)
+      Update16BitFlags(Arg);
+    Ctx.Args.push_back(TI);
+  }
+}
+
+/// Build the worklist of element types to emit overloads for, sorted in
+/// canonical order (see getTypeSortPriority).
+static void buildWorklist(const Record *R, SmallVectorImpl<TypeWorkItem> 
&Worklist,
+                   const OverloadContext &Ctx) {
+  const Record *AvailRec = R->getValueAsDef("Availability");
+  std::string Availability = getVersionString(AvailRec);
+  bool AvailabilityIsAtLeastSM6_2 = AvailRec->getValueAsInt("Major") > 6 ||
+                                    (AvailRec->getValueAsInt("Major") == 6 &&
+                                     AvailRec->getValueAsInt("Minor") >= 2);
+
+  std::vector<const Record *> VaryingTypeRecords =
+      R->getValueAsListOfDefs("VaryingTypes");
+
+  // Populate the availability and guard fields of a TypeWorkItem based on
+  // whether the type is 16-bit, conditionally 16-bit, or a regular type.
+  auto SetAvailability = [&](TypeWorkItem &Item, bool Is16Bit,
+                             bool IsCond16Bit) {
+    Item.NeedsIfdefGuard = Is16Bit;
+    if (Is16Bit || IsCond16Bit) {
+      if (AvailabilityIsAtLeastSM6_2) {
+        Item.Availability = Availability;
+      } else {
+        Item.Availability = SM6_2;
+        Item.Use16BitAvail = IsCond16Bit;
+
+        // Note: If Availability = x where x < 6.2 and a half type is used,
+        // neither _HLSL_AVAILABILITY(shadermodel, x) nor
+        // _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) are correct:
+        //
+        //   _HLSL_AVAILABILITY(shadermodel, x) will set the availbility for 
the
+        //   half overload to x even when 16-bit types are enabled, but x < 6.2
+        //   and 6.2 is required for 16-bit half.
+        //
+        //   _HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) will set the
+        //   availability for the half overload to 6.2 when 16-bit types are
+        //   enabled, but there will be no availability set when 16-bit types
+        //   are not enabled.
+        //
+        // A possible solution to this is to make _HLSL_16BIT_AVAILABILITY
+        // accept 3 args: (shadermodel, X, Y) where X is the availability for
+        // the 16-bit half type overload (which will typically be 6.2), and Y 
is
+        // the availability for the non-16-bit half overload. However, this
+        // sitation does not currently arise, so we just assert below that this
+        // case will never occur.
+        assert(
+            !(IsCond16Bit && !Availability.empty()) &&
+            "Can not handle availability for an intrinsic using half types and"
+            " which has an explicit shader model requirement older than 6.2");
+      }
+    } else {
+      Item.Availability = Availability;
+    }
+  };
+
+  // If no Varying types are specified, just add a single work item.
+  // This is for HLSLBuiltin records that don't use Varying types.
+  if (VaryingTypeRecords.empty()) {
+    TypeWorkItem Item;
+    SetAvailability(Item, Ctx.Uses16BitType, Ctx.UsesConditionally16BitType);
+    Worklist.push_back(Item);
+    return;
+  }
+
+  // Sort Varying types so that overloads are always emitted in canonical 
order.
+  llvm::sort(VaryingTypeRecords, [](const Record *A, const Record *B) {
+    return getTypeSortPriority(A) < getTypeSortPriority(B);
+  });
+
+  // Add a work item for each Varying element type.
+  for (size_t I = 0, N = VaryingTypeRecords.size(); I < N; ++I) {
+    const Record *ElemTy = VaryingTypeRecords[I];
+
+    TypeWorkItem Item;
+    Item.ElemType = ElemTy->getValueAsString("Name");
+    bool Is16Bit = Ctx.Uses16BitType || ElemTy->getValueAsBit("Is16Bit");
+    bool IsCond16Bit = Ctx.UsesConditionally16BitType ||
+                       ElemTy->getValueAsBit("IsConditionally16Bit");
+    SetAvailability(Item, Is16Bit, IsCond16Bit);
+
+    Worklist.push_back(Item);
+  }
+}
+
+/// Emit a Doxygen documentation comment from the Doc field.
+void emitDocComment(raw_ostream &OS, const Record *R) {
+  StringRef Doc = R->getValueAsString("Doc");
+  if (Doc.empty())
+    return;
+  Doc = Doc.trim();
+  SmallVector<StringRef> DocLines;
+  Doc.split(DocLines, '\n');
+  for (StringRef Line : DocLines) {
+    if (Line.empty())
+      OS << "///\n";
+    else
+      OS << "/// " << Line << "\n";
+  }
+}
+
+/// Process the worklist: emit all shape variants for each type with
+/// availability annotations and #ifdef guards.
+static void emitWorklistOverloads(raw_ostream &OS, const OverloadContext &Ctx,
+                           ArrayRef<TypeWorkItem> Worklist,
+                           bool EmitScalarOverload,
+                           ArrayRef<int64_t> VectorSizes,
+                           ArrayRef<const Record *> MatrixDimensions) {
+  bool InIfdef = false;
+  for (const TypeWorkItem &Item : Worklist) {
+    if (Item.NeedsIfdefGuard && !InIfdef) {
+      OS << "#ifdef __HLSL_ENABLE_16_BIT\n";
+      InIfdef = true;
+    }
+
+    auto EmitAvail = [&]() {
+      if (!Item.Availability.empty())
+        emitAvailability(OS, Item.Availability, Item.Use16BitAvail);
+    };
+
+    if (EmitScalarOverload) {
+      EmitAvail();
+      emitScalarOverload(Ctx, Item.ElemType);
+    }
+    for (int64_t N : VectorSizes) {
+      EmitAvail();
+      emitVectorOverload(Ctx, Item.ElemType, N);
+    }
+    for (const Record *MD : MatrixDimensions) {
+      EmitAvail();
+      emitMatrixOverload(Ctx, Item.ElemType, MD->getValueAsInt("Rows"),
+                         MD->getValueAsInt("Cols"));
+    }
+
+    if (InIfdef) {
+      bool NextIsUnguarded =
+          (&Item == &Worklist.back()) || !(&Item + 1)->NeedsIfdefGuard;
+      if (NextIsUnguarded) {
+        OS << "#endif\n";
+        InIfdef = false;
+      }
+    }
+
+    OS << "\n";
+  }
+}
+
+/// Emit all overloads for a single HLSLBuiltin record.
+static void emitBuiltinOverloads(raw_ostream &OS, const Record *R) {
+  OverloadContext Ctx(OS);
+  buildOverloadContext(R, Ctx);
+
+  SmallVector<TypeWorkItem> Worklist;
+  buildWorklist(R, Worklist, Ctx);
+
+  emitDocComment(OS, R);
+  OS << "// " << Ctx.FuncName << " overloads\n";
+
+  // Emit a scalar overload if a scalar Varying overload was requested.
+  // If no Varying types are used at all, emit a scalar overload to handle
+  // emitting a single overload for fixed-typed args or arg-less functions.
+  bool EmitScalarOverload = R->getValueAsBit("VaryingScalar") ||
+                            R->getValueAsListOfDefs("VaryingTypes").empty();
+
+  std::vector<int64_t> VectorSizes = 
R->getValueAsListOfInts("VaryingVecSizes");
+  std::vector<const Record *> MatrixDimensions =
+      R->getValueAsListOfDefs("VaryingMatDims");
+
+  // Sort vector sizes and matrix dimensions for consistent output order.
+  llvm::sort(VectorSizes);
+  llvm::sort(MatrixDimensions, [](const Record *A, const Record *B) {
+    int RowA = A->getValueAsInt("Rows"), RowB = B->getValueAsInt("Rows");
+    if (RowA != RowB)
+      return RowA < RowB;
+    return A->getValueAsInt("Cols") < B->getValueAsInt("Cols");
+  });
+
+  emitWorklistOverloads(OS, Ctx, Worklist, EmitScalarOverload, VectorSizes,
+                        MatrixDimensions);
+}
+/// Emit alias overloads for a single HLSLBuiltin record.
+/// Skips records that have inline bodies (DetailFunc or Body).
+static void emitAliasBuiltin(raw_ostream &OS, const Record *R) {
+  if (!R->getValueAsString("DetailFunc").empty() ||
+      !R->getValueAsString("Body").empty())
+    return;
+  emitBuiltinOverloads(OS, R);
+}
+
+/// Emit inline overloads for a single HLSLBuiltin record.
+/// Skips records that are pure alias declarations.
+static void emitInlineBuiltin(raw_ostream &OS, const Record *R) {
+  if (R->getValueAsString("DetailFunc").empty() &&
+      R->getValueAsString("Body").empty())
+    return;
+  emitBuiltinOverloads(OS, R);
+}
+
+} // anonymous namespace
+
+namespace clang {
+
+void EmitHLSLAliasIntrinsics(const RecordKeeper &Records, raw_ostream &OS) {
+  OS << "// This file is auto-generated by clang-tblgen from "
+        "HLSLIntrinsics.td.\n";
+  OS << "// Do not edit this file directly.\n\n";
+
+  for (const Record *R : Records.getAllDerivedDefinitions("HLSLBuiltin"))
+    emitAliasBuiltin(OS, R);
+}
+
+void EmitHLSLInlineIntrinsics(const RecordKeeper &Records, raw_ostream &OS) {
+  OS << "// This file is auto-generated by clang-tblgen from "
+        "HLSLIntrinsics.td.\n";
+  OS << "// Do not edit this file directly.\n\n";
+
+  for (const Record *R : Records.getAllDerivedDefinitions("HLSLBuiltin"))
+    emitInlineBuiltin(OS, R);
+}
+
+} // namespace clang
diff --git a/clang/utils/TableGen/TableGen.cpp 
b/clang/utils/TableGen/TableGen.cpp
index bd8573dcb940f..0ce9d8306ae16 100644
--- a/clang/utils/TableGen/TableGen.cpp
+++ b/clang/utils/TableGen/TableGen.cpp
@@ -118,6 +118,8 @@ enum ActionType {
   GenRISCVAndesVectorBuiltins,
   GenRISCVAndesVectorBuiltinCG,
   GenRISCVAndesVectorBuiltinSema,
+  GenHLSLAliasIntrinsics,
+  GenHLSLInlineIntrinsics,
   GenAttrDocs,
   GenBuiltinDocs,
   GenDiagDocs,
@@ -346,6 +348,12 @@ cl::opt<ActionType> Action(
         clEnumValN(GenRISCVAndesVectorBuiltinSema,
                    "gen-riscv-andes-vector-builtin-sema",
                    "Generate riscv_andes_vector_builtin_sema.inc for clang"),
+        clEnumValN(GenHLSLAliasIntrinsics, "gen-hlsl-alias-intrinsics",
+                   "Generate HLSL alias intrinsic overloads for "
+                   "hlsl_alias_intrinsics.h"),
+        clEnumValN(GenHLSLInlineIntrinsics, "gen-hlsl-inline-intrinsics",
+                   "Generate HLSL inline intrinsic overloads for "
+                   "hlsl_intrinsics.h"),
         clEnumValN(GenAttrDocs, "gen-attr-docs",
                    "Generate attribute documentation"),
         clEnumValN(GenBuiltinDocs, "gen-builtin-docs",
@@ -654,6 +662,12 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper 
&Records) {
   case GenRISCVAndesVectorBuiltinSema:
     EmitRVVBuiltinSema(Records, OS);
     break;
+  case GenHLSLAliasIntrinsics:
+    EmitHLSLAliasIntrinsics(Records, OS);
+    break;
+  case GenHLSLInlineIntrinsics:
+    EmitHLSLInlineIntrinsics(Records, OS);
+    break;
   case GenAttrDocs:
     EmitClangAttrDocs(Records, OS);
     break;
diff --git a/clang/utils/TableGen/TableGenBackends.h 
b/clang/utils/TableGen/TableGenBackends.h
index 98dc9f4611917..f9bd7ccf9d0d8 100644
--- a/clang/utils/TableGen/TableGenBackends.h
+++ b/clang/utils/TableGen/TableGenBackends.h
@@ -191,6 +191,11 @@ void EmitCdeBuiltinCG(const llvm::RecordKeeper &Records, 
llvm::raw_ostream &OS);
 void EmitCdeBuiltinAliases(const llvm::RecordKeeper &Records,
                            llvm::raw_ostream &OS);
 
+void EmitHLSLAliasIntrinsics(const llvm::RecordKeeper &Records,
+                             llvm::raw_ostream &OS);
+void EmitHLSLInlineIntrinsics(const llvm::RecordKeeper &Records,
+                              llvm::raw_ostream &OS);
+
 void EmitClangAttrDocs(const llvm::RecordKeeper &Records,
                        llvm::raw_ostream &OS);
 void EmitClangDiagDocs(const llvm::RecordKeeper &Records,

>From d55f823a21e0cfe01607da20749068170dc14ebf Mon Sep 17 00:00:00 2001
From: Deric Cheung <[email protected]>
Date: Thu, 19 Mar 2026 16:47:52 -0700
Subject: [PATCH 2/2] Apply clang-format

---
 clang/utils/TableGen/HLSLEmitter.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/clang/utils/TableGen/HLSLEmitter.cpp 
b/clang/utils/TableGen/HLSLEmitter.cpp
index 6505f0402a709..6c15ca96f67c2 100644
--- a/clang/utils/TableGen/HLSLEmitter.cpp
+++ b/clang/utils/TableGen/HLSLEmitter.cpp
@@ -366,8 +366,9 @@ static void buildOverloadContext(const Record *R, 
OverloadContext &Ctx) {
 
 /// Build the worklist of element types to emit overloads for, sorted in
 /// canonical order (see getTypeSortPriority).
-static void buildWorklist(const Record *R, SmallVectorImpl<TypeWorkItem> 
&Worklist,
-                   const OverloadContext &Ctx) {
+static void buildWorklist(const Record *R,
+                          SmallVectorImpl<TypeWorkItem> &Worklist,
+                          const OverloadContext &Ctx) {
   const Record *AvailRec = R->getValueAsDef("Availability");
   std::string Availability = getVersionString(AvailRec);
   bool AvailabilityIsAtLeastSM6_2 = AvailRec->getValueAsInt("Major") > 6 ||
@@ -466,10 +467,10 @@ void emitDocComment(raw_ostream &OS, const Record *R) {
 /// Process the worklist: emit all shape variants for each type with
 /// availability annotations and #ifdef guards.
 static void emitWorklistOverloads(raw_ostream &OS, const OverloadContext &Ctx,
-                           ArrayRef<TypeWorkItem> Worklist,
-                           bool EmitScalarOverload,
-                           ArrayRef<int64_t> VectorSizes,
-                           ArrayRef<const Record *> MatrixDimensions) {
+                                  ArrayRef<TypeWorkItem> Worklist,
+                                  bool EmitScalarOverload,
+                                  ArrayRef<int64_t> VectorSizes,
+                                  ArrayRef<const Record *> MatrixDimensions) {
   bool InIfdef = false;
   for (const TypeWorkItem &Item : Worklist) {
     if (Item.NeedsIfdefGuard && !InIfdef) {

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to