From b36e6944e0d50bb2fc2c9019338eb1765e8848ff Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Sun, 7 Dec 2025 13:31:16 -0500 Subject: [PATCH 1/2] [HLSL][Matrix] Add Matrix Bool and represent them as i32 elements fixes #171049 fixes #171050 - Allow Bools for matrix type when in HLSL mode - use ConvertTypeForMem to figure out the bool size - Add Bool matrix types to hlsl_basic_types.h --- clang/include/clang/AST/TypeBase.h | 31 ++++- clang/lib/AST/ASTContext.cpp | 2 +- clang/lib/CodeGen/CGExpr.cpp | 7 +- clang/lib/CodeGen/CodeGenTypes.cpp | 5 +- clang/lib/Headers/hlsl/hlsl_basic_types.h | 17 +++ clang/lib/Sema/SemaChecking.cpp | 4 +- clang/lib/Sema/SemaType.cpp | 2 +- clang/test/CodeGenHLSL/BoolMatrix.hlsl | 151 ++++++++++++++++++++++ clang/test/CodeGenHLSL/basic_types.hlsl | 33 +++++ 9 files changed, 242 insertions(+), 10 deletions(-) create mode 100644 clang/test/CodeGenHLSL/BoolMatrix.hlsl diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index 30b9efe5a31b7..cf6897b6e515c 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -2637,6 +2637,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. bool isExtVectorBoolType() const; // Extended vector type with bool element. + bool isConstantMatrixBoolType() const; // Matrix type with bool element. // Extended vector type with bool element that is packed. HLSL doesn't pack // its bool vectors. bool isPackedVectorBoolType(const ASTContext &ctx) const; @@ -4352,12 +4353,26 @@ class MatrixType : public Type, public llvm::FoldingSetNode { /// Valid elements types are the following: /// * an integer type (as in C23 6.2.5p22), but excluding enumerated types - /// and _Bool + /// and _Bool (except that in HLSL, bool is allowed) /// * the standard floating types float or double /// * a half-precision floating point type, if one is supported on the target - static bool isValidElementType(QualType T) { - return T->isDependentType() || - (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); + static bool isValidElementType(QualType T, const LangOptions &LangOpts) { + // Dependent is always okay + if (T->isDependentType()) + return true; + + // Enums are never okay + if (T->isEnumeralType()) + return false; + + // In HLSL, bool is allowed as a matrix element type. + // Note: isRealType includes bool so don't need to check + if (LangOpts.HLSL) + return T->isRealType(); + + // In non-HLSL modes, follow the existing rule: + // real type, but not _Bool. + return T->isRealType() && !T->isBooleanType(); } bool isSugared() const { return false; } @@ -8665,6 +8680,14 @@ inline bool Type::isExtVectorBoolType() const { return cast(CanonicalType)->getElementType()->isBooleanType(); } +inline bool Type::isConstantMatrixBoolType() const { + if (!isConstantMatrixType()) + return false; + return cast(CanonicalType) + ->getElementType() + ->isBooleanType(); +} + inline bool Type::isSubscriptableVectorType() const { return isVectorType() || isSveVLSBuiltinType(); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 404ce3ffd77c7..5ca76c79df7c6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4712,7 +4712,7 @@ QualType ASTContext::getConstantMatrixType(QualType ElementTy, unsigned NumRows, ConstantMatrixType::Profile(ID, ElementTy, NumRows, NumColumns, Type::ConstantMatrix); - assert(MatrixType::isValidElementType(ElementTy) && + assert(MatrixType::isValidElementType(ElementTy, getLangOpts()) && "need a valid element type"); assert(NumRows > 0 && NumRows <= LangOpts.MaxMatrixDimension && NumColumns > 0 && NumColumns <= LangOpts.MaxMatrixDimension && diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 3bde8e1fa2ac3..b44c1a7d18120 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2655,8 +2655,13 @@ void CodeGenFunction::EmitStoreThroughLValue(RValue Src, LValue Dst, MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened()); } llvm::Instruction *Load = Builder.CreateLoad(Dst.getMatrixAddress()); + llvm::Value *InsertVal = Src.getScalarVal(); + if (getLangOpts().HLSL && InsertVal->getType()->isIntegerTy(1)) { + llvm::Type *StorageElmTy = Load->getType()->getScalarType(); + InsertVal = Builder.CreateZExt(InsertVal, StorageElmTy); + } llvm::Value *Vec = - Builder.CreateInsertElement(Load, Src.getScalarVal(), Idx, "matins"); + Builder.CreateInsertElement(Load, InsertVal, Idx, "matins"); auto *I = Builder.CreateStore(Vec, Dst.getMatrixAddress(), Dst.isVolatileQualified()); addInstToCurrentSourceAtom(I, Vec); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index be862cf07f177..a41bf86d6f95c 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -104,7 +104,10 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) { if (T->isConstantMatrixType()) { const Type *Ty = Context.getCanonicalType(T).getTypePtr(); const ConstantMatrixType *MT = cast(Ty); - return llvm::ArrayType::get(ConvertType(MT->getElementType()), + llvm::Type *IRElemTy = ConvertType(MT->getElementType()); + if (T->isConstantMatrixBoolType() && Context.getLangOpts().HLSL) + IRElemTy = ConvertTypeForMem(Context.BoolTy); + return llvm::ArrayType::get(IRElemTy, MT->getNumRows() * MT->getNumColumns()); } diff --git a/clang/lib/Headers/hlsl/hlsl_basic_types.h b/clang/lib/Headers/hlsl/hlsl_basic_types.h index fc1e265067714..b1d87c51de9bb 100644 --- a/clang/lib/Headers/hlsl/hlsl_basic_types.h +++ b/clang/lib/Headers/hlsl/hlsl_basic_types.h @@ -150,6 +150,23 @@ typedef matrix uint16_t4x3; typedef matrix uint16_t4x4; #endif +typedef matrix bool1x1; +typedef matrix bool1x2; +typedef matrix bool1x3; +typedef matrix bool1x4; +typedef matrix bool2x1; +typedef matrix bool2x2; +typedef matrix bool2x3; +typedef matrix bool2x4; +typedef matrix bool3x1; +typedef matrix bool3x2; +typedef matrix bool3x3; +typedef matrix bool3x4; +typedef matrix bool4x1; +typedef matrix bool4x2; +typedef matrix bool4x3; +typedef matrix bool4x4; + typedef matrix int1x1; typedef matrix int1x2; typedef matrix int1x3; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 02c838bc4a862..bdf2e08400801 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2145,7 +2145,7 @@ checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy, switch (ArgTyRestr) { case Sema::EltwiseBuiltinArgTyRestriction::None: if (!ArgTy->getAs() && - !ConstantMatrixType::isValidElementType(ArgTy)) { + !ConstantMatrixType::isValidElementType(ArgTy, S.getLangOpts())) { return S.Diag(Loc, diag::err_builtin_invalid_arg_type) << ArgOrdinal << /* vector */ 2 << /* integer */ 1 << /* fp */ 1 << ArgTy; @@ -16545,7 +16545,7 @@ ExprResult Sema::BuiltinMatrixColumnMajorLoad(CallExpr *TheCall, } else { ElementTy = PtrTy->getPointeeType().getUnqualifiedType(); - if (!ConstantMatrixType::isValidElementType(ElementTy)) { + if (!ConstantMatrixType::isValidElementType(ElementTy, getLangOpts())) { Diag(PtrExpr->getBeginLoc(), diag::err_builtin_invalid_arg_type) << PtrArgIdx + 1 << 0 << /* pointer to element ty */ 5 << /* no fp */ 0 << PtrExpr->getType(); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index fd64d4456cbfa..7ef83433326ed 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2467,7 +2467,7 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols, // Check element type, if it is not dependent. if (!ElementTy->isDependentType() && - !MatrixType::isValidElementType(ElementTy)) { + !MatrixType::isValidElementType(ElementTy, getLangOpts())) { Diag(AttrLoc, diag::err_attribute_invalid_matrix_type) << ElementTy; return QualType(); } diff --git a/clang/test/CodeGenHLSL/BoolMatrix.hlsl b/clang/test/CodeGenHLSL/BoolMatrix.hlsl new file mode 100644 index 0000000000000..da90738b68b96 --- /dev/null +++ b/clang/test/CodeGenHLSL/BoolMatrix.hlsl @@ -0,0 +1,151 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s + + +struct S { + bool2x2 bM; + float f; +}; + +// CHECK-LABEL: define hidden noundef i1 @_Z3fn1v( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 4 +// CHECK-NEXT: [[B:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: store <4 x i1> splat (i1 true), 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]] +// +bool fn1() { + bool2x2 B = {true,true,true,true}; + return B[0][0]; +} + +// CHECK-LABEL: define hidden noundef <4 x i1> @_Z3fn2b( +// CHECK-SAME: i1 noundef [[V:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca <4 x i1>, align 4 +// CHECK-NEXT: [[V_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: [[A:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: [[STOREDV:%.*]] = zext i1 [[V]] to i32 +// CHECK-NEXT: store i32 [[STOREDV]], ptr [[V_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc i32 [[TMP0]] to i1 +// CHECK-NEXT: [[VECINIT:%.*]] = insertelement <4 x i1> poison, i1 [[LOADEDV]], i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[V_ADDR]], align 4 +// CHECK-NEXT: [[LOADEDV1:%.*]] = trunc i32 [[TMP1]] to i1 +// CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x i1> [[VECINIT]], i1 [[LOADEDV1]], i32 1 +// CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x i1> [[VECINIT2]], i1 true, i32 2 +// CHECK-NEXT: [[VECINIT4:%.*]] = insertelement <4 x i1> [[VECINIT3]], i1 false, i32 3 +// CHECK-NEXT: store <4 x i1> [[VECINIT4]], ptr [[A]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr [[A]], align 4 +// CHECK-NEXT: store <4 x i32> [[TMP2]], ptr [[RETVAL]], align 4 +// CHECK-NEXT: [[TMP3:%.*]] = load <4 x i1>, ptr [[RETVAL]], align 4 +// CHECK-NEXT: ret <4 x i1> [[TMP3]] +// +bool2x2 fn2(bool V) { + bool2x2 A = {V, true, V, false}; + return A; +} + +// CHECK-LABEL: define hidden noundef i1 @_Z3fn3v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 4 +// CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_S:%.*]], align 1 +// CHECK-NEXT: [[BM:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0 +// CHECK-NEXT: store <4 x i1> , ptr [[BM]], align 1 +// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 1 +// CHECK-NEXT: store float 1.000000e+00, ptr [[F]], align 1 +// CHECK-NEXT: [[BM1:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[BM1]], 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]] +// +bool fn3() { + S s = {{true,true, false, false}, 1.0}; + return s.bM[0][0]; +} + +// CHECK-LABEL: define hidden noundef i1 @_Z3fn4v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca i1, align 4 +// CHECK-NEXT: [[ARR:%.*]] = alloca [2 x [4 x i32]], align 4 +// CHECK-NEXT: store <4 x i1> splat (i1 true), ptr [[ARR]], align 4 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR]], i32 1 +// CHECK-NEXT: store <4 x i1> zeroinitializer, ptr [[ARRAYINIT_ELEMENT]], align 4 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [4 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]] +// +bool fn4() { + bool2x2 Arr[2] = {{true,true,true,true}, {false,false,false,false}}; + return Arr[0][1][0]; +} + +// CHECK-LABEL: define hidden void @_Z3fn5v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[M:%.*]] = alloca [4 x i32], align 4 +// CHECK-NEXT: store <4 x i1> splat (i1 true), ptr [[M]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[M]], align 4 +// CHECK-NEXT: [[MATINS:%.*]] = insertelement <4 x i32> [[TMP0]], i32 0, i32 3 +// CHECK-NEXT: store <4 x i32> [[MATINS]], ptr [[M]], align 4 +// CHECK-NEXT: ret void +// +void fn5() { + bool2x2 M = {true,true,true,true}; + M[1][1] = false; +} + +// CHECK-LABEL: define hidden void @_Z3fn6v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[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 +// CHECK-NEXT: [[BM:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0 +// CHECK-NEXT: store <4 x i1> , ptr [[BM]], align 1 +// CHECK-NEXT: [[F:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 1 +// CHECK-NEXT: store float 1.000000e+00, ptr [[F]], align 1 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[V]], align 4 +// CHECK-NEXT: [[LOADEDV:%.*]] = trunc i32 [[TMP0]] to i1 +// CHECK-NEXT: [[BM1:%.*]] = getelementptr inbounds nuw [[STRUCT_S]], ptr [[S]], i32 0, i32 0 +// CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr [[BM1]], align 1 +// CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[LOADEDV]] to i32 +// CHECK-NEXT: [[MATINS:%.*]] = insertelement <4 x i32> [[TMP1]], i32 [[TMP2]], i32 1 +// CHECK-NEXT: store <4 x i32> [[MATINS]], ptr [[BM1]], align 1 +// CHECK-NEXT: ret void +// +void fn6() { + bool V = false; + S s = {{true,true,false,false}, 1.0}; + s.bM[1][0] = V; +} + +// CHECK-LABEL: define hidden void @_Z3fn7v( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARR:%.*]] = alloca [2 x [4 x i32]], align 4 +// CHECK-NEXT: store <4 x i1> splat (i1 true), ptr [[ARR]], align 4 +// CHECK-NEXT: [[ARRAYINIT_ELEMENT:%.*]] = getelementptr inbounds [4 x i32], ptr [[ARR]], i32 1 +// CHECK-NEXT: store <4 x i1> zeroinitializer, ptr [[ARRAYINIT_ELEMENT]], align 4 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x [4 x i32]], ptr [[ARR]], i32 0, i32 0 +// CHECK-NEXT: [[TMP0:%.*]] = load <4 x i32>, ptr [[ARRAYIDX]], align 4 +// CHECK-NEXT: [[MATINS:%.*]] = insertelement <4 x i32> [[TMP0]], i32 0, i32 1 +// CHECK-NEXT: store <4 x i32> [[MATINS]], ptr [[ARRAYIDX]], align 4 +// CHECK-NEXT: ret void +// +void fn7() { + bool2x2 Arr[2] = {{true,true,true,true}, {false,false,false,false}}; + Arr[0][1][0] = false; +} diff --git a/clang/test/CodeGenHLSL/basic_types.hlsl b/clang/test/CodeGenHLSL/basic_types.hlsl index 8836126934957..677a9a8f5d1de 100644 --- a/clang/test/CodeGenHLSL/basic_types.hlsl +++ b/clang/test/CodeGenHLSL/basic_types.hlsl @@ -38,6 +38,22 @@ // CHECK: @double2_Val = external hidden addrspace(2) global <2 x double>, align 16 // CHECK: @double3_Val = external hidden addrspace(2) global <3 x double>, align 32 // CHECK: @double4_Val = external hidden addrspace(2) global <4 x double>, align 32 +// CHECK: @bool1x1_Val = external hidden addrspace(2) global [1 x i32], align 4 +// CHECK: @bool1x2_Val = external hidden addrspace(2) global [2 x i32], align 4 +// CHECK: @bool1x3_Val = external hidden addrspace(2) global [3 x i32], align 4 +// CHECK: @bool1x4_Val = external hidden addrspace(2) global [4 x i32], align 4 +// CHECK: @bool2x1_Val = external hidden addrspace(2) global [2 x i32], align 4 +// CHECK: @bool2x2_Val = external hidden addrspace(2) global [4 x i32], align 4 +// CHECK: @bool2x3_Val = external hidden addrspace(2) global [6 x i32], align 4 +// CHECK: @bool2x4_Val = external hidden addrspace(2) global [8 x i32], align 4 +// CHECK: @bool3x1_Val = external hidden addrspace(2) global [3 x i32], align 4 +// CHECK: @bool3x2_Val = external hidden addrspace(2) global [6 x i32], align 4 +// CHECK: @bool3x3_Val = external hidden addrspace(2) global [9 x i32], align 4 +// CHECK: @bool3x4_Val = external hidden addrspace(2) global [12 x i32], align 4 +// CHECK: @bool4x1_Val = external hidden addrspace(2) global [4 x i32], align 4 +// CHECK: @bool4x2_Val = external hidden addrspace(2) global [8 x i32], align 4 +// CHECK: @bool4x3_Val = external hidden addrspace(2) global [12 x i32], align 4 +// CHECK: @bool4x4_Val = external hidden addrspace(2) global [16 x i32], align 4 #ifdef NAMESPACED #define TYPE_DECL(T) hlsl::T T##_Val @@ -93,3 +109,20 @@ TYPE_DECL( float4 ); TYPE_DECL( double2 ); TYPE_DECL( double3 ); TYPE_DECL( double4 ); + +TYPE_DECL( bool1x1 ); +TYPE_DECL( bool1x2 ); +TYPE_DECL( bool1x3 ); +TYPE_DECL( bool1x4 ); +TYPE_DECL( bool2x1 ); +TYPE_DECL( bool2x2 ); +TYPE_DECL( bool2x3 ); +TYPE_DECL( bool2x4 ); +TYPE_DECL( bool3x1 ); +TYPE_DECL( bool3x2 ); +TYPE_DECL( bool3x3 ); +TYPE_DECL( bool3x4 ); +TYPE_DECL( bool4x1 ); +TYPE_DECL( bool4x2 ); +TYPE_DECL( bool4x3 ); +TYPE_DECL( bool4x4 ); From 9c9fd5390b35ca693734c11562d7ae66050b418b Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Sun, 7 Dec 2025 16:00:32 -0500 Subject: [PATCH 2/2] these tests were errroneously dependent on MatrixType::isValidElementType --- clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl | 7 +++---- clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 2 +- clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl index bbe567b6d6ac1..5f86e281eeca5 100644 --- a/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl @@ -99,18 +99,17 @@ float2 test_builtin_clamp_int_vect_to_float_vec_promotion(int2 p0, float p1) { } float test_builtin_clamp_bool_type_promotion(bool p0) { - return __builtin_hlsl_elementwise_clamp(p0, p0, p0); - // expected-error@-1 {{1st argument must be a vector, integer or floating-point type (was 'bool')}} + return __builtin_hlsl_elementwise_clamp(p0, p0, p0); // note: should not error } float builtin_bool_to_float_type_promotion(float p0, bool p1) { return __builtin_hlsl_elementwise_clamp(p0, p0, p1); - // expected-error@-1 {{3rd argument must be a vector, integer or floating-point type (was 'bool')}} + // expected-error@-1 {{arguments are of different types ('float' vs 'bool')}} } float builtin_bool_to_float_type_promotion2(bool p0, float p1) { return __builtin_hlsl_elementwise_clamp(p1, p0, p1); - // expected-error@-1 {{2nd argument must be a vector, integer or floating-point type (was 'bool')}} + // expected-error@-1 {{arguments are of different types ('float' vs 'bool')}} } float builtin_clamp_int_to_float_promotion(float p0, int p1) { diff --git a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl index f514a04eb9f49..3751f53ef40fd 100644 --- a/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl @@ -106,7 +106,7 @@ float test_builtin_dot_int_vect_to_float_vec_promotion(int2 p0, float p1) { int test_builtin_dot_bool_type_promotion(bool p0, float p1) { return __builtin_hlsl_dot(p0, p1); - // expected-error@-1 {{1st argument must be a vector, integer or floating-point type (was 'bool')}} + // expected-error@-1 {{arguments are of different types ('bool' vs 'float')}} } double test_dot_double(double2 p0, double2 p1) { diff --git a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl index 0e9dda7055f98..a993fd9c26899 100644 --- a/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl +++ b/clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl @@ -72,12 +72,12 @@ float2 test_builtin_mad_int_vect_to_float_vec_promotion(int2 p0, float p1) { float builtin_bool_to_float_type_promotion(float p0, bool p1) { return __builtin_hlsl_mad(p0, p0, p1); - // expected-error@-1 {{3rd argument must be a vector, integer or floating-point type (was 'bool')}} + // expected-error@-1 {{arguments are of different types ('float' vs 'bool')}} } float builtin_bool_to_float_type_promotion2(bool p0, float p1) { return __builtin_hlsl_mad(p1, p0, p1); - // expected-error@-1 {{2nd argument must be a vector, integer or floating-point type (was 'bool')}} + // expected-error@-1 {{arguments are of different types ('float' vs 'bool')}} } float builtin_mad_int_to_float_promotion(float p0, int p1) {