Author: Farzon Lotfi
Date: 2025-12-20T17:20:32-05:00
New Revision: cb56a910f8bc90cb7df700fa702b75a0a2c550f8

URL: 
https://github.com/llvm/llvm-project/commit/cb56a910f8bc90cb7df700fa702b75a0a2c550f8
DIFF: 
https://github.com/llvm/llvm-project/commit/cb56a910f8bc90cb7df700fa702b75a0a2c550f8.diff

LOG: [HLSL][Matrix] Add OR and AND logical operator support for matrix (#172384)

fixes #172341

This change adds the `or` and `and` HLSL builtins with overloads for the
matrix types.

It also disables the logical operators from being used for HLSL 2021. To
keep this code from getting too complicated HLSL 2018 and lower logical
operator support was not added.

Added: 
    clang/test/CodeGenHLSL/builtins/and_mat.hlsl
    clang/test/SemaHLSL/BuiltIns/logical-mat-operator-errors.hlsl

Modified: 
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/Sema.h
    clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaHLSL.cpp
    clang/test/CodeGenHLSL/builtins/or.hlsl
    clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
    clang/test/SemaHLSL/Language/UsualArithmeticConversions.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 95ef2a1d9f614..9ff22b03ec86d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9763,6 +9763,9 @@ def err_typecheck_cond_incompatible_operands : Error<
 def err_typecheck_expect_scalar_or_vector : Error<
   "invalid operand of type %0 where %1 or "
   "a vector of such type is required">;
+def err_typecheck_expect_scalar_or_vector_or_matrix : Error<
+  "invalid operand of type %0 where %1 or "
+  "a vector or matrix of such type is required">;
 def err_typecheck_expect_any_scalar_or_vector : Error<
   "invalid operand of type %0%select{| where a scalar or vector is 
required}1">;
 def err_typecheck_expect_flt_or_vector : Error<
@@ -13284,6 +13287,7 @@ def err_std_initializer_list_malformed : Error<
   "%0 layout not recognized. Must be a non-polymorphic class type with no 
bases and two fields: a 'const E *' and either another 'const E *' or a 
'std::size_t'">;
 
 // HLSL Diagnostics
+def err_hlsl_langstd_unimplemented : Error<"support for HLSL language version 
%0 is incomplete">;
 def err_hlsl_attr_unsupported_in_stage : Error<"attribute %0 is unsupported in 
'%1' shaders, requires %select{|one of the following: }2%3">;
 def err_hlsl_attr_invalid_type : Error<
    "attribute %0 only applies to a field or parameter of type '%1'">;

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 91b07aa500b86..b5d9f4cf9fa8b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7868,7 +7868,9 @@ class Sema final : public SemaBase {
   QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
                                       SourceLocation Loc,
                                       BinaryOperatorKind Opc);
-
+  QualType CheckMatrixLogicalOperands(ExprResult &LHS, ExprResult &RHS,
+                                      SourceLocation Loc,
+                                      BinaryOperatorKind Opc);
   // type checking for sizeless vector binary operators.
   QualType CheckSizelessVectorOperands(ExprResult &LHS, ExprResult &RHS,
                                        SourceLocation Loc, bool IsCompAssign,

diff  --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h 
b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
index f58150ed61106..b065e5dd8447f 100644
--- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
+++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h
@@ -294,8 +294,8 @@ bool all(double4);
 
//===----------------------------------------------------------------------===//
 
 /// \fn bool and(bool x, bool y)
-/// \brief Logically ands two boolean vectors elementwise and produces a bool
-/// vector output.
+/// \brief Logically ands two boolean vectors or matrices elementwise and
+/// produces a bool vector or matrix output.
 
 // TODO: Clean up clang-format marker once we've resolved
 //       https://github.com/llvm/llvm-project/issues/127851
@@ -309,6 +309,38 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
 bool3 and(bool3 x, bool3 y);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
 bool4 and(bool4 x, bool4 y);
+
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool1x2 and(bool1x2 x, bool1x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool1x3 and(bool1x3 x, bool1x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool1x4 and(bool1x4 x, bool1x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2x1 and(bool2x1 x, bool2x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2x2 and(bool2x2 x, bool2x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2x3 and(bool2x3 x, bool2x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool2x4 and(bool2x4 x, bool2x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3x1 and(bool3x1 x, bool3x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3x2 and(bool3x2 x, bool3x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3x3 and(bool3x3 x, bool3x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool3x4 and(bool3x4 x, bool3x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4x1 and(bool4x1 x, bool4x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4x2 and(bool4x2 x, bool4x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4x3 and(bool4x3 x, bool4x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
+bool4x4 and(bool4x4 x, bool4x4 y);
 // clang-format on
 
 
//===----------------------------------------------------------------------===//
@@ -1759,8 +1791,8 @@ float4 normalize(float4);
 
//===----------------------------------------------------------------------===//
 
 /// \fn bool or(bool x, bool y)
-/// \brief Logically ors two boolean vectors elementwise and produces a bool
-/// vector output.
+/// \brief Logically ors two boolean vectors or matrices elementwise and
+///  produces a bool vector or matrix output.
 
 // TODO: Clean up clang-format marker once we've resolved
 //       https://github.com/llvm/llvm-project/issues/127851
@@ -1774,6 +1806,37 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
 bool3 or(bool3, bool3);
 _HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
 bool4 or(bool4, bool4);
+
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool1x2 or(bool1x2 x, bool1x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool1x3 or(bool1x3 x, bool1x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool1x4 or(bool1x4 x, bool1x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2x1 or(bool2x1 x, bool2x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2x2 or(bool2x2 x, bool2x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2x3 or(bool2x3 x, bool2x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool2x4 or(bool2x4 x, bool2x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3x1 or(bool3x1 x, bool3x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3x2 or(bool3x2 x, bool3x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3x3 or(bool3x3 x, bool3x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool3x4 or(bool3x4 x, bool3x4 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4x1 or(bool4x1 x, bool4x1 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4x2 or(bool4x2 x, bool4x2 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4x3 or(bool4x3 x, bool4x3 y);
+_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
+bool4x4 or(bool4x4 x, bool4x4 y);
 // clang-format on
 
 
//===----------------------------------------------------------------------===//

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5a31b42541d99..e12e4b204afad 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -13445,6 +13445,25 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult 
&LHS, ExprResult &RHS,
   return GetSignedVectorType(LHS.get()->getType());
 }
 
+QualType Sema::CheckMatrixLogicalOperands(ExprResult &LHS, ExprResult &RHS,
+                                          SourceLocation Loc,
+                                          BinaryOperatorKind Opc) {
+
+  if (!getLangOpts().HLSL) {
+    assert(false && "Logical operands are not supported in C\\C++");
+    return QualType();
+  }
+
+  if (getLangOpts().getHLSLVersion() >= LangOptionsBase::HLSL_2021) {
+    (void)InvalidOperands(Loc, LHS, RHS);
+    HLSL().emitLogicalOperatorFixIt(LHS.get(), RHS.get(), Opc);
+    return QualType();
+  }
+  SemaRef.Diag(LHS.get()->getBeginLoc(), diag::err_hlsl_langstd_unimplemented)
+      << getLangOpts().getHLSLVersion();
+  return QualType();
+}
+
 QualType Sema::CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
                                               SourceLocation Loc,
                                               bool IsCompAssign) {
@@ -13617,6 +13636,10 @@ inline QualType Sema::CheckLogicalOperands(ExprResult 
&LHS, ExprResult &RHS,
       RHS.get()->getType()->isVectorType())
     return CheckVectorLogicalOperands(LHS, RHS, Loc, Opc);
 
+  if (LHS.get()->getType()->isConstantMatrixType() ||
+      RHS.get()->getType()->isConstantMatrixType())
+    return CheckMatrixLogicalOperands(LHS, RHS, Loc, Opc);
+
   bool EnumConstantInBoolContext = false;
   for (const ExprResult &HS : {LHS, RHS}) {
     if (const auto *DREHS = dyn_cast<DeclRefExpr>(HS.get())) {

diff  --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 3db885022491e..06130c985876f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2998,6 +2998,36 @@ static bool CheckScalarOrVector(Sema *S, CallExpr 
*TheCall, QualType Scalar,
   return false;
 }
 
+static bool CheckScalarOrVectorOrMatrix(Sema *S, CallExpr *TheCall,
+                                        QualType Scalar, unsigned ArgIndex) {
+  assert(TheCall->getNumArgs() > ArgIndex);
+
+  Expr *Arg = TheCall->getArg(ArgIndex);
+  QualType ArgType = Arg->getType();
+
+  // Scalar: T
+  if (S->Context.hasSameUnqualifiedType(ArgType, Scalar))
+    return false;
+
+  // Vector: vector<T>
+  if (const auto *VTy = ArgType->getAs<VectorType>()) {
+    if (S->Context.hasSameUnqualifiedType(VTy->getElementType(), Scalar))
+      return false;
+  }
+
+  // Matrix: ConstantMatrixType with element type T
+  if (const auto *MTy = ArgType->getAs<ConstantMatrixType>()) {
+    if (S->Context.hasSameUnqualifiedType(MTy->getElementType(), Scalar))
+      return false;
+  }
+
+  // Not a scalar/vector/matrix-of-scalar
+  S->Diag(Arg->getBeginLoc(),
+          diag::err_typecheck_expect_scalar_or_vector_or_matrix)
+      << ArgType << Scalar;
+  return true;
+}
+
 static bool CheckAnyScalarOrVector(Sema *S, CallExpr *TheCall,
                                    unsigned ArgIndex) {
   assert(TheCall->getNumArgs() >= ArgIndex);
@@ -3230,7 +3260,8 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   case Builtin::BI__builtin_hlsl_or: {
     if (SemaRef.checkArgCount(TheCall, 2))
       return true;
-    if (CheckScalarOrVector(&SemaRef, TheCall, getASTContext().BoolTy, 0))
+    if (CheckScalarOrVectorOrMatrix(&SemaRef, TheCall, getASTContext().BoolTy,
+                                    0))
       return true;
     if (CheckAllArgsHaveSameType(&SemaRef, TheCall))
       return true;

diff  --git a/clang/test/CodeGenHLSL/builtins/and_mat.hlsl 
b/clang/test/CodeGenHLSL/builtins/and_mat.hlsl
new file mode 100644
index 0000000000000..c070dd90d9568
--- /dev/null
+++ b/clang/test/CodeGenHLSL/builtins/and_mat.hlsl
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 -finclude-default-header -triple \
+// RUN:   dxil-pc-shadermodel6.3-library %s \
+// RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s
+
+// 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:%.*]]
+bool1x2 test_and_bool1x2(bool1x2 x, bool1x2 y)
+{
+    return and(x, 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:%.*]]
+bool1x3 test_and_bool1x3(bool1x3 x, bool1x3 y)
+{
+    return and(x, 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:%.*]]
+bool1x4 test_and_bool1x4(bool1x4 x, bool1x4 y)
+{
+    return and(x, 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:%.*]]
+bool2x1 test_and_bool2x1(bool2x1 x, bool2x1 y)
+{
+    return and(x, 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:%.*]]
+bool2x2 test_and_bool2x2(bool2x2 x, bool2x2 y)
+{
+    return and(x, 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:%.*]]
+bool2x3 test_and_bool2x3(bool2x3 x, bool2x3 y)
+{
+    return and(x, 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:%.*]]
+bool2x4 test_and_bool2x4(bool2x4 x, bool2x4 y)
+{
+    return and(x, 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:%.*]]
+bool3x1 test_and_bool3x1(bool3x1 x, bool3x1 y)
+{
+    return and(x, 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:%.*]]
+bool3x2 test_and_bool3x2(bool3x2 x, bool3x2 y)
+{
+    return and(x, 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:%.*]]
+bool3x3 test_and_bool3x3(bool3x3 x, bool3x3 y)
+{
+    return and(x, 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:%.*]]
+bool3x4 test_and_bool3x4(bool3x4 x, bool3x4 y)
+{
+    return and(x, 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:%.*]]
+bool4x1 test_and_bool4x1(bool4x1 x, bool4x1 y)
+{
+    return and(x, 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:%.*]]
+bool4x2 test_and_bool4x2(bool4x2 x, bool4x2 y)
+{
+    return and(x, 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:%.*]]
+bool4x3 test_and_bool4x3(bool4x3 x, bool4x3 y)
+{
+    return and(x, 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:%.*]]
+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 0a09cd2459fff..cf07d2fb7b42b 100644
--- a/clang/test/CodeGenHLSL/builtins/or.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/or.hlsl
@@ -2,79 +2,230 @@
 // RUN:   dxil-pc-shadermodel6.3-library %s \
 // RUN:   -emit-llvm -disable-llvm-passes -o - | FileCheck %s
 
-//CHECK-LABEL: define hidden noundef i1 @_Z14test_or_scalarbb(
-//CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[HLSL_OR:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
-//CHECK:         ret i1 [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef i1 @_Z14test_or_scalarbb(
+// CHECK-SAME: i1 noundef [[X:%.*]], i1 noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[HLSL_OR:%.*]] = or i1 [[A:%.*]], [[B:%.*]]
+// CHECK:         ret i1 [[HLSL_OR]]
 bool test_or_scalar(bool x, bool y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_(
-//CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[HLSL_OR:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]]
-//CHECK:         ret <2 x i1> [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef <2 x i1> @_Z13test_or_bool2Dv2_bS_(
+// CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[HLSL_OR:%.*]] = or <2 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <2 x i1> [[HLSL_OR]]
 bool2 test_or_bool2(bool2 x, bool2 y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_(
-//CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[HLSL_OR:%.*]] = or <3 x i1> [[A:%.*]], [[B:%.*]]
-//CHECK:         ret <3 x i1> [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef <3 x i1> @_Z13test_or_bool3Dv3_bS_(
+// CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[HLSL_OR:%.*]] = or <3 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <3 x i1> [[HLSL_OR]]
 bool3 test_or_bool3(bool3 x, bool3 y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_(
-//CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]]
-//CHECK:         ret <4 x i1> [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef <4 x i1> @_Z13test_or_bool4Dv4_bS_(
+// CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) 
#[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[A:%.*]], [[B:%.*]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool4 test_or_bool4(bool4 x, bool4 y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef i1 @_Z11test_or_intii(
-//CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[TOBBOL:%.*]] = icmp ne i32 [[A:%.*]], 0
-//CHECK:         [[TOBBOL1:%.*]] = icmp ne i32 [[B:%.*]], 0
-//CHECK:         [[HLSL_OR:%.*]] = or i1 [[TOBBOL]], [[TOBBOL1]]
-//CHECK:         ret i1 [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef i1 @_Z11test_or_intii(
+// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[TOBBOL:%.*]] = icmp ne i32 [[A:%.*]], 0
+// CHECK:         [[TOBBOL1:%.*]] = icmp ne i32 [[B:%.*]], 0
+// CHECK:         [[HLSL_OR:%.*]] = or i1 [[TOBBOL]], [[TOBBOL1]]
+// CHECK:         ret i1 [[HLSL_OR]]
 bool test_or_int(int x, int y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef <4 x i1> @_Z12test_or_int4Dv4_iS_(
-//CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) 
#[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[TOBOOL:%.*]] = icmp ne <4 x i32> [[A:%.*]], zeroinitializer
-//CHECK:         [[TOBOOL1:%.*]] = icmp ne <4 x i32> [[B:%.*]], zeroinitializer
-//CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
-//CHECK:         ret <4 x i1> [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef <4 x i1> @_Z12test_or_int4Dv4_iS_(
+// CHECK-SAME: <4 x i32> noundef [[X:%.*]], <4 x i32> noundef [[Y:%.*]]) 
#[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[TOBOOL:%.*]] = icmp ne <4 x i32> [[A:%.*]], zeroinitializer
+// CHECK:         [[TOBOOL1:%.*]] = icmp ne <4 x i32> [[B:%.*]], 
zeroinitializer
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool4 test_or_int4(int4 x, int4 y)
 {
     return or(x, y);
 }
 
-//CHECK-LABEL: define hidden noundef <4 x i1> @_Z14test_or_float4Dv4_fS_(
-//CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> 
noundef nofpclass(nan inf) [[Y:%.*]]) #[[ATTR0]] {
-//CHECK-NEXT:  entry:
-//CHECK:         [[TOBOOL:%.*]] =  fcmp reassoc nnan ninf nsz arcp afn une <4 
x float> [[A:%.*]], zeroinitializer
-//CHECK:         [[TOBOOL1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 
x float> [[B:%.*]], zeroinitializer
-//CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
-//CHECK:         ret <4 x i1> [[HLSL_OR]]
+// CHECK-LABEL: define hidden noundef <4 x i1> @_Z14test_or_float4Dv4_fS_(
+// CHECK-SAME: <4 x float> noundef nofpclass(nan inf) [[X:%.*]], <4 x float> 
noundef nofpclass(nan inf) [[Y:%.*]]) #[[ATTR0]] {
+// CHECK-NEXT:  entry:
+// CHECK:         [[TOBOOL:%.*]] =  fcmp reassoc nnan ninf nsz arcp afn une <4 
x float> [[A:%.*]], zeroinitializer
+// CHECK:         [[TOBOOL1:%.*]] = fcmp reassoc nnan ninf nsz arcp afn une <4 
x float> [[B:%.*]], zeroinitializer
+// CHECK:         [[HLSL_OR:%.*]] = or <4 x i1> [[TOBOOL]], [[TOBOOL1]]
+// CHECK:         ret <4 x i1> [[HLSL_OR]]
 bool4 test_or_float4(float4 x, float4 y)
 {
     return or(x, 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:%.*]]
+bool1x2 test_or_bool1x2(bool1x2 x, bool1x2 y)
+{
+    return or(x, 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:%.*]]
+bool1x3 test_or_bool1x3(bool1x3 x, bool1x3 y)
+{
+    return or(x, 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:%.*]]
+bool1x4 test_or_bool1x4(bool1x4 x, bool1x4 y)
+{
+    return or(x, 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:%.*]]
+bool2x1 test_or_bool2x1(bool2x1 x, bool2x1 y)
+{
+    return or(x, 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:%.*]]
+bool2x2 test_or_bool2x2(bool2x2 x, bool2x2 y)
+{
+    return or(x, 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:%.*]]
+bool2x3 test_or_bool2x3(bool2x3 x, bool2x3 y)
+{
+    return or(x, 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:%.*]]
+bool2x4 test_or_bool2x4(bool2x4 x, bool2x4 y)
+{
+    return or(x, 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:%.*]]
+bool3x1 test_or_bool3x1(bool3x1 x, bool3x1 y)
+{
+    return or(x, 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:%.*]]
+bool3x2 test_or_bool3x2(bool3x2 x, bool3x2 y)
+{
+    return or(x, 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:%.*]]
+bool3x3 test_or_bool3x3(bool3x3 x, bool3x3 y)
+{
+    return or(x, 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:%.*]]
+bool3x4 test_or_bool3x4(bool3x4 x, bool3x4 y)
+{
+    return or(x, 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:%.*]]
+bool4x1 test_or_bool4x1(bool4x1 x, bool4x1 y)
+{
+    return or(x, 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:%.*]]
+bool4x2 test_or_bool4x2(bool4x2 x, bool4x2 y)
+{
+    return or(x, 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:%.*]]
+bool4x3 test_or_bool4x3(bool4x3 x, bool4x3 y)
+{
+    return or(x, 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:%.*]]
+bool4x4 test_or_bool4x4(bool4x4 x, bool4x4 y)
+{
+    return or(x, y);
+}

diff  --git a/clang/test/SemaHLSL/BuiltIns/logical-mat-operator-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/logical-mat-operator-errors.hlsl
new file mode 100644
index 0000000000000..bd7f01dbd768f
--- /dev/null
+++ b/clang/test/SemaHLSL/BuiltIns/logical-mat-operator-errors.hlsl
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=or
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library %s -verify -DTEST_FUNC=and
+
+bool2x2 test_mismatched_args(bool2x2 a, bool3x3 b)
+{
+  return TEST_FUNC(a, b);
+  // expected-warning@-1 {{implicit conversion truncates matrix: 'bool3x3' 
(aka 'matrix<bool, 3, 3>') to 'matrix<bool, 2, 2>'}}
+}
+
+bool3x3 test_mismatched_args(bool3x3 a, bool2x2 b)
+{
+  return TEST_FUNC(a, b);
+  // expected-error@-1 {{cannot initialize return object of type 'bool3x3' 
(aka 'matrix<bool, 3, 3>') with an rvalue of type 'matrix<bool, 2, 2>'}}
+}
+
+bool2x2 test_mismatched_args2(bool3x3 a, bool2x2 b)
+{
+  return TEST_FUNC(a, b);
+  // expected-warning@-1 {{implicit conversion truncates matrix: 'bool3x3' 
(aka 'matrix<bool, 3, 3>') to 'matrix<bool, 2, 2>'}}
+}
+
+bool3x3 test_mismatched_return_larger(bool2x2 a, bool2x2 b)
+{
+  return TEST_FUNC(a, b);
+  // expected-error@-1 {{cannot initialize return object of type 
'matrix<[...], 3, 3>' with an rvalue of type 'matrix<[...], 2, 2>'}}
+}
+
+bool2x2 test_mismatched_return_smaller(bool3x3 a, bool3x3 b)
+{
+  return TEST_FUNC(a, b);
+  // expected-warning@-1 {{implicit conversion truncates matrix: 'bool3x3' 
(aka 'matrix<bool, 3, 3>') to 'matrix<bool, 2, 2>'}}
+}

diff  --git a/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl 
b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
index 71dad2f29d9aa..e30150dccb870 100644
--- a/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl
@@ -23,7 +23,7 @@ bool2 test_mismatched_args(bool2 a, bool3 b)
 bool test_incorrect_type(int a)
 {
     return TEST_FUNC(a, a);
-  // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector 
of such type is required}}
+  // expected-error@-1{{invalid operand of type 'int' where 'bool' or a vector 
or matrix of such type is required}}
 }
 
 bool test_mismatched_scalars(bool a, int b)
@@ -31,3 +31,11 @@ bool test_mismatched_scalars(bool a, int b)
   return TEST_FUNC(a, b);
   // expected-error@-1{{all arguments to}}{{_builtin_hlsl_or|_builtin_hlsl_and 
}}{{must have the same type}}
 }
+
+bool2x2 test_mismatched_matrix_dimensions(bool2x2 a, bool3x3 b)
+{
+    return TEST_FUNC(a, b);
+  // expected-error@-1{{cannot pass object of non-trivial type 'bool2x2' (aka 
'matrix<bool, 2, 2>') through variadic function; call will abort at runtime}}
+  // expected-error@-2{{cannot pass object of non-trivial type 'bool3x3' (aka 
'matrix<bool, 3, 3>') through variadic function; call will abort at runtime}}
+  // expected-error@-3{{all arguments to}}{{_builtin_hlsl_or|_builtin_hlsl_and 
}}{{must have the same type}}
+}

diff  --git a/clang/test/SemaHLSL/Language/UsualArithmeticConversions.hlsl 
b/clang/test/SemaHLSL/Language/UsualArithmeticConversions.hlsl
index d9f20a4cb79ec..3c6710a50270c 100644
--- a/clang/test/SemaHLSL/Language/UsualArithmeticConversions.hlsl
+++ b/clang/test/SemaHLSL/Language/UsualArithmeticConversions.hlsl
@@ -359,6 +359,28 @@ export bool4 b4f4i4Logical(float4 A, int4 B) {
   return A || B; // #b4f4i4Logical
 }
 
+#if __HLSL_VERSION >= 2021
+// expected-error@#b4x4f4x4i4x4LogicalOR{{invalid operands to binary 
expression ('float4x4' (aka 'matrix<float, 4, 4>') and 'int4x4' (aka 
'matrix<int, 4, 4>')}}
+// expected-note@#b4x4f4x4i4x4LogicalOR{{did you mean or?}}
+#else
+// expected-error@#b4x4f4x4i4x4LogicalOR{{support for HLSL language version 
2018 is incomplete}}
+#endif
+
+export bool4x4 b4x4f4x4i4x4LogicalOR(float4x4 A, int4x4 B) {
+  return A || B; // #b4x4f4x4i4x4LogicalOR
+}
+
+#if __HLSL_VERSION >= 2021
+// expected-error@#b4x4f4x4i4x4LogicalAND{{invalid operands to binary 
expression ('float4x4' (aka 'matrix<float, 4, 4>') and 'int4x4' (aka 
'matrix<int, 4, 4>')}}
+// expected-note@#b4x4f4x4i4x4LogicalAND{{did you mean and?}}
+#else
+// expected-error@#b4x4f4x4i4x4LogicalAND{{support for HLSL language version 
2018 is incomplete}}
+#endif
+
+export bool4x4 b4x4f4x4i4x4LogicalAND(float4x4 A, int4x4 B) {
+  return A && B; // #b4x4f4x4i4x4LogicalAND
+}
+
 #if __HLSL_VERSION >= 2021
 // expected-error@#b2f2i4Logical{{invalid operands to binary expression 
('float2' (aka 'vector<float, 2>') and 'int4' (aka 'vector<int, 4>'))}}
 // expected-note@#b2f2i4Logical{{did you mean and?}}


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

Reply via email to