diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 381d1fb063eba..4ab2f1e422a46 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9766,6 +9766,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< @@ -13277,6 +13280,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 42f130c3a700d..94d4bce29d9ba 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -7866,7 +7866,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..c4c2b99167692 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,31 @@ _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) +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 +1784,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 +1799,31 @@ _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) +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 e01bf9c1a50e3..553129f27c3d2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13389,6 +13389,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 support 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) { @@ -13561,6 +13580,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(HS.get())) { diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 28744ff0ff42e..c6b989ffffef0 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2993,6 +2993,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 + if (const auto *VTy = ArgType->getAs()) { + if (S->Context.hasSameUnqualifiedType(VTy->getElementType(), Scalar)) + return false; + } + + // Matrix: ConstantMatrixType with element type T + if (const auto *MTy = ArgType->getAs()) { + 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); @@ -3225,7 +3255,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..4f9e5da304fd1 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/and_mat.hlsl @@ -0,0 +1,125 @@ +// 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_bool2x1u11matrix_typeILm2ELm1EbES_( +//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:%.*]] +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..53240ec14c202 100644 --- a/clang/test/CodeGenHLSL/builtins/or.hlsl +++ b/clang/test/CodeGenHLSL/builtins/or.hlsl @@ -78,3 +78,124 @@ bool4 test_or_float4(float4 x, float4 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..e29c76b13ae23 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/logical-mat-operator-errors.hlsl @@ -0,0 +1,33 @@ + +// 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') to 'matrix'}} +} + +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') with an rvalue of type 'matrix'}} +} + +bool2x2 test_mismatched_args2(bool3x3 a, bool2x2 b) +{ + return TEST_FUNC(a, b); + // expected-warning@-1 {{implicit conversion truncates matrix: 'bool3x3' (aka 'matrix') to 'matrix'}} +} + +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') to 'matrix'}} +} diff --git a/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/logical-operator-errors.hlsl index 71dad2f29d9aa..589abde7ddf2c 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_args(bool2x2 a, bool3x3 b) +{ + return TEST_FUNC(a, b); + // expected-error@-1{{cannot pass object of non-trivial type 'bool2x2' (aka 'matrix') through variadic function; call will abort at runtime}} + // expected-error@-2{{cannot pass object of non-trivial type 'bool3x3' (aka 'matrix') 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') and 'int4x4' (aka 'matrix')}} +// 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') and 'int4x4' (aka 'matrix')}} +// 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') and 'int4' (aka 'vector'))}} // expected-note@#b2f2i4Logical{{did you mean and?}}