Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 27 additions & 4 deletions clang/include/clang/AST/TypeBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -8665,6 +8680,14 @@ inline bool Type::isExtVectorBoolType() const {
return cast<ExtVectorType>(CanonicalType)->getElementType()->isBooleanType();
}

inline bool Type::isConstantMatrixBoolType() const {
if (!isConstantMatrixType())
return false;
return cast<ConstantMatrixType>(CanonicalType)
->getElementType()
->isBooleanType();
}

inline bool Type::isSubscriptableVectorType() const {
return isVectorType() || isSveVLSBuiltinType();
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ llvm::Type *CodeGenTypes::ConvertTypeForMem(QualType T) {
if (T->isConstantMatrixType()) {
const Type *Ty = Context.getCanonicalType(T).getTypePtr();
const ConstantMatrixType *MT = cast<ConstantMatrixType>(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());
}

Expand Down
17 changes: 17 additions & 0 deletions clang/lib/Headers/hlsl/hlsl_basic_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ typedef matrix<uint16_t, 4, 3> uint16_t4x3;
typedef matrix<uint16_t, 4, 4> uint16_t4x4;
#endif

typedef matrix<bool, 1, 1> bool1x1;
typedef matrix<bool, 1, 2> bool1x2;
typedef matrix<bool, 1, 3> bool1x3;
typedef matrix<bool, 1, 4> bool1x4;
typedef matrix<bool, 2, 1> bool2x1;
typedef matrix<bool, 2, 2> bool2x2;
typedef matrix<bool, 2, 3> bool2x3;
typedef matrix<bool, 2, 4> bool2x4;
typedef matrix<bool, 3, 1> bool3x1;
typedef matrix<bool, 3, 2> bool3x2;
typedef matrix<bool, 3, 3> bool3x3;
typedef matrix<bool, 3, 4> bool3x4;
typedef matrix<bool, 4, 1> bool4x1;
typedef matrix<bool, 4, 2> bool4x2;
typedef matrix<bool, 4, 3> bool4x3;
typedef matrix<bool, 4, 4> bool4x4;

typedef matrix<int, 1, 1> int1x1;
typedef matrix<int, 1, 2> int1x2;
typedef matrix<int, 1, 3> int1x3;
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2145,7 +2145,7 @@ checkMathBuiltinElementType(Sema &S, SourceLocation Loc, QualType ArgTy,
switch (ArgTyRestr) {
case Sema::EltwiseBuiltinArgTyRestriction::None:
if (!ArgTy->getAs<VectorType>() &&
!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;
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
151 changes: 151 additions & 0 deletions clang/test/CodeGenHLSL/BoolMatrix.hlsl
Original file line number Diff line number Diff line change
@@ -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> <i1 true, i1 false, i1 true, i1 false>, 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> <i1 true, i1 false, i1 true, i1 false>, 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;
}
33 changes: 33 additions & 0 deletions clang/test/CodeGenHLSL/basic_types.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 );
7 changes: 3 additions & 4 deletions clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}

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) {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions clang/test/SemaHLSL/BuiltIns/mad-errors.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading