[clang] [HLSL] Adds matrix support for isnan() and isinf(). (PR #195586)

Dan Brown via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 3 16:57:04 PDT 2026


https://github.com/danbrown-amd updated https://github.com/llvm/llvm-project/pull/195586

>From cca0475d1b8e6deb7ebcdbbd68b456fb28cecb80 Mon Sep 17 00:00:00 2001
From: Dan Brown <danbrown at amd.com>
Date: Sun, 3 May 2026 23:01:34 -0600
Subject: [PATCH 1/5] [HLSL] Adds matrix support for isnan() and isinf().
 Addresses #184483 and #184505.

Assisted-by: Claude Sonnet 4
---
 clang/include/clang/Basic/Builtins.td         |   4 +-
 clang/include/clang/Basic/HLSLIntrinsics.td   |   2 -
 clang/lib/CodeGen/CGExpr.cpp                  |   3 +
 clang/lib/CodeGen/CGHLSLBuiltins.cpp          |  20 +-
 .../lib/Headers/hlsl/hlsl_compat_overloads.h  |  64 ++++++
 clang/lib/Sema/SemaChecking.cpp               |   3 +-
 clang/lib/Sema/SemaHLSL.cpp                   |   9 +-
 .../builtins/isinf-overloads_mat.hlsl         |  88 +++++++++
 .../test/CodeGenHLSL/builtins/isinf_mat.hlsl  | 183 ++++++++++++++++++
 .../CodeGenHLSL/builtins/isnan-overloads.hlsl |  31 ++-
 .../builtins/isnan-overloads_mat.hlsl         |  88 +++++++++
 clang/test/CodeGenHLSL/builtins/isnan.hlsl    | 161 +++++++++++++++
 .../test/CodeGenHLSL/builtins/isnan_mat.hlsl  | 183 ++++++++++++++++++
 .../test/SemaHLSL/BuiltIns/isinf-errors.hlsl  |  11 --
 .../SemaHLSL/BuiltIns/isinf-errors_mat.hlsl   |   6 +
 .../test/SemaHLSL/BuiltIns/isnan-errors.hlsl  |  11 --
 .../SemaHLSL/BuiltIns/isnan-errors_mat.hlsl   |   6 +
 17 files changed, 829 insertions(+), 44 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/builtins/isinf-overloads_mat.hlsl
 create mode 100644 clang/test/CodeGenHLSL/builtins/isinf_mat.hlsl
 create mode 100644 clang/test/CodeGenHLSL/builtins/isnan-overloads_mat.hlsl
 create mode 100644 clang/test/CodeGenHLSL/builtins/isnan_mat.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/isinf-errors_mat.hlsl
 create mode 100644 clang/test/SemaHLSL/BuiltIns/isnan-errors_mat.hlsl

diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td
index 8d2a824ef5610..87b08a64c2418 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5594,13 +5594,13 @@ def HLSLFrac : LangBuiltin<"HLSL_LANG"> {
 
 def HLSLIsinf : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_isinf"];
-  let Attributes = [NoThrow, Const];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
   let Prototype = "void(...)";
 }
 
 def HLSLIsnan : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_elementwise_isnan"];
-  let Attributes = [NoThrow, Const];
+  let Attributes = [NoThrow, Const, CustomTypeChecking];
   let Prototype = "void(...)";
 }
 
diff --git a/clang/include/clang/Basic/HLSLIntrinsics.td b/clang/include/clang/Basic/HLSLIntrinsics.td
index 6084a6f92180e..96c65ea807293 100644
--- a/clang/include/clang/Basic/HLSLIntrinsics.td
+++ b/clang/include/clang/Basic/HLSLIntrinsics.td
@@ -1085,7 +1085,6 @@ to True if the x parameter is +INF or -INF. Otherwise, False.
 }];
   let ReturnType = VaryingShape<BoolTy>;
   let VaryingTypes = [HalfTy, FloatTy];
-  let VaryingMatDims = [];
 }
 
 // Determines if the specified value x is Not a Number.
@@ -1100,7 +1099,6 @@ to True if the x parameter is NaN or QNaN. Otherwise, False.
 }];
   let ReturnType = VaryingShape<BoolTy>;
   let VaryingTypes = [HalfTy, FloatTy];
-  let VaryingMatDims = [];
 }
 
 // Returns the result of multiplying the specified value by two raised
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 325902f2127bc..a9ff1aaab0376 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -2292,6 +2292,9 @@ llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
   }
 
   llvm::Type *ResTy = ConvertType(Ty);
+  if (Ty->isConstantMatrixBoolType())
+    return Builder.CreateTrunc(Value, ResTy, "loadedv");
+
   bool HasBoolRep = Ty->hasBooleanRepresentation() || Ty->isExtVectorBoolType();
   if (HasBoolRep && CGM.getCodeGenOpts().isConvertingBoolWithCmp0()) {
     return Builder.CreateICmpNE(
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index bf599e2d77aa8..55e3690535d85 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -1140,9 +1140,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     llvm::Type *Xty = Op0->getType();
     llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext());
     if (Xty->isVectorTy()) {
-      auto *XVecTy = E->getArg(0)->getType()->castAs<VectorType>();
-      retType = llvm::VectorType::get(
-          retType, ElementCount::getFixed(XVecTy->getNumElements()));
+      unsigned NumElts;
+      if (auto *MatTy = E->getArg(0)->getType()->getAs<ConstantMatrixType>())
+        NumElts = MatTy->getNumRows() * MatTy->getNumColumns();
+      else
+        NumElts =
+            E->getArg(0)->getType()->castAs<VectorType>()->getNumElements();
+      retType = llvm::VectorType::get(retType, ElementCount::getFixed(NumElts));
     }
     if (!E->getArg(0)->getType()->hasFloatingRepresentation())
       llvm_unreachable("isinf operand must have a float representation");
@@ -1155,9 +1159,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     llvm::Type *Xty = Op0->getType();
     llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext());
     if (Xty->isVectorTy()) {
-      auto *XVecTy = E->getArg(0)->getType()->castAs<VectorType>();
-      retType = llvm::VectorType::get(
-          retType, ElementCount::getFixed(XVecTy->getNumElements()));
+      unsigned NumElts;
+      if (auto *MatTy = E->getArg(0)->getType()->getAs<ConstantMatrixType>())
+        NumElts = MatTy->getNumRows() * MatTy->getNumColumns();
+      else
+        NumElts =
+            E->getArg(0)->getType()->castAs<VectorType>()->getNumElements();
+      retType = llvm::VectorType::get(retType, ElementCount::getFixed(NumElts));
     }
     if (!E->getArg(0)->getType()->hasFloatingRepresentation())
       llvm_unreachable("isnan operand must have a float representation");
diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index d97039128ea85..4d00b34b32ca0 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -390,15 +390,79 @@ _DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool3 isinf(double3 V) { return isinf((float3)V); }
 _DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool4 isinf(double4 V) { return isinf((float4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x2 isinf(double1x2 V) { return isinf((float1x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x3 isinf(double1x3 V) { return isinf((float1x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x4 isinf(double1x4 V) { return isinf((float1x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x1 isinf(double2x1 V) { return isinf((float2x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x2 isinf(double2x2 V) { return isinf((float2x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x3 isinf(double2x3 V) { return isinf((float2x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x4 isinf(double2x4 V) { return isinf((float2x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x1 isinf(double3x1 V) { return isinf((float3x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x2 isinf(double3x2 V) { return isinf((float3x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x3 isinf(double3x3 V) { return isinf((float3x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x4 isinf(double3x4 V) { return isinf((float3x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x1 isinf(double4x1 V) { return isinf((float4x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x2 isinf(double4x2 V) { return isinf((float4x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x3 isinf(double4x3 V) { return isinf((float4x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x4 isinf(double4x4 V) { return isinf((float4x4)V); }
 
 //===----------------------------------------------------------------------===//
 // isnan builtins overloads
 //===----------------------------------------------------------------------===//
 
+_DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool isnan(double V) { return isnan((float)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool2 isnan(double2 V) { return isnan((float2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool3 isnan(double3 V) { return isnan((float3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
 constexpr bool4 isnan(double4 V) { return isnan((float4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x2 isnan(double1x2 V) { return isnan((float1x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x3 isnan(double1x3 V) { return isnan((float1x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool1x4 isnan(double1x4 V) { return isnan((float1x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x1 isnan(double2x1 V) { return isnan((float2x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x2 isnan(double2x2 V) { return isnan((float2x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x3 isnan(double2x3 V) { return isnan((float2x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool2x4 isnan(double2x4 V) { return isnan((float2x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x1 isnan(double3x1 V) { return isnan((float3x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x2 isnan(double3x2 V) { return isnan((float3x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x3 isnan(double3x3 V) { return isnan((float3x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool3x4 isnan(double3x4 V) { return isnan((float3x4)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x1 isnan(double4x1 V) { return isnan((float4x1)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x2 isnan(double4x2 V) { return isnan((float4x2)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x3 isnan(double4x3 V) { return isnan((float4x3)V); }
+_DXC_DEPRECATED_64BIT_FN(fn)
+constexpr bool4x4 isnan(double4x4 V) { return isnan((float4x4)V); }
 
 //===----------------------------------------------------------------------===//
 // lerp builtins overloads
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8a8c9cc9d2c23..193112306db13 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2200,7 +2200,8 @@ checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy,
 
   switch (ArgTyRestr) {
   case Sema::EltwiseBuiltinArgTyRestriction::None:
-    if (!ArgTy->getAs<VectorType>() && !isValidMathElementType(ArgTy)) {
+    if (!ArgTy->getAs<VectorType>() && !ArgTy->getAs<MatrixType>() &&
+        !isValidMathElementType(ArgTy)) {
       return S.Diag(Loc, diag::err_builtin_invalid_arg_type)
              << ArgOrdinal << /* vector */ 2 << /* integer */ 1 << /* fp */ 1
              << ArgTy;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 04148fcd008d5..ab820883904f0 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3282,6 +3282,8 @@ static bool CheckFloatRepresentation(Sema *S, SourceLocation Loc,
   clang::QualType BaseType =
       PassedType->isVectorType()
           ? PassedType->castAs<clang::VectorType>()->getElementType()
+      : PassedType->getAs<clang::ConstantMatrixType>()
+          ? PassedType->castAs<clang::ConstantMatrixType>()->getElementType()
           : PassedType;
   if (!BaseType->isFloat32Type())
     return S->Diag(Loc, diag::err_builtin_invalid_arg_type)
@@ -3402,10 +3404,13 @@ static bool CheckExpectedBitWidth(Sema *S, CallExpr *TheCall,
 
 static void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall,
                                        QualType ReturnType) {
-  auto *VecTyA = TheCall->getArg(0)->getType()->getAs<VectorType>();
-  if (VecTyA)
+  if (auto *VecTyA = TheCall->getArg(0)->getType()->getAs<VectorType>())
     ReturnType =
         S->Context.getExtVectorType(ReturnType, VecTyA->getNumElements());
+  else if (auto *MatTyA =
+               TheCall->getArg(0)->getType()->getAs<ConstantMatrixType>())
+    ReturnType = S->Context.getConstantMatrixType(
+        ReturnType, MatTyA->getNumRows(), MatTyA->getNumColumns());
 
   TheCall->setType(ReturnType);
 }
diff --git a/clang/test/CodeGenHLSL/builtins/isinf-overloads_mat.hlsl b/clang/test/CodeGenHLSL/builtins/isinf-overloads_mat.hlsl
new file mode 100644
index 0000000000000..2a00eab249ed1
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/isinf-overloads_mat.hlsl
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden noundef" -DTARGET=dx
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden spir_func noundef" -DTARGET=spv
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
+// RUN:   -verify -verify-ignore-unexpected=note
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s \
+// RUN:   -verify -verify-ignore-unexpected=note
+
+// CHECK: define [[FNATTRS]] <2 x i1> @
+// CHECK: %hlsl.isinf = call <2 x i1> @llvm.[[TARGET]].isinf.v2f32
+// CHECK: ret <2 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x2 test_isinf_double1x2(double1x2 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <3 x i1> @
+// CHECK: %hlsl.isinf = call <3 x i1> @llvm.[[TARGET]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x3 test_isinf_double1x3(double1x3 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[TARGET]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x4 test_isinf_double1x4(double1x4 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <2 x i1> @
+// CHECK: %hlsl.isinf = call <2 x i1> @llvm.[[TARGET]].isinf.v2f32
+// CHECK: ret <2 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x1 test_isinf_double2x1(double2x1 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[TARGET]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x2 test_isinf_double2x2(double2x2 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <6 x i1> @
+// CHECK: %hlsl.isinf = call <6 x i1> @llvm.[[TARGET]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x3 test_isinf_double2x3(double2x3 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <8 x i1> @
+// CHECK: %hlsl.isinf = call <8 x i1> @llvm.[[TARGET]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x4 test_isinf_double2x4(double2x4 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <3 x i1> @
+// CHECK: %hlsl.isinf = call <3 x i1> @llvm.[[TARGET]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x1 test_isinf_double3x1(double3x1 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <6 x i1> @
+// CHECK: %hlsl.isinf = call <6 x i1> @llvm.[[TARGET]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x2 test_isinf_double3x2(double3x2 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <9 x i1> @
+// CHECK: %hlsl.isinf = call <9 x i1> @llvm.[[TARGET]].isinf.v9f32
+// CHECK: ret <9 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x3 test_isinf_double3x3(double3x3 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <12 x i1> @
+// CHECK: %hlsl.isinf = call <12 x i1> @llvm.[[TARGET]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x4 test_isinf_double3x4(double3x4 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[TARGET]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x1 test_isinf_double4x1(double4x1 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <8 x i1> @
+// CHECK: %hlsl.isinf = call <8 x i1> @llvm.[[TARGET]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x2 test_isinf_double4x2(double4x2 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <12 x i1> @
+// CHECK: %hlsl.isinf = call <12 x i1> @llvm.[[TARGET]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x3 test_isinf_double4x3(double4x3 p0) { return isinf(p0); }
+// CHECK: define [[FNATTRS]] <16 x i1> @
+// CHECK: %hlsl.isinf = call <16 x i1> @llvm.[[TARGET]].isinf.v16f32
+// CHECK: ret <16 x i1> %hlsl.isinf
+// expected-warning at +1 {{'isinf' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x4 test_isinf_double4x4(double4x4 p0) { return isinf(p0); }
diff --git a/clang/test/CodeGenHLSL/builtins/isinf_mat.hlsl b/clang/test/CodeGenHLSL/builtins/isinf_mat.hlsl
new file mode 100644
index 0000000000000..2d9eea3a8ec04
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/isinf_mat.hlsl
@@ -0,0 +1,183 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN:   --check-prefixes=CHECK,DXCHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK,DXCHECK,NO_HALF
+
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN:   --check-prefixes=CHECK,SPVCHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK,SPVCHECK,NO_HALF
+
+// DXCHECK: define hidden [[FN_TYPE:]]noundef <2 x i1> @
+// SPVCHECK: define hidden [[FN_TYPE:spir_func ]]noundef <2 x i1> @
+// DXCHECK: %hlsl.isinf = call <2 x i1> @llvm.[[ICF:dx]].isinf.v2f32(
+// SPVCHECK: %hlsl.isinf = call <2 x i1> @llvm.[[ICF:spv]].isinf.v2f32(
+// CHECK: ret <2 x i1> %hlsl.isinf
+bool1x2 test_isinf_float1x2(float1x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+bool1x3 test_isinf_float1x3(float1x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool1x4 test_isinf_float1x4(float1x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// CHECK: %hlsl.isinf = call <2 x i1> @llvm.[[ICF]].isinf.v2f32
+// CHECK: ret <2 x i1> %hlsl.isinf
+bool2x1 test_isinf_float2x1(float2x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool2x2 test_isinf_float2x2(float2x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+bool2x3 test_isinf_float2x3(float2x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+bool2x4 test_isinf_float2x4(float2x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+bool3x1 test_isinf_float3x1(float3x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+bool3x2 test_isinf_float3x2(float3x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// CHECK: %hlsl.isinf = call <9 x i1> @llvm.[[ICF]].isinf.v9f32
+// CHECK: ret <9 x i1> %hlsl.isinf
+bool3x3 test_isinf_float3x3(float3x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+bool3x4 test_isinf_float3x4(float3x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool4x1 test_isinf_float4x1(float4x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+bool4x2 test_isinf_float4x2(float4x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+bool4x3 test_isinf_float4x3(float4x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// CHECK: %hlsl.isinf = call <16 x i1> @llvm.[[ICF]].isinf.v16f32
+// CHECK: ret <16 x i1> %hlsl.isinf
+bool4x4 test_isinf_float4x4(float4x4 p0) { return isinf(p0); }
+
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <2 x i1> @llvm.[[ICF]].isinf.v2f16
+// NO_HALF: %hlsl.isinf = call <2 x i1> @llvm.[[ICF]].isinf.v2f32
+// CHECK: ret <2 x i1> %hlsl.isinf
+bool1x2 test_isinf_half1x2(half1x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f16
+// NO_HALF: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+bool1x3 test_isinf_half1x3(half1x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f16
+// NO_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool1x4 test_isinf_half1x4(half1x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <2 x i1> @llvm.[[ICF]].isinf.v2f16
+// NO_HALF: %hlsl.isinf = call <2 x i1> @llvm.[[ICF]].isinf.v2f32
+// CHECK: ret <2 x i1> %hlsl.isinf
+bool2x1 test_isinf_half2x1(half2x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f16
+// NO_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool2x2 test_isinf_half2x2(half2x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f16
+// NO_HALF: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+bool2x3 test_isinf_half2x3(half2x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f16
+// NO_HALF: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+bool2x4 test_isinf_half2x4(half2x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f16
+// NO_HALF: %hlsl.isinf = call <3 x i1> @llvm.[[ICF]].isinf.v3f32
+// CHECK: ret <3 x i1> %hlsl.isinf
+bool3x1 test_isinf_half3x1(half3x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f16
+// NO_HALF: %hlsl.isinf = call <6 x i1> @llvm.[[ICF]].isinf.v6f32
+// CHECK: ret <6 x i1> %hlsl.isinf
+bool3x2 test_isinf_half3x2(half3x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <9 x i1> @llvm.[[ICF]].isinf.v9f16
+// NO_HALF: %hlsl.isinf = call <9 x i1> @llvm.[[ICF]].isinf.v9f32
+// CHECK: ret <9 x i1> %hlsl.isinf
+bool3x3 test_isinf_half3x3(half3x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f16
+// NO_HALF: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+bool3x4 test_isinf_half3x4(half3x4 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f16
+// NO_HALF: %hlsl.isinf = call <4 x i1> @llvm.[[ICF]].isinf.v4f32
+// CHECK: ret <4 x i1> %hlsl.isinf
+bool4x1 test_isinf_half4x1(half4x1 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f16
+// NO_HALF: %hlsl.isinf = call <8 x i1> @llvm.[[ICF]].isinf.v8f32
+// CHECK: ret <8 x i1> %hlsl.isinf
+bool4x2 test_isinf_half4x2(half4x2 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f16
+// NO_HALF: %hlsl.isinf = call <12 x i1> @llvm.[[ICF]].isinf.v12f32
+// CHECK: ret <12 x i1> %hlsl.isinf
+bool4x3 test_isinf_half4x3(half4x3 p0) { return isinf(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// NATIVE_HALF: %hlsl.isinf = call <16 x i1> @llvm.[[ICF]].isinf.v16f16
+// NO_HALF: %hlsl.isinf = call <16 x i1> @llvm.[[ICF]].isinf.v16f32
+// CHECK: ret <16 x i1> %hlsl.isinf
+bool4x4 test_isinf_half4x4(half4x4 p0) { return isinf(p0); }
diff --git a/clang/test/CodeGenHLSL/builtins/isnan-overloads.hlsl b/clang/test/CodeGenHLSL/builtins/isnan-overloads.hlsl
index a0c3eee5da636..8e2a1326e7b1b 100644
--- a/clang/test/CodeGenHLSL/builtins/isnan-overloads.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/isnan-overloads.hlsl
@@ -1,20 +1,33 @@
 // RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
 // RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
-// RUN:   -o - | FileCheck %s
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden noundef" -DTARGET=dx
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden spir_func noundef" -DTARGET=spv
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
+// RUN:   -verify -verify-ignore-unexpected=note
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s \
+// RUN:   -verify -verify-ignore-unexpected=note
 
-// CHECK: define hidden noundef i1 @
-// CHECK: %hlsl.isnan = call i1 @llvm.dx.isnan.f32(
+// CHECK: define [[FNATTRS]] i1 @
+// CHECK: %hlsl.isnan = call i1 @llvm.[[TARGET]].isnan.f32(
 // CHECK: ret i1 %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
 bool test_isnan_double(double p0) { return isnan(p0); }
-// CHECK: define hidden noundef <2 x i1> @
-// CHECK: %hlsl.isnan = call <2 x i1> @llvm.dx.isnan.v2f32
+// CHECK: define [[FNATTRS]] <2 x i1> @
+// CHECK: %hlsl.isnan = call <2 x i1> @llvm.[[TARGET]].isnan.v2f32
 // CHECK: ret <2 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
 bool2 test_isnan_double2(double2 p0) { return isnan(p0); }
-// CHECK: define hidden noundef <3 x i1> @
-// CHECK: %hlsl.isnan = call <3 x i1> @llvm.dx.isnan.v3f32
+// CHECK: define [[FNATTRS]] <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[TARGET]].isnan.v3f32
 // CHECK: ret <3 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
 bool3 test_isnan_double3(double3 p0) { return isnan(p0); }
-// CHECK: define hidden noundef <4 x i1> @
-// CHECK: %hlsl.isnan = call <4 x i1> @llvm.dx.isnan.v4f32
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[TARGET]].isnan.v4f32
 // CHECK: ret <4 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
 bool4 test_isnan_double4(double4 p0) { return isnan(p0); }
diff --git a/clang/test/CodeGenHLSL/builtins/isnan-overloads_mat.hlsl b/clang/test/CodeGenHLSL/builtins/isnan-overloads_mat.hlsl
new file mode 100644
index 0000000000000..234897e456663
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/isnan-overloads_mat.hlsl
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden noundef" -DTARGET=dx
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN:   -Wdeprecated-declarations -o - | FileCheck %s \
+// RUN:   -DFNATTRS="hidden spir_func noundef" -DTARGET=spv
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.3-library %s \
+// RUN:   -verify -verify-ignore-unexpected=note
+// RUN: %clang_cc1 -std=hlsl202x -finclude-default-header -x hlsl -triple spirv-unknown-vulkan-compute %s \
+// RUN:   -verify -verify-ignore-unexpected=note
+
+// CHECK: define [[FNATTRS]] <2 x i1> @
+// CHECK: %hlsl.isnan = call <2 x i1> @llvm.[[TARGET]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x2 test_isnan_double1x2(double1x2 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[TARGET]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x3 test_isnan_double1x3(double1x3 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[TARGET]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool1x4 test_isnan_double1x4(double1x4 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <2 x i1> @
+// CHECK: %hlsl.isnan = call <2 x i1> @llvm.[[TARGET]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x1 test_isnan_double2x1(double2x1 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[TARGET]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x2 test_isnan_double2x2(double2x2 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[TARGET]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x3 test_isnan_double2x3(double2x3 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[TARGET]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool2x4 test_isnan_double2x4(double2x4 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[TARGET]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x1 test_isnan_double3x1(double3x1 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[TARGET]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x2 test_isnan_double3x2(double3x2 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <9 x i1> @
+// CHECK: %hlsl.isnan = call <9 x i1> @llvm.[[TARGET]].isnan.v9f32
+// CHECK: ret <9 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x3 test_isnan_double3x3(double3x3 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[TARGET]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool3x4 test_isnan_double3x4(double3x4 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[TARGET]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x1 test_isnan_double4x1(double4x1 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[TARGET]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x2 test_isnan_double4x2(double4x2 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[TARGET]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x3 test_isnan_double4x3(double4x3 p0) { return isnan(p0); }
+// CHECK: define [[FNATTRS]] <16 x i1> @
+// CHECK: %hlsl.isnan = call <16 x i1> @llvm.[[TARGET]].isnan.v16f32
+// CHECK: ret <16 x i1> %hlsl.isnan
+// expected-warning at +1 {{'isnan' is deprecated: In 202x 64 bit API lowering for fn is deprecated. Explicitly cast parameters to 32 or 16 bit types.}}
+bool4x4 test_isnan_double4x4(double4x4 p0) { return isnan(p0); }
diff --git a/clang/test/CodeGenHLSL/builtins/isnan.hlsl b/clang/test/CodeGenHLSL/builtins/isnan.hlsl
index cca3863557229..f52c508309f25 100644
--- a/clang/test/CodeGenHLSL/builtins/isnan.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/isnan.hlsl
@@ -60,3 +60,164 @@ bool3 test_isnan_float3(float3 p0) { return isnan(p0); }
 // CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
 // CHECK: ret <4 x i1> %hlsl.isnan
 bool4 test_isnan_float4(float4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool1x3 test_isnan_float1x3(float1x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool1x4 test_isnan_float1x4(float1x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// CHECK: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool2x1 test_isnan_float2x1(float2x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool2x2 test_isnan_float2x2(float2x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool2x3 test_isnan_float2x3(float2x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool2x4 test_isnan_float2x4(float2x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool3x1 test_isnan_float3x1(float3x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool3x2 test_isnan_float3x2(float3x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// CHECK: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f32
+// CHECK: ret <9 x i1> %hlsl.isnan
+bool3x3 test_isnan_float3x3(float3x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool3x4 test_isnan_float3x4(float3x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool4x1 test_isnan_float4x1(float4x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool4x2 test_isnan_float4x2(float4x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool4x3 test_isnan_float4x3(float4x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// CHECK: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f32
+// CHECK: ret <16 x i1> %hlsl.isnan
+bool4x4 test_isnan_float4x4(float4x4 p0) { return isnan(p0); }
+
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f16
+// NO_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool1x2 test_isnan_half1x2(half1x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f16
+// NO_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool1x3 test_isnan_half1x3(half1x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool1x4 test_isnan_half1x4(half1x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f16
+// NO_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool2x1 test_isnan_half2x1(half2x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool2x2 test_isnan_half2x2(half2x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f16
+// NO_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool2x3 test_isnan_half2x3(half2x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f16
+// NO_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool2x4 test_isnan_half2x4(half2x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f16
+// NO_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool3x1 test_isnan_half3x1(half3x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f16
+// NO_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool3x2 test_isnan_half3x2(half3x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f16
+// NO_HALF: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f32
+// CHECK: ret <9 x i1> %hlsl.isnan
+bool3x3 test_isnan_half3x3(half3x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f16
+// NO_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool3x4 test_isnan_half3x4(half3x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool4x1 test_isnan_half4x1(half4x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f16
+// NO_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool4x2 test_isnan_half4x2(half4x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f16
+// NO_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool4x3 test_isnan_half4x3(half4x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f16
+// NO_HALF: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f32
+// CHECK: ret <16 x i1> %hlsl.isnan
+bool4x4 test_isnan_half4x4(half4x4 p0) { return isnan(p0); }
diff --git a/clang/test/CodeGenHLSL/builtins/isnan_mat.hlsl b/clang/test/CodeGenHLSL/builtins/isnan_mat.hlsl
new file mode 100644
index 0000000000000..d354e0aed55e5
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/isnan_mat.hlsl
@@ -0,0 +1,183 @@
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -fnative-half-type -fnative-int16-type \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN:   --check-prefixes=CHECK,DXCHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK,DXCHECK,NO_HALF
+
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -fnative-half-type -fnative-int16-type \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s \
+// RUN:   --check-prefixes=CHECK,SPVCHECK,NATIVE_HALF
+// RUN: %clang_cc1 -finclude-default-header -x hlsl -triple \
+// RUN:   spirv-unknown-vulkan-compute %s -emit-llvm -disable-llvm-passes \
+// RUN:   -o - | FileCheck %s --check-prefixes=CHECK,SPVCHECK,NO_HALF
+
+// DXCHECK: define hidden [[FN_TYPE:]]noundef <2 x i1> @
+// SPVCHECK: define hidden [[FN_TYPE:spir_func ]]noundef <2 x i1> @
+// DXCHECK: %hlsl.isnan = call <2 x i1> @llvm.[[ICF:dx]].isnan.v2f32(
+// SPVCHECK: %hlsl.isnan = call <2 x i1> @llvm.[[ICF:spv]].isnan.v2f32(
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool1x2 test_isnan_float1x2(float1x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool1x3 test_isnan_float1x3(float1x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool1x4 test_isnan_float1x4(float1x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// CHECK: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool2x1 test_isnan_float2x1(float2x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool2x2 test_isnan_float2x2(float2x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool2x3 test_isnan_float2x3(float2x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool2x4 test_isnan_float2x4(float2x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// CHECK: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool3x1 test_isnan_float3x1(float3x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// CHECK: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool3x2 test_isnan_float3x2(float3x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// CHECK: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f32
+// CHECK: ret <9 x i1> %hlsl.isnan
+bool3x3 test_isnan_float3x3(float3x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool3x4 test_isnan_float3x4(float3x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// CHECK: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool4x1 test_isnan_float4x1(float4x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// CHECK: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool4x2 test_isnan_float4x2(float4x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// CHECK: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool4x3 test_isnan_float4x3(float4x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// CHECK: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f32
+// CHECK: ret <16 x i1> %hlsl.isnan
+bool4x4 test_isnan_float4x4(float4x4 p0) { return isnan(p0); }
+
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f16
+// NO_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool1x2 test_isnan_half1x2(half1x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f16
+// NO_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool1x3 test_isnan_half1x3(half1x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool1x4 test_isnan_half1x4(half1x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <2 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f16
+// NO_HALF: %hlsl.isnan = call <2 x i1> @llvm.[[ICF]].isnan.v2f32
+// CHECK: ret <2 x i1> %hlsl.isnan
+bool2x1 test_isnan_half2x1(half2x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool2x2 test_isnan_half2x2(half2x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f16
+// NO_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool2x3 test_isnan_half2x3(half2x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f16
+// NO_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool2x4 test_isnan_half2x4(half2x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <3 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f16
+// NO_HALF: %hlsl.isnan = call <3 x i1> @llvm.[[ICF]].isnan.v3f32
+// CHECK: ret <3 x i1> %hlsl.isnan
+bool3x1 test_isnan_half3x1(half3x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <6 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f16
+// NO_HALF: %hlsl.isnan = call <6 x i1> @llvm.[[ICF]].isnan.v6f32
+// CHECK: ret <6 x i1> %hlsl.isnan
+bool3x2 test_isnan_half3x2(half3x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <9 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f16
+// NO_HALF: %hlsl.isnan = call <9 x i1> @llvm.[[ICF]].isnan.v9f32
+// CHECK: ret <9 x i1> %hlsl.isnan
+bool3x3 test_isnan_half3x3(half3x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f16
+// NO_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool3x4 test_isnan_half3x4(half3x4 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <4 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f16
+// NO_HALF: %hlsl.isnan = call <4 x i1> @llvm.[[ICF]].isnan.v4f32
+// CHECK: ret <4 x i1> %hlsl.isnan
+bool4x1 test_isnan_half4x1(half4x1 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <8 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f16
+// NO_HALF: %hlsl.isnan = call <8 x i1> @llvm.[[ICF]].isnan.v8f32
+// CHECK: ret <8 x i1> %hlsl.isnan
+bool4x2 test_isnan_half4x2(half4x2 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <12 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f16
+// NO_HALF: %hlsl.isnan = call <12 x i1> @llvm.[[ICF]].isnan.v12f32
+// CHECK: ret <12 x i1> %hlsl.isnan
+bool4x3 test_isnan_half4x3(half4x3 p0) { return isnan(p0); }
+
+// CHECK: define hidden [[FN_TYPE]]noundef <16 x i1> @
+// NATIVE_HALF: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f16
+// NO_HALF: %hlsl.isnan = call <16 x i1> @llvm.[[ICF]].isnan.v16f32
+// CHECK: ret <16 x i1> %hlsl.isnan
+bool4x4 test_isnan_half4x4(half4x4 p0) { return isnan(p0); }
diff --git a/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl
index a32bc9628a295..7ffc750f2d941 100644
--- a/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl
@@ -25,14 +25,3 @@ bool2 builtin_isinf_int2_to_float2_promotion(int2 p1) {
   return __builtin_hlsl_elementwise_isinf(p1);
   // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'int2' (aka 'vector<int, 2>'))}}
 }
-
-// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion
-half builtin_isinf_half_scalar (half p0) {
-  return __builtin_hlsl_elementwise_isinf (p0);
-  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double')}}
-}
-
-float builtin_isinf_float_scalar ( float p0) {
-  return __builtin_hlsl_elementwise_isinf (p0);
-  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double')}}
-}
diff --git a/clang/test/SemaHLSL/BuiltIns/isinf-errors_mat.hlsl b/clang/test/SemaHLSL/BuiltIns/isinf-errors_mat.hlsl
new file mode 100644
index 0000000000000..70d2a68ca16dd
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/isinf-errors_mat.hlsl
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type -emit-llvm-only -disable-llvm-passes -verify
+
+bool2x2 test_builtin_isinf_double_matrix(double2x2 p0) {
+  return __builtin_hlsl_elementwise_isinf(p0);
+  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double2x2' (aka 'matrix<double, 2, 2>'))}}
+}
diff --git a/clang/test/SemaHLSL/BuiltIns/isnan-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/isnan-errors.hlsl
index 625c415f91de2..1af44ec2dd38f 100644
--- a/clang/test/SemaHLSL/BuiltIns/isnan-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/isnan-errors.hlsl
@@ -25,14 +25,3 @@ bool2 builtin_isnan_int2_to_float2_promotion(int2 p1) {
   return __builtin_hlsl_elementwise_isnan(p1);
   // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'int2' (aka 'vector<int, 2>'))}}
 }
-
-// builtins are variadic functions and so are subject to DefaultVariadicArgumentPromotion
-half builtin_isnan_half_scalar (half p0) {
-  return __builtin_hlsl_elementwise_isnan (p0);
-  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double')}}
-}
-
-float builtin_isnan_float_scalar ( float p0) {
-  return __builtin_hlsl_elementwise_isnan (p0);
-  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double')}}
-}
diff --git a/clang/test/SemaHLSL/BuiltIns/isnan-errors_mat.hlsl b/clang/test/SemaHLSL/BuiltIns/isnan-errors_mat.hlsl
new file mode 100644
index 0000000000000..b8728c78bab22
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/isnan-errors_mat.hlsl
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -fnative-int16-type -emit-llvm-only -disable-llvm-passes -verify
+
+bool2x2 test_builtin_isnan_double_matrix(double2x2 p0) {
+  return __builtin_hlsl_elementwise_isnan(p0);
+  // expected-error at -1 {{1st argument must be a scalar or vector of 16 or 32 bit floating-point types (was 'double2x2' (aka 'matrix<double, 2, 2>'))}}
+}

>From e3cb0e5f46cd5dba79a52bb84b266da1517c8123 Mon Sep 17 00:00:00 2001
From: danbrown-amd <danbrown at amd.com>
Date: Thu, 28 May 2026 16:18:06 -0600
Subject: [PATCH 2/5] [HLSL] Fixes crash on bool matrix single subscript.

VisitMatrixSingleSubscriptExpr used ConvertTypeForMem to determine the element type for the result vector, but Visit(E->getBase()) returns a value in register representation. For bool matrices this causes a type mismatch: the flat matrix value has element type i1 while the result vector is built with element type i32, causing an assertion failure in InsertElementInst ("Invalid insertelement instruction operands!").  Fix by using ConvertType instead of ConvertTypeForMem, so the element type of the result vector matches the register type of the extracted elements. The existing EmitFromMemory call on the result handles any further conversion.

Assisted-by: Claude Sonnet 4
---
 clang/lib/CodeGen/CGExprScalar.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index c8a8ec7b6d928..34fd00431d2ac 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -2241,7 +2241,7 @@ Value *ScalarExprEmitter::VisitMatrixSingleSubscriptExpr(
     MB.CreateIndexAssumption(RowIdx, NumRows);
 
   Value *FlatMatrix = Visit(E->getBase());
-  llvm::Type *ElemTy = CGF.ConvertTypeForMem(MatrixTy->getElementType());
+  llvm::Type *ElemTy = CGF.ConvertType(MatrixTy->getElementType());
   auto *ResultTy = llvm::FixedVectorType::get(ElemTy, NumColumns);
   Value *RowVec = llvm::PoisonValue::get(ResultTy);
 

>From e09bc7a7b13cc53303941f75605ef108cbd46941 Mon Sep 17 00:00:00 2001
From: danbrown-amd <danbrown at amd.com>
Date: Sun, 31 May 2026 21:41:36 -0600
Subject: [PATCH 3/5] Updates tests in accordance with previous commit.

---
 .../MatrixSingleSubscriptGetter.hlsl          | 51 +++++++---------
 .../MatrixToAndFromVectorConstructors.hlsl    | 25 ++++----
 .../BasicFeatures/VectorElementwiseCast.hlsl  | 24 ++++----
 clang/test/CodeGenHLSL/BoolMatrix.hlsl        | 44 ++++----------
 clang/test/CodeGenHLSL/builtins/and_mat.hlsl  | 60 +++++++++----------
 clang/test/CodeGenHLSL/builtins/or.hlsl       | 60 +++++++++----------
 .../test/CodeGenHLSL/builtins/transpose.hlsl  |  5 +-
 7 files changed, 124 insertions(+), 145 deletions(-)

diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
index 07cad8214e284..baac77b2e0fad 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
@@ -4,7 +4,6 @@
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z24getFloatVecMatrixDynamicu11matrix_typeILm4ELm4EfEi(
 // CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x float>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <16 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -32,7 +31,6 @@ float4 getFloatVecMatrixDynamic(float4x4 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z27getFloatScalarMatrixDynamicu11matrix_typeILm2ELm1EfEi(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -52,7 +50,6 @@ float getFloatScalarMatrixDynamic(float2x1 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z28getFloatScalarMatrixConstantu11matrix_typeILm2ELm1EfE(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
@@ -68,7 +65,6 @@ float getFloatScalarMatrixConstant(float2x1 M) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z29getFloatScalarMatrixConstant2u11matrix_typeILm2ELm1EfE(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
@@ -84,7 +80,6 @@ float getFloatScalarMatrixConstant2(float2x1 M) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z19getIntMatrixDynamicu11matrix_typeILm4ELm4EiEi(
 // CHECK-SAME: <16 x i32> noundef [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
@@ -112,7 +107,6 @@ int4 getIntMatrixDynamic(int4x4 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z22AddFloatMatrixConstantu11matrix_typeILm4ELm4EfE(
 // CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x float>], align 4
 // CHECK-NEXT:    store <16 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
@@ -163,7 +157,6 @@ float4 AddFloatMatrixConstant(float4x4 M) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z20AddIntMatrixConstantu11matrix_typeILm4ELm4EiE(
 // CHECK-SAME: <16 x i32> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
@@ -214,7 +207,6 @@ int4 AddIntMatrixConstant(int4x4 M) {
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z23getBoolVecMatrixDynamicu11matrix_typeILm2ELm3EbEi(
 // CHECK-SAME: <6 x i1> noundef [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [3 x <2 x i32>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <6 x i1> [[M]] to <6 x i32>
@@ -222,16 +214,17 @@ int4 AddIntMatrixConstant(int4x4 M) {
 // CHECK-NEXT:    store i32 [[INDEX]], ptr [[INDEX_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[INDEX_ADDR]], align 4
 // CHECK-NEXT:    [[TMP2:%.*]] = load <6 x i32>, ptr [[M_ADDR]], align 4
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <6 x i32> [[TMP2]] to <6 x i1>
 // CHECK-NEXT:    [[TMP3:%.*]] = add i32 0, [[TMP1]]
-// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP3]]
-// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <3 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
+// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <6 x i1> [[TRUNC]], i32 [[TMP3]]
+// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <3 x i1> poison, i1 [[MATRIX_ELEM]], i32 0
 // CHECK-NEXT:    [[TMP4:%.*]] = add i32 2, [[TMP1]]
-// CHECK-NEXT:    [[MATRIX_ELEM1:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP4]]
-// CHECK-NEXT:    [[MATRIX_ROW_INS2:%.*]] = insertelement <3 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
+// CHECK-NEXT:    [[MATRIX_ELEM1:%.*]] = extractelement <6 x i1> [[TRUNC]], i32 [[TMP4]]
+// CHECK-NEXT:    [[MATRIX_ROW_INS2:%.*]] = insertelement <3 x i1> [[MATRIX_ROW_INS]], i1 [[MATRIX_ELEM1]], i32 1
 // CHECK-NEXT:    [[TMP5:%.*]] = add i32 4, [[TMP1]]
-// CHECK-NEXT:    [[MATRIX_ELEM3:%.*]] = extractelement <6 x i32> [[TMP2]], i32 [[TMP5]]
-// CHECK-NEXT:    [[MATRIX_ROW_INS4:%.*]] = insertelement <3 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
-// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <3 x i32> [[MATRIX_ROW_INS4]], zeroinitializer
+// CHECK-NEXT:    [[MATRIX_ELEM3:%.*]] = extractelement <6 x i1> [[TRUNC]], i32 [[TMP5]]
+// CHECK-NEXT:    [[MATRIX_ROW_INS4:%.*]] = insertelement <3 x i1> [[MATRIX_ROW_INS2]], i1 [[MATRIX_ELEM3]], i32 2
+// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <3 x i1> [[MATRIX_ROW_INS4]], zeroinitializer
 // CHECK-NEXT:    ret <3 x i1> [[LOADEDV]]
 //
 bool3 getBoolVecMatrixDynamic(bool2x3 M, int index) {
@@ -241,20 +234,20 @@ bool3 getBoolVecMatrixDynamic(bool2x3 M, int index) {
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z24getBoolVecMatrixConstantu11matrix_typeILm4ELm4EbE(
 // CHECK-SAME: <16 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <16 x i1> [[M]] to <16 x i32>
 // CHECK-NEXT:    store <16 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
-// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <16 x i32> [[TMP1]], i32 0
-// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <4 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
-// CHECK-NEXT:    [[MATRIX_ELEM1:%.*]] = extractelement <16 x i32> [[TMP1]], i32 4
-// CHECK-NEXT:    [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS]], i32 [[MATRIX_ELEM1]], i32 1
-// CHECK-NEXT:    [[MATRIX_ELEM3:%.*]] = extractelement <16 x i32> [[TMP1]], i32 8
-// CHECK-NEXT:    [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS2]], i32 [[MATRIX_ELEM3]], i32 2
-// CHECK-NEXT:    [[MATRIX_ELEM5:%.*]] = extractelement <16 x i32> [[TMP1]], i32 12
-// CHECK-NEXT:    [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x i32> [[MATRIX_ROW_INS4]], i32 [[MATRIX_ELEM5]], i32 3
-// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <4 x i32> [[MATRIX_ROW_INS6]], zeroinitializer
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <16 x i32> [[TMP1]] to <16 x i1>
+// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <16 x i1> [[TRUNC]], i32 0
+// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <4 x i1> poison, i1 [[MATRIX_ELEM]], i32 0
+// CHECK-NEXT:    [[MATRIX_ELEM1:%.*]] = extractelement <16 x i1> [[TRUNC]], i32 4
+// CHECK-NEXT:    [[MATRIX_ROW_INS2:%.*]] = insertelement <4 x i1> [[MATRIX_ROW_INS]], i1 [[MATRIX_ELEM1]], i32 1
+// CHECK-NEXT:    [[MATRIX_ELEM3:%.*]] = extractelement <16 x i1> [[TRUNC]], i32 8
+// CHECK-NEXT:    [[MATRIX_ROW_INS4:%.*]] = insertelement <4 x i1> [[MATRIX_ROW_INS2]], i1 [[MATRIX_ELEM3]], i32 2
+// CHECK-NEXT:    [[MATRIX_ELEM5:%.*]] = extractelement <16 x i1> [[TRUNC]], i32 12
+// CHECK-NEXT:    [[MATRIX_ROW_INS6:%.*]] = insertelement <4 x i1> [[MATRIX_ROW_INS4]], i1 [[MATRIX_ELEM5]], i32 3
+// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <4 x i1> [[MATRIX_ROW_INS6]], zeroinitializer
 // CHECK-NEXT:    ret <4 x i1> [[LOADEDV]]
 //
 bool4 getBoolVecMatrixConstant(bool4x4 M) {
@@ -264,14 +257,14 @@ bool4 getBoolVecMatrixConstant(bool4x4 M) {
 // CHECK-LABEL: define hidden noundef i1 @_Z27getBoolScalarMatrixConstantu11matrix_typeILm3ELm1EbE(
 // CHECK-SAME: <3 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <3 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[M]] to <3 x i32>
 // CHECK-NEXT:    store <3 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i32>, ptr [[M_ADDR]], align 4
-// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <3 x i32> [[TMP1]], i32 1
-// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <1 x i32> poison, i32 [[MATRIX_ELEM]], i32 0
-// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <1 x i32> [[MATRIX_ROW_INS]], zeroinitializer
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i1>
+// CHECK-NEXT:    [[MATRIX_ELEM:%.*]] = extractelement <3 x i1> [[TRUNC]], i32 1
+// CHECK-NEXT:    [[MATRIX_ROW_INS:%.*]] = insertelement <1 x i1> poison, i1 [[MATRIX_ELEM]], i32 0
+// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne <1 x i1> [[MATRIX_ROW_INS]], zeroinitializer
 // CHECK-NEXT:    [[CAST_VTRUNC:%.*]] = extractelement <1 x i1> [[LOADEDV]], i32 0
 // CHECK-NEXT:    ret i1 [[CAST_VTRUNC]]
 //
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
index 358f976126f55..76d9a78ea9df8 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
@@ -4,7 +4,6 @@
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z2fnu11matrix_typeILm2ELm2EfE(
 // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [2 x <2 x float>], align 4
 // CHECK-NEXT:    [[V:%.*]] = alloca <4 x float>, align 4
 // CHECK-NEXT:    store <4 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -34,7 +33,6 @@ float4 fn(float2x2 m) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z2fnDv4_i(
 // CHECK-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca <4 x i32>, align 4
 // CHECK-NEXT:    [[M:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> [[V]], ptr [[V_ADDR]], align 4
@@ -64,7 +62,6 @@ int2x2 fn(int4 v) {
 // CHECK-LABEL: define hidden noundef <2 x i32> @_Z3fn1Dv2_i(
 // CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca <2 x i32>, align 4
 // CHECK-NEXT:    store <2 x i32> [[V]], ptr [[V_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i32>, ptr [[V_ADDR]], align 4
@@ -82,7 +79,6 @@ int1x2 fn1(int2 v) {
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z3fn2Dv3_b(
 // CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[B_ADDR:%.*]] = alloca <3 x i32>, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32>
 // CHECK-NEXT:    store <3 x i32> [[TMP0]], ptr [[B_ADDR]], align 4
@@ -107,21 +103,26 @@ bool3x1 fn2(bool3 b) {
 // CHECK-LABEL: define hidden noundef <3 x i32> @_Z3fn3u11matrix_typeILm1ELm3EbE(
 // CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // COL-CHECK-NEXT:    [[B_ADDR:%.*]] = alloca [3 x <1 x i32>], align 4
 // ROW-CHECK-NEXT:    [[B_ADDR:%.*]] = alloca [1 x <3 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32>
 // CHECK-NEXT:    store <3 x i32> [[TMP0]], ptr [[B_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4
-// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <3 x i32> [[TMP1]], i32 0
-// CHECK-NEXT:    [[VECINIT:%.*]] = insertelement <3 x i32> poison, i32 [[MATRIXEXT]], i32 0
+// CHECK-NEXT:    [[TRUNC1:%.*]] = trunc <3 x i32> [[TMP1]] to <3 x i1>
+// CHECK-NEXT:    [[MATRIXEXT1:%.*]] = extractelement <3 x i1> [[TRUNC1]], i32 0
+// CHECK-NEXT:    [[CONV1:%.*]] = zext i1 [[MATRIXEXT1]] to i32
+// CHECK-NEXT:    [[VECINIT1:%.*]] = insertelement <3 x i32> poison, i32 [[CONV1]], i32 0
 // CHECK-NEXT:    [[TMP2:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4
-// CHECK-NEXT:    [[MATRIXEXT1:%.*]] = extractelement <3 x i32> [[TMP2]], i32 1
-// CHECK-NEXT:    [[VECINIT2:%.*]] = insertelement <3 x i32> [[VECINIT]], i32 [[MATRIXEXT1]], i32 1
+// CHECK-NEXT:    [[TRUNC2:%.*]] = trunc <3 x i32> [[TMP2]] to <3 x i1>
+// CHECK-NEXT:    [[MATRIXEXT2:%.*]] = extractelement <3 x i1> [[TRUNC2]], i32 1
+// CHECK-NEXT:    [[CONV2:%.*]] = zext i1 [[MATRIXEXT2]] to i32
+// CHECK-NEXT:    [[VECINIT2:%.*]] = insertelement <3 x i32> [[VECINIT1]], i32 [[CONV2]], i32 1
 // CHECK-NEXT:    [[TMP3:%.*]] = load <3 x i32>, ptr [[B_ADDR]], align 4
-// CHECK-NEXT:    [[MATRIXEXT3:%.*]] = extractelement <3 x i32> [[TMP3]], i32 2
-// CHECK-NEXT:    [[VECINIT4:%.*]] = insertelement <3 x i32> [[VECINIT2]], i32 [[MATRIXEXT3]], i32 2
-// CHECK-NEXT:    ret <3 x i32> [[VECINIT4]]
+// CHECK-NEXT:    [[TRUNC3:%.*]] = trunc <3 x i32> [[TMP3]] to <3 x i1>
+// CHECK-NEXT:    [[MATRIXEXT3:%.*]] = extractelement <3 x i1> [[TRUNC3]], i32 2
+// CHECK-NEXT:    [[CONV3:%.*]] = zext i1 [[MATRIXEXT3]] to i32
+// CHECK-NEXT:    [[VECINIT3:%.*]] = insertelement <3 x i32> [[VECINIT2]], i32 [[CONV3]], i32 2
+// CHECK-NEXT:    ret <3 x i32> [[VECINIT3]]
 //
 int3 fn3(bool1x3 b) {
     return b;
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl
index ad227f9fe825e..5bef07346b0ff 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/VectorElementwiseCast.hlsl
@@ -193,19 +193,21 @@ export void call8(int3x1 M) {
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <2 x i1> %M to <2 x i32>
 // CHECK-NEXT:    store <2 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load <2 x i32>, ptr [[M_ADDR]], align 4
-// CHECK-NEXT:    store <2 x i32> [[TMP1]], ptr [[HLSL_EWCAST_SRC]], align 4
+// CHECK-NEXT:    [[LOADEDV0:%.*]] = trunc <2 x i32> [[TMP1]] to <2 x i1>
+// CHECK-NEXT:    [[TMP2:%.*]] = zext <2 x i1> [[LOADEDV0]] to <2 x i32>
+// CHECK-NEXT:    store <2 x i32> [[TMP2]], ptr [[HLSL_EWCAST_SRC]], align 4
 // CHECK-NEXT:    [[MATRIX_GEP:%.*]] = getelementptr inbounds <2 x i32>, ptr [[HLSL_EWCAST_SRC]], i32 0
-// CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i1>, ptr [[FLATCAST_TMP]], align 4
-// CHECK-NEXT:    [[TMP3:%.*]] = load <2 x i32>, ptr [[MATRIX_GEP]], align 4
-// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <2 x i32> [[TMP3]], i32 0
-// CHECK-NEXT:    [[LOADEDV:%.*]] = icmp ne i32 [[MATRIXEXT]], 0
-// CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i1> [[TMP2]], i1 [[LOADEDV]], i64 0
-// CHECK-NEXT:    [[TMP5:%.*]] = load <2 x i32>, ptr [[MATRIX_GEP]], align 4
-// CHECK-NEXT:    [[MATRIXEXT1:%.*]] = extractelement <2 x i32> [[TMP5]], i32 1
+// CHECK-NEXT:    [[TMP3:%.*]] = load <2 x i1>, ptr [[FLATCAST_TMP]], align 4
+// CHECK-NEXT:    [[TMP4:%.*]] = load <2 x i32>, ptr [[MATRIX_GEP]], align 4
+// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <2 x i32> [[TMP4]], i32 0
+// CHECK-NEXT:    [[LOADEDV1:%.*]] = icmp ne i32 [[MATRIXEXT]], 0
+// CHECK-NEXT:    [[TMP5:%.*]] = insertelement <2 x i1> [[TMP3]], i1 [[LOADEDV1]], i64 0
+// CHECK-NEXT:    [[TMP6:%.*]] = load <2 x i32>, ptr [[MATRIX_GEP]], align 4
+// CHECK-NEXT:    [[MATRIXEXT1:%.*]] = extractelement <2 x i32> [[TMP6]], i32 1
 // CHECK-NEXT:    [[LOADEDV2:%.*]] = icmp ne i32 [[MATRIXEXT1]], 0
-// CHECK-NEXT:    [[TMP6:%.*]] = insertelement <2 x i1> [[TMP4]], i1 [[LOADEDV2]], i64 1
-// CHECK-NEXT:    [[TMP7:%.*]] = zext <2 x i1> [[TMP6]] to <2 x i32>
-// CHECK-NEXT:    store <2 x i32> [[TMP7]], ptr [[V]], align 4
+// CHECK-NEXT:    [[TMP7:%.*]] = insertelement <2 x i1> [[TMP5]], i1 [[LOADEDV2]], i64 1
+// CHECK-NEXT:    [[TMP8:%.*]] = zext <2 x i1> [[TMP7]] to <2 x i32>
+// CHECK-NEXT:    store <2 x i32> [[TMP8]], ptr [[V]], align 4
 // CHECK-NEXT:    ret void
 export void call9(bool1x2 M) {
     bool2 V = (bool2)M;
diff --git a/clang/test/CodeGenHLSL/BoolMatrix.hlsl b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
index eeb2fa83d4656..d237c7a5eaaca 100644
--- a/clang/test/CodeGenHLSL/BoolMatrix.hlsl
+++ b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
@@ -10,15 +10,12 @@ struct S {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn1v(
 // CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca i1, align 4
 // CHECK-NEXT:    [[B:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[B]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[B]], align 4
-// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i32 0
-// CHECK-NEXT:    store i32 [[MATRIXEXT]], ptr [[RETVAL]], align 4
-// CHECK-NEXT:    [[TMP1:%.*]] = load i1, ptr [[RETVAL]], align 4
-// CHECK-NEXT:    ret i1 [[TMP1]]
+// CHECK-NEXT:    [[LOADEDV:%.*]] = trunc <4 x i32> [[TMP0]] to <4 x i1>
+// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i1> [[LOADEDV]], i32 0
+// CHECK-NEXT:    ret i1 [[MATRIXEXT]]
 //
 bool fn1() {
   bool2x2 B = {true,true,true,true};
@@ -28,8 +25,6 @@ bool fn1() {
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z3fn2b(
 // CHECK-SAME: i1 noundef [[V:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca <4 x i1>, align 4
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[A:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[V]] to i32
@@ -45,9 +40,8 @@ bool fn1() {
 // CHECK-NEXT:    [[TMP2:%.*]] = zext <4 x i1> [[VECINIT4]] to <4 x i32>
 // CHECK-NEXT:    store <4 x i32> [[TMP2]], ptr [[A]], align 4
 // CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i32>, ptr [[A]], align 4
-// CHECK-NEXT:    store <4 x i32> [[TMP3]], ptr [[RETVAL]], align 4
-// CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i1>, ptr [[RETVAL]], align 4
-// CHECK-NEXT:    ret <4 x i1> [[TMP4]]
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <4 x i32> [[TMP3]] to <4 x i1>
+// CHECK-NEXT:    ret <4 x i1> [[TRUNC]]
 //
 bool2x2 fn2(bool V) {
   bool2x2 A = {V, true, V, false};
@@ -57,16 +51,13 @@ bool2x2 fn2(bool V) {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn3v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca i1, align 4
 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[S]], ptr align 1 @__const._Z3fn3v.s, i32 20, i1 false)
 // CHECK-NEXT:    [[BM:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[BM]], align 1
-// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i32 0
-// CHECK-NEXT:    store i32 [[MATRIXEXT]], ptr [[RETVAL]], align 4
-// CHECK-NEXT:    [[TMP1:%.*]] = load i1, ptr [[RETVAL]], align 4
-// CHECK-NEXT:    ret i1 [[TMP1]]
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <4 x i32> [[TMP0]] to <4 x i1>
+// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i1> [[TRUNC]], i32 0
+// CHECK-NEXT:    ret i1 [[MATRIXEXT]]
 //
 bool fn3() {
   S s = {{true,true,false,false}, 1.0};
@@ -76,16 +67,13 @@ bool fn3() {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn4v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca i1, align 4
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
 // CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[ARRAYIDX]], align 4
-// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i32> [[TMP0]], i32 1
-// CHECK-NEXT:    store i32 [[MATRIXEXT]], ptr [[RETVAL]], align 4
-// CHECK-NEXT:    [[TMP1:%.*]] = load i1, ptr [[RETVAL]], align 4
-// CHECK-NEXT:    ret i1 [[TMP1]]
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <4 x i32> [[TMP0]] to <4 x i1>
+// CHECK-NEXT:    [[MATRIXEXT:%.*]] = extractelement <4 x i1> [[TRUNC]], i32 1
+// CHECK-NEXT:    ret i1 [[MATRIXEXT]]
 //
 bool fn4() {
   bool2x2 Arr[2] = {{true,true,true,true}, {false,false,false,false}};
@@ -95,7 +83,6 @@ bool fn4() {
 // CHECK-LABEL: define hidden void @_Z3fn5v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[M]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = getelementptr <4 x i32>, ptr [[M]], i32 0, i32 3
@@ -110,7 +97,6 @@ void fn5() {
 // CHECK-LABEL: define hidden void @_Z3fn6v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1
 // CHECK-NEXT:    store i32 0, ptr [[V]], align 4
@@ -132,7 +118,6 @@ void fn6() {
 // CHECK-LABEL: define hidden void @_Z3fn7v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit.1, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
@@ -148,15 +133,12 @@ void fn7() {
 // CHECK-LABEL: define hidden noundef <16 x i1> @_Z3fn8u11matrix_typeILm4ELm4EbE(
 // CHECK-SAME: <16 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
-// CHECK-NEXT:    [[RETVAL:%.*]] = alloca <16 x i1>, align 4
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <16 x i1> [[M]] to <16 x i32>
 // CHECK-NEXT:    store <16 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP1:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
-// CHECK-NEXT:    store <16 x i32> [[TMP1]], ptr [[RETVAL]], align 4
-// CHECK-NEXT:    [[TMP2:%.*]] = load <16 x i1>, ptr [[RETVAL]], align 4
-// CHECK-NEXT:    ret <16 x i1> [[TMP2]]
+// CHECK-NEXT:    [[TRUNC:%.*]] = trunc <16 x i32> [[TMP1]] to <16 x i1>
+// CHECK-NEXT:    ret <16 x i1> [[TRUNC]]
 //
 bool4x4 fn8(bool4x4 m) {
   return m;
diff --git a/clang/test/CodeGenHLSL/builtins/and_mat.hlsl b/clang/test/CodeGenHLSL/builtins/and_mat.hlsl
index c070dd90d9568..66c87c5de9453 100644
--- a/clang/test/CodeGenHLSL/builtins/and_mat.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/and_mat.hlsl
@@ -5,8 +5,8 @@
 // CHECK-LABEL: define hidden noundef <2 x i1> @_Z16test_and_bool1x2u11matrix_typeILm1ELm2EbES_(
 // CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <2 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <2 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <2 x i1> [[HLSL_AND]]
 bool1x2 test_and_bool1x2(bool1x2 x, bool1x2 y)
 {
     return and(x, y);
@@ -15,8 +15,8 @@ bool1x2 test_and_bool1x2(bool1x2 x, bool1x2 y)
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z16test_and_bool1x3u11matrix_typeILm1ELm3EbES_(
 // CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <3 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <3 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <3 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <3 x i1> [[HLSL_AND]]
 bool1x3 test_and_bool1x3(bool1x3 x, bool1x3 y)
 {
     return and(x, y);
@@ -25,8 +25,8 @@ bool1x3 test_and_bool1x3(bool1x3 x, bool1x3 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool1x4u11matrix_typeILm1ELm4EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_AND]]
 bool1x4 test_and_bool1x4(bool1x4 x, bool1x4 y)
 {
     return and(x, y);
@@ -35,8 +35,8 @@ bool1x4 test_and_bool1x4(bool1x4 x, bool1x4 y)
 // CHECK-LABEL: define hidden noundef <2 x i1> @_Z16test_and_bool2x1u11matrix_typeILm2ELm1EbES_(
 // CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <2 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <2 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <2 x i1> [[HLSL_AND]]
 bool2x1 test_and_bool2x1(bool2x1 x, bool2x1 y)
 {
     return and(x, y);
@@ -46,8 +46,8 @@ bool2x1 test_and_bool2x1(bool2x1 x, bool2x1 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool2x2u11matrix_typeILm2ELm2EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_AND]]
 bool2x2 test_and_bool2x2(bool2x2 x, bool2x2 y)
 {
     return and(x, y);
@@ -56,8 +56,8 @@ bool2x2 test_and_bool2x2(bool2x2 x, bool2x2 y)
 // CHECK-LABEL: define hidden noundef <6 x i1> @_Z16test_and_bool2x3u11matrix_typeILm2ELm3EbES_(
 // CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <6 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <6 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <6 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <6 x i1> [[HLSL_AND]]
 bool2x3 test_and_bool2x3(bool2x3 x, bool2x3 y)
 {
     return and(x, y);
@@ -66,8 +66,8 @@ bool2x3 test_and_bool2x3(bool2x3 x, bool2x3 y)
 // CHECK-LABEL: define hidden noundef <8 x i1> @_Z16test_and_bool2x4u11matrix_typeILm2ELm4EbES_(
 // CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <8 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <8 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <8 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <8 x i1> [[HLSL_AND]]
 bool2x4 test_and_bool2x4(bool2x4 x, bool2x4 y)
 {
     return and(x, y);
@@ -76,8 +76,8 @@ bool2x4 test_and_bool2x4(bool2x4 x, bool2x4 y)
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z16test_and_bool3x1u11matrix_typeILm3ELm1EbES_(
 // CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <3 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <3 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <3 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <3 x i1> [[HLSL_AND]]
 bool3x1 test_and_bool3x1(bool3x1 x, bool3x1 y)
 {
     return and(x, y);
@@ -86,8 +86,8 @@ bool3x1 test_and_bool3x1(bool3x1 x, bool3x1 y)
 // CHECK-LABEL: define hidden noundef <6 x i1> @_Z16test_and_bool3x2u11matrix_typeILm3ELm2EbES_(
 // CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <6 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <6 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <6 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <6 x i1> [[HLSL_AND]]
 bool3x2 test_and_bool3x2(bool3x2 x, bool3x2 y)
 {
     return and(x, y);
@@ -97,8 +97,8 @@ bool3x2 test_and_bool3x2(bool3x2 x, bool3x2 y)
 // CHECK-LABEL: define hidden noundef <9 x i1> @_Z16test_and_bool3x3u11matrix_typeILm3ELm3EbES_(
 // CHECK-SAME: <9 x i1> noundef [[X:%.*]], <9 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <9 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <9 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <9 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <9 x i1> [[HLSL_AND]]
 bool3x3 test_and_bool3x3(bool3x3 x, bool3x3 y)
 {
     return and(x, y);
@@ -107,8 +107,8 @@ bool3x3 test_and_bool3x3(bool3x3 x, bool3x3 y)
 // CHECK-LABEL: define hidden noundef <12 x i1> @_Z16test_and_bool3x4u11matrix_typeILm3ELm4EbES_(
 // CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <12 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <12 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <12 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <12 x i1> [[HLSL_AND]]
 bool3x4 test_and_bool3x4(bool3x4 x, bool3x4 y)
 {
     return and(x, y);
@@ -117,8 +117,8 @@ bool3x4 test_and_bool3x4(bool3x4 x, bool3x4 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool4x1u11matrix_typeILm4ELm1EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_AND]]
 bool4x1 test_and_bool4x1(bool4x1 x, bool4x1 y)
 {
     return and(x, y);
@@ -127,8 +127,8 @@ bool4x1 test_and_bool4x1(bool4x1 x, bool4x1 y)
 // CHECK-LABEL: define hidden noundef <8 x i1> @_Z16test_and_bool4x2u11matrix_typeILm4ELm2EbES_(
 // CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <8 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <8 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <8 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <8 x i1> [[HLSL_AND]]
 bool4x2 test_and_bool4x2(bool4x2 x, bool4x2 y)
 {
     return and(x, y);
@@ -137,8 +137,8 @@ bool4x2 test_and_bool4x2(bool4x2 x, bool4x2 y)
 // CHECK-LABEL: define hidden noundef <12 x i1> @_Z16test_and_bool4x3u11matrix_typeILm4ELm3EbES_(
 // CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <12 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <12 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <12 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <12 x i1> [[HLSL_AND]]
 bool4x3 test_and_bool4x3(bool4x3 x, bool4x3 y)
 {
     return and(x, y);
@@ -147,8 +147,8 @@ bool4x3 test_and_bool4x3(bool4x3 x, bool4x3 y)
 // CHECK-LABEL: define hidden noundef <16 x i1> @_Z16test_and_bool4x4u11matrix_typeILm4ELm4EbES_(
 // CHECK-SAME: <16 x i1> noundef [[X:%.*]], <16 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_AND:%.*]] = and <16 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <16 x i1> [[HLSL_AND_CAST:%.*]]
+// CHECK:         [[HLSL_AND:%.*]] = and <16 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <16 x i1> [[HLSL_AND]]
 bool4x4 test_and_bool4x4(bool4x4 x, bool4x4 y)
 {
     return and(x, y);
diff --git a/clang/test/CodeGenHLSL/builtins/or.hlsl b/clang/test/CodeGenHLSL/builtins/or.hlsl
index cf07d2fb7b42b..bd6f9c3f21d49 100644
--- a/clang/test/CodeGenHLSL/builtins/or.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/or.hlsl
@@ -81,8 +81,8 @@ bool4 test_or_float4(float4 x, float4 y)
 // CHECK-LABEL: define hidden noundef <2 x i1> @_Z15test_or_bool1x2u11matrix_typeILm1ELm2EbES_(
 // CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <2 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <2 x i1> [[HLSL_OR]]
 bool1x2 test_or_bool1x2(bool1x2 x, bool1x2 y)
 {
     return or(x, y);
@@ -91,8 +91,8 @@ bool1x2 test_or_bool1x2(bool1x2 x, bool1x2 y)
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z15test_or_bool1x3u11matrix_typeILm1ELm3EbES_(
 // CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <3 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <3 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <3 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <3 x i1> [[HLSL_OR]]
 bool1x3 test_or_bool1x3(bool1x3 x, bool1x3 y)
 {
     return or(x, y);
@@ -101,8 +101,8 @@ bool1x3 test_or_bool1x3(bool1x3 x, bool1x3 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z15test_or_bool1x4u11matrix_typeILm1ELm4EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool1x4 test_or_bool1x4(bool1x4 x, bool1x4 y)
 {
     return or(x, y);
@@ -111,8 +111,8 @@ bool1x4 test_or_bool1x4(bool1x4 x, bool1x4 y)
 // CHECK-LABEL: define hidden noundef <2 x i1> @_Z15test_or_bool2x1u11matrix_typeILm2ELm1EbES_(
 // CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <2 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <2 x i1> [[HLSL_OR]]
 bool2x1 test_or_bool2x1(bool2x1 x, bool2x1 y)
 {
     return or(x, y);
@@ -122,8 +122,8 @@ bool2x1 test_or_bool2x1(bool2x1 x, bool2x1 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z15test_or_bool2x2u11matrix_typeILm2ELm2EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool2x2 test_or_bool2x2(bool2x2 x, bool2x2 y)
 {
     return or(x, y);
@@ -132,8 +132,8 @@ bool2x2 test_or_bool2x2(bool2x2 x, bool2x2 y)
 // CHECK-LABEL: define hidden noundef <6 x i1> @_Z15test_or_bool2x3u11matrix_typeILm2ELm3EbES_(
 // CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <6 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <6 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <6 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <6 x i1> [[HLSL_OR]]
 bool2x3 test_or_bool2x3(bool2x3 x, bool2x3 y)
 {
     return or(x, y);
@@ -142,8 +142,8 @@ bool2x3 test_or_bool2x3(bool2x3 x, bool2x3 y)
 // CHECK-LABEL: define hidden noundef <8 x i1> @_Z15test_or_bool2x4u11matrix_typeILm2ELm4EbES_(
 // CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <8 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <8 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <8 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <8 x i1> [[HLSL_OR]]
 bool2x4 test_or_bool2x4(bool2x4 x, bool2x4 y)
 {
     return or(x, y);
@@ -152,8 +152,8 @@ bool2x4 test_or_bool2x4(bool2x4 x, bool2x4 y)
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z15test_or_bool3x1u11matrix_typeILm3ELm1EbES_(
 // CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <3 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <3 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <3 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <3 x i1> [[HLSL_OR]]
 bool3x1 test_or_bool3x1(bool3x1 x, bool3x1 y)
 {
     return or(x, y);
@@ -162,8 +162,8 @@ bool3x1 test_or_bool3x1(bool3x1 x, bool3x1 y)
 // CHECK-LABEL: define hidden noundef <6 x i1> @_Z15test_or_bool3x2u11matrix_typeILm3ELm2EbES_(
 // CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <6 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <6 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <6 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <6 x i1> [[HLSL_OR]]
 bool3x2 test_or_bool3x2(bool3x2 x, bool3x2 y)
 {
     return or(x, y);
@@ -173,8 +173,8 @@ bool3x2 test_or_bool3x2(bool3x2 x, bool3x2 y)
 // CHECK-LABEL: define hidden noundef <9 x i1> @_Z15test_or_bool3x3u11matrix_typeILm3ELm3EbES_(
 // CHECK-SAME: <9 x i1> noundef [[X:%.*]], <9 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <9 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <9 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <9 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <9 x i1> [[HLSL_OR]]
 bool3x3 test_or_bool3x3(bool3x3 x, bool3x3 y)
 {
     return or(x, y);
@@ -183,8 +183,8 @@ bool3x3 test_or_bool3x3(bool3x3 x, bool3x3 y)
 // CHECK-LABEL: define hidden noundef <12 x i1> @_Z15test_or_bool3x4u11matrix_typeILm3ELm4EbES_(
 // CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <12 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <12 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <12 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <12 x i1> [[HLSL_OR]]
 bool3x4 test_or_bool3x4(bool3x4 x, bool3x4 y)
 {
     return or(x, y);
@@ -193,8 +193,8 @@ bool3x4 test_or_bool3x4(bool3x4 x, bool3x4 y)
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z15test_or_bool4x1u11matrix_typeILm4ELm1EbES_(
 // CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <4 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <4 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool4x1 test_or_bool4x1(bool4x1 x, bool4x1 y)
 {
     return or(x, y);
@@ -203,8 +203,8 @@ bool4x1 test_or_bool4x1(bool4x1 x, bool4x1 y)
 // CHECK-LABEL: define hidden noundef <8 x i1> @_Z15test_or_bool4x2u11matrix_typeILm4ELm2EbES_(
 // CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <8 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <8 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <8 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <8 x i1> [[HLSL_OR]]
 bool4x2 test_or_bool4x2(bool4x2 x, bool4x2 y)
 {
     return or(x, y);
@@ -213,8 +213,8 @@ bool4x2 test_or_bool4x2(bool4x2 x, bool4x2 y)
 // CHECK-LABEL: define hidden noundef <12 x i1> @_Z15test_or_bool4x3u11matrix_typeILm4ELm3EbES_(
 // CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <12 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <12 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <12 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <12 x i1> [[HLSL_OR]]
 bool4x3 test_or_bool4x3(bool4x3 x, bool4x3 y)
 {
     return or(x, y);
@@ -223,8 +223,8 @@ bool4x3 test_or_bool4x3(bool4x3 x, bool4x3 y)
 // CHECK-LABEL: define hidden noundef <16 x i1> @_Z15test_or_bool4x4u11matrix_typeILm4ELm4EbES_(
 // CHECK-SAME: <16 x i1> noundef [[X:%.*]], <16 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  entry:
-// CHECK:         [[HLSL_OR:%.*]] = or <16 x i32> [[A:%.*]], [[B:%.*]]
-// CHECK:         ret <16 x i1> [[HLSL_OR_CAST:%.*]]
+// CHECK:         [[HLSL_OR:%.*]] = or <16 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <16 x i1> [[HLSL_OR]]
 bool4x4 test_or_bool4x4(bool4x4 x, bool4x4 y)
 {
     return or(x, y);
diff --git a/clang/test/CodeGenHLSL/builtins/transpose.hlsl b/clang/test/CodeGenHLSL/builtins/transpose.hlsl
index d8430fcf5bf9d..0863fba6190c1 100644
--- a/clang/test/CodeGenHLSL/builtins/transpose.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/transpose.hlsl
@@ -9,8 +9,9 @@
 // CHECK:       [[A_EXT:%.*]] = zext <6 x i1> %{{.*}} to <6 x i32>
 // CHECK:       store <6 x i32> [[A_EXT]], ptr [[A_ADDR]], align 4
 // CHECK:       [[A:%.*]] = load <6 x i32>, ptr [[A_ADDR]], align 4
-// COLMAJOR:    [[TRANS:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[A]], i32 2, i32 3)
-// ROWMAJOR:    [[TRANS:%.*]] = call <6 x i32> @llvm.matrix.transpose.v6i32(<6 x i32> [[A]], i32 3, i32 2)
+// CHECK:       [[TRUNC:%.*]] = trunc <6 x i32> [[A]] to <6 x i1>
+// COLMAJOR:    [[TRANS:%.*]] = call <6 x i1> @llvm.matrix.transpose.v6i1(<6 x i1> [[TRUNC]], i32 2, i32 3)
+// ROWMAJOR:    [[TRANS:%.*]] = call <6 x i1> @llvm.matrix.transpose.v6i1(<6 x i1> [[TRUNC]], i32 3, i32 2)
 bool3x2 test_transpose_bool2x3(bool2x3 a) {
   return transpose(a);
 }

>From dd901f8828970561e7d7ce2a1ce8998018031e1b Mon Sep 17 00:00:00 2001
From: danbrown-amd <danbrown at amd.com>
Date: Wed, 3 Jun 2026 10:21:10 -0600
Subject: [PATCH 4/5] Restores convergence.entry checks.

---
 .../BasicFeatures/MatrixSingleSubscriptGetter.hlsl     | 10 ++++++++++
 .../MatrixToAndFromVectorConstructors.hlsl             |  5 +++++
 clang/test/CodeGenHLSL/BoolMatrix.hlsl                 |  8 ++++++++
 3 files changed, 23 insertions(+)

diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
index baac77b2e0fad..6adf7e80fe0eb 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixSingleSubscriptGetter.hlsl
@@ -4,6 +4,7 @@
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z24getFloatVecMatrixDynamicu11matrix_typeILm4ELm4EfEi(
 // CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x float>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <16 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -31,6 +32,7 @@ float4 getFloatVecMatrixDynamic(float4x4 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z27getFloatScalarMatrixDynamicu11matrix_typeILm2ELm1EfEi(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -50,6 +52,7 @@ float getFloatScalarMatrixDynamic(float2x1 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z28getFloatScalarMatrixConstantu11matrix_typeILm2ELm1EfE(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
@@ -65,6 +68,7 @@ float getFloatScalarMatrixConstant(float2x1 M) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) float @_Z29getFloatScalarMatrixConstant2u11matrix_typeILm2ELm1EfE(
 // CHECK-SAME: <2 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <2 x float>], align 4
 // CHECK-NEXT:    store <2 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x float>, ptr [[M_ADDR]], align 4
@@ -80,6 +84,7 @@ float getFloatScalarMatrixConstant2(float2x1 M) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z19getIntMatrixDynamicu11matrix_typeILm4ELm4EiEi(
 // CHECK-SAME: <16 x i32> noundef [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
@@ -107,6 +112,7 @@ int4 getIntMatrixDynamic(int4x4 M, int index) {
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z22AddFloatMatrixConstantu11matrix_typeILm4ELm4EfE(
 // CHECK-SAME: <16 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x float>], align 4
 // CHECK-NEXT:    store <16 x float> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <16 x float>, ptr [[M_ADDR]], align 4
@@ -157,6 +163,7 @@ float4 AddFloatMatrixConstant(float4x4 M) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z20AddIntMatrixConstantu11matrix_typeILm4ELm4EiE(
 // CHECK-SAME: <16 x i32> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    store <16 x i32> [[M]], ptr [[M_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i32>, ptr [[M_ADDR]], align 4
@@ -207,6 +214,7 @@ int4 AddIntMatrixConstant(int4x4 M) {
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z23getBoolVecMatrixDynamicu11matrix_typeILm2ELm3EbEi(
 // CHECK-SAME: <6 x i1> noundef [[M:%.*]], i32 noundef [[INDEX:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [3 x <2 x i32>], align 4
 // CHECK-NEXT:    [[INDEX_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <6 x i1> [[M]] to <6 x i32>
@@ -234,6 +242,7 @@ bool3 getBoolVecMatrixDynamic(bool2x3 M, int index) {
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z24getBoolVecMatrixConstantu11matrix_typeILm4ELm4EbE(
 // CHECK-SAME: <16 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <16 x i1> [[M]] to <16 x i32>
 // CHECK-NEXT:    store <16 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
@@ -257,6 +266,7 @@ bool4 getBoolVecMatrixConstant(bool4x4 M) {
 // CHECK-LABEL: define hidden noundef i1 @_Z27getBoolScalarMatrixConstantu11matrix_typeILm3ELm1EbE(
 // CHECK-SAME: <3 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [1 x <3 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[M]] to <3 x i32>
 // CHECK-NEXT:    store <3 x i32> [[TMP0]], ptr [[M_ADDR]], align 4
diff --git a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
index 76d9a78ea9df8..c75116ec6c9cd 100644
--- a/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
+++ b/clang/test/CodeGenHLSL/BasicFeatures/MatrixToAndFromVectorConstructors.hlsl
@@ -4,6 +4,7 @@
 // CHECK-LABEL: define hidden noundef nofpclass(nan inf) <4 x float> @_Z2fnu11matrix_typeILm2ELm2EfE(
 // CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[M:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [2 x <2 x float>], align 4
 // CHECK-NEXT:    [[V:%.*]] = alloca <4 x float>, align 4
 // CHECK-NEXT:    store <4 x float> [[M]], ptr [[M_ADDR]], align 4
@@ -33,6 +34,7 @@ float4 fn(float2x2 m) {
 // CHECK-LABEL: define hidden noundef <4 x i32> @_Z2fnDv4_i(
 // CHECK-SAME: <4 x i32> noundef [[V:%.*]]) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca <4 x i32>, align 4
 // CHECK-NEXT:    [[M:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> [[V]], ptr [[V_ADDR]], align 4
@@ -62,6 +64,7 @@ int2x2 fn(int4 v) {
 // CHECK-LABEL: define hidden noundef <2 x i32> @_Z3fn1Dv2_i(
 // CHECK-SAME: <2 x i32> noundef [[V:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca <2 x i32>, align 4
 // CHECK-NEXT:    store <2 x i32> [[V]], ptr [[V_ADDR]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i32>, ptr [[V_ADDR]], align 4
@@ -79,6 +82,7 @@ int1x2 fn1(int2 v) {
 // CHECK-LABEL: define hidden noundef <3 x i1> @_Z3fn2Dv3_b(
 // CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[B_ADDR:%.*]] = alloca <3 x i32>, align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32>
 // CHECK-NEXT:    store <3 x i32> [[TMP0]], ptr [[B_ADDR]], align 4
@@ -103,6 +107,7 @@ bool3x1 fn2(bool3 b) {
 // CHECK-LABEL: define hidden noundef <3 x i32> @_Z3fn3u11matrix_typeILm1ELm3EbE(
 // CHECK-SAME: <3 x i1> noundef [[B:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // COL-CHECK-NEXT:    [[B_ADDR:%.*]] = alloca [3 x <1 x i32>], align 4
 // ROW-CHECK-NEXT:    [[B_ADDR:%.*]] = alloca [1 x <3 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <3 x i1> [[B]] to <3 x i32>
diff --git a/clang/test/CodeGenHLSL/BoolMatrix.hlsl b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
index d237c7a5eaaca..2b21d45495156 100644
--- a/clang/test/CodeGenHLSL/BoolMatrix.hlsl
+++ b/clang/test/CodeGenHLSL/BoolMatrix.hlsl
@@ -10,6 +10,7 @@ struct S {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn1v(
 // CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[B:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[B]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[B]], align 4
@@ -25,6 +26,7 @@ bool fn1() {
 // CHECK-LABEL: define hidden noundef <4 x i1> @_Z3fn2b(
 // CHECK-SAME: i1 noundef [[V:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V_ADDR:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[A:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    [[STOREDV:%.*]] = zext i1 [[V]] to i32
@@ -51,6 +53,7 @@ bool2x2 fn2(bool V) {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn3v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[S]], ptr align 1 @__const._Z3fn3v.s, i32 20, i1 false)
 // CHECK-NEXT:    [[BM:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0
@@ -67,6 +70,7 @@ bool fn3() {
 // CHECK-LABEL: define hidden noundef i1 @_Z3fn4v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
@@ -83,6 +87,7 @@ bool fn4() {
 // CHECK-LABEL: define hidden void @_Z3fn5v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M:%.*]] = alloca [2 x <2 x i32>], align 4
 // CHECK-NEXT:    store <4 x i32> splat (i32 1), ptr [[M]], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = getelementptr <4 x i32>, ptr [[M]], i32 0, i32 3
@@ -97,6 +102,7 @@ void fn5() {
 // CHECK-LABEL: define hidden void @_Z3fn6v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[V:%.*]] = alloca i32, align 4
 // CHECK-NEXT:    [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1
 // CHECK-NEXT:    store i32 0, ptr [[V]], align 4
@@ -118,6 +124,7 @@ void fn6() {
 // CHECK-LABEL: define hidden void @_Z3fn7v(
 // CHECK-SAME: ) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[ARR:%.*]] = alloca [2 x [2 x <2 x i32>]], align 4
 // CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[ARR]], ptr align 4 @constinit.1, i32 32, i1 false)
 // CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [2 x <2 x i32>]], ptr [[ARR]], i32 0, i32 0
@@ -133,6 +140,7 @@ void fn7() {
 // CHECK-LABEL: define hidden noundef <16 x i1> @_Z3fn8u11matrix_typeILm4ELm4EbE(
 // CHECK-SAME: <16 x i1> noundef [[M:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
+// CHECK-NEXT:    %[[#C_ENTRY:]] = call token @llvm.experimental.convergence.entry()
 // CHECK-NEXT:    [[M_ADDR:%.*]] = alloca [4 x <4 x i32>], align 4
 // CHECK-NEXT:    [[TMP0:%.*]] = zext <16 x i1> [[M]] to <16 x i32>
 // CHECK-NEXT:    store <16 x i32> [[TMP0]], ptr [[M_ADDR]], align 4

>From ebb0530db3b95c13069b1ed48e49d34b477af1a4 Mon Sep 17 00:00:00 2001
From: Dan Brown <danbrown at amd.com>
Date: Wed, 3 Jun 2026 17:53:08 -0600
Subject: [PATCH 5/5] Uses macros to generate double compatibility tests.

---
 .../lib/Headers/hlsl/hlsl_compat_overloads.h  | 80 +------------------
 1 file changed, 4 insertions(+), 76 deletions(-)

diff --git a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
index 4d00b34b32ca0..970d1c819971e 100644
--- a/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
+++ b/clang/lib/Headers/hlsl/hlsl_compat_overloads.h
@@ -382,87 +382,15 @@ _DXC_COMPAT_UNARY_INTEGER_OVERLOADS(frac)
 // isinf builtins overloads
 //===----------------------------------------------------------------------===//
 
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool isinf(double V) { return isinf((float)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2 isinf(double2 V) { return isinf((float2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3 isinf(double3 V) { return isinf((float3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4 isinf(double4 V) { return isinf((float4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x2 isinf(double1x2 V) { return isinf((float1x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x3 isinf(double1x3 V) { return isinf((float1x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x4 isinf(double1x4 V) { return isinf((float1x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x1 isinf(double2x1 V) { return isinf((float2x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x2 isinf(double2x2 V) { return isinf((float2x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x3 isinf(double2x3 V) { return isinf((float2x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x4 isinf(double2x4 V) { return isinf((float2x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x1 isinf(double3x1 V) { return isinf((float3x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x2 isinf(double3x2 V) { return isinf((float3x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x3 isinf(double3x3 V) { return isinf((float3x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x4 isinf(double3x4 V) { return isinf((float3x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x1 isinf(double4x1 V) { return isinf((float4x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x2 isinf(double4x2 V) { return isinf((float4x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x3 isinf(double4x3 V) { return isinf((float4x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x4 isinf(double4x4 V) { return isinf((float4x4)V); }
+_DXC_COMPAT_BINARY_DOUBLE_OVERLOADS(isinf)
+_DXC_COMPAT_BINARY_DOUBLE_MATRIX_OVERLOADS(isinf)
 
 //===----------------------------------------------------------------------===//
 // isnan builtins overloads
 //===----------------------------------------------------------------------===//
 
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool isnan(double V) { return isnan((float)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2 isnan(double2 V) { return isnan((float2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3 isnan(double3 V) { return isnan((float3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4 isnan(double4 V) { return isnan((float4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x2 isnan(double1x2 V) { return isnan((float1x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x3 isnan(double1x3 V) { return isnan((float1x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool1x4 isnan(double1x4 V) { return isnan((float1x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x1 isnan(double2x1 V) { return isnan((float2x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x2 isnan(double2x2 V) { return isnan((float2x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x3 isnan(double2x3 V) { return isnan((float2x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool2x4 isnan(double2x4 V) { return isnan((float2x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x1 isnan(double3x1 V) { return isnan((float3x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x2 isnan(double3x2 V) { return isnan((float3x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x3 isnan(double3x3 V) { return isnan((float3x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool3x4 isnan(double3x4 V) { return isnan((float3x4)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x1 isnan(double4x1 V) { return isnan((float4x1)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x2 isnan(double4x2 V) { return isnan((float4x2)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x3 isnan(double4x3 V) { return isnan((float4x3)V); }
-_DXC_DEPRECATED_64BIT_FN(fn)
-constexpr bool4x4 isnan(double4x4 V) { return isnan((float4x4)V); }
+_DXC_COMPAT_BINARY_DOUBLE_OVERLOADS(isnan)
+_DXC_COMPAT_BINARY_DOUBLE_MATRIX_OVERLOADS(isnan)
 
 //===----------------------------------------------------------------------===//
 // lerp builtins overloads



More information about the cfe-commits mailing list