Skip to content

Commit cb56a91

Browse files
authored
[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.
1 parent e77246d commit cb56a91

File tree

10 files changed

+539
-48
lines changed

10 files changed

+539
-48
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9763,6 +9763,9 @@ def err_typecheck_cond_incompatible_operands : Error<
97639763
def err_typecheck_expect_scalar_or_vector : Error<
97649764
"invalid operand of type %0 where %1 or "
97659765
"a vector of such type is required">;
9766+
def err_typecheck_expect_scalar_or_vector_or_matrix : Error<
9767+
"invalid operand of type %0 where %1 or "
9768+
"a vector or matrix of such type is required">;
97669769
def err_typecheck_expect_any_scalar_or_vector : Error<
97679770
"invalid operand of type %0%select{| where a scalar or vector is required}1">;
97689771
def err_typecheck_expect_flt_or_vector : Error<
@@ -13284,6 +13287,7 @@ def err_std_initializer_list_malformed : Error<
1328413287
"%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'">;
1328513288

1328613289
// HLSL Diagnostics
13290+
def err_hlsl_langstd_unimplemented : Error<"support for HLSL language version %0 is incomplete">;
1328713291
def err_hlsl_attr_unsupported_in_stage : Error<"attribute %0 is unsupported in '%1' shaders, requires %select{|one of the following: }2%3">;
1328813292
def err_hlsl_attr_invalid_type : Error<
1328913293
"attribute %0 only applies to a field or parameter of type '%1'">;

clang/include/clang/Sema/Sema.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7868,7 +7868,9 @@ class Sema final : public SemaBase {
78687868
QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
78697869
SourceLocation Loc,
78707870
BinaryOperatorKind Opc);
7871-
7871+
QualType CheckMatrixLogicalOperands(ExprResult &LHS, ExprResult &RHS,
7872+
SourceLocation Loc,
7873+
BinaryOperatorKind Opc);
78727874
// type checking for sizeless vector binary operators.
78737875
QualType CheckSizelessVectorOperands(ExprResult &LHS, ExprResult &RHS,
78747876
SourceLocation Loc, bool IsCompAssign,

clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -294,8 +294,8 @@ bool all(double4);
294294
//===----------------------------------------------------------------------===//
295295

296296
/// \fn bool and(bool x, bool y)
297-
/// \brief Logically ands two boolean vectors elementwise and produces a bool
298-
/// vector output.
297+
/// \brief Logically ands two boolean vectors or matrices elementwise and
298+
/// produces a bool vector or matrix output.
299299

300300
// TODO: Clean up clang-format marker once we've resolved
301301
// https://github.com/llvm/llvm-project/issues/127851
@@ -309,6 +309,38 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
309309
bool3 and(bool3 x, bool3 y);
310310
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
311311
bool4 and(bool4 x, bool4 y);
312+
313+
314+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
315+
bool1x2 and(bool1x2 x, bool1x2 y);
316+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
317+
bool1x3 and(bool1x3 x, bool1x3 y);
318+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
319+
bool1x4 and(bool1x4 x, bool1x4 y);
320+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
321+
bool2x1 and(bool2x1 x, bool2x1 y);
322+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
323+
bool2x2 and(bool2x2 x, bool2x2 y);
324+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
325+
bool2x3 and(bool2x3 x, bool2x3 y);
326+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
327+
bool2x4 and(bool2x4 x, bool2x4 y);
328+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
329+
bool3x1 and(bool3x1 x, bool3x1 y);
330+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
331+
bool3x2 and(bool3x2 x, bool3x2 y);
332+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
333+
bool3x3 and(bool3x3 x, bool3x3 y);
334+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
335+
bool3x4 and(bool3x4 x, bool3x4 y);
336+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
337+
bool4x1 and(bool4x1 x, bool4x1 y);
338+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
339+
bool4x2 and(bool4x2 x, bool4x2 y);
340+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
341+
bool4x3 and(bool4x3 x, bool4x3 y);
342+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_and)
343+
bool4x4 and(bool4x4 x, bool4x4 y);
312344
// clang-format on
313345

314346
//===----------------------------------------------------------------------===//
@@ -1759,8 +1791,8 @@ float4 normalize(float4);
17591791
//===----------------------------------------------------------------------===//
17601792

17611793
/// \fn bool or(bool x, bool y)
1762-
/// \brief Logically ors two boolean vectors elementwise and produces a bool
1763-
/// vector output.
1794+
/// \brief Logically ors two boolean vectors or matrices elementwise and
1795+
/// produces a bool vector or matrix output.
17641796

17651797
// TODO: Clean up clang-format marker once we've resolved
17661798
// https://github.com/llvm/llvm-project/issues/127851
@@ -1774,6 +1806,37 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
17741806
bool3 or(bool3, bool3);
17751807
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
17761808
bool4 or(bool4, bool4);
1809+
1810+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1811+
bool1x2 or(bool1x2 x, bool1x2 y);
1812+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1813+
bool1x3 or(bool1x3 x, bool1x3 y);
1814+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1815+
bool1x4 or(bool1x4 x, bool1x4 y);
1816+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1817+
bool2x1 or(bool2x1 x, bool2x1 y);
1818+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1819+
bool2x2 or(bool2x2 x, bool2x2 y);
1820+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1821+
bool2x3 or(bool2x3 x, bool2x3 y);
1822+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1823+
bool2x4 or(bool2x4 x, bool2x4 y);
1824+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1825+
bool3x1 or(bool3x1 x, bool3x1 y);
1826+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1827+
bool3x2 or(bool3x2 x, bool3x2 y);
1828+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1829+
bool3x3 or(bool3x3 x, bool3x3 y);
1830+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1831+
bool3x4 or(bool3x4 x, bool3x4 y);
1832+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1833+
bool4x1 or(bool4x1 x, bool4x1 y);
1834+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1835+
bool4x2 or(bool4x2 x, bool4x2 y);
1836+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1837+
bool4x3 or(bool4x3 x, bool4x3 y);
1838+
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_or)
1839+
bool4x4 or(bool4x4 x, bool4x4 y);
17771840
// clang-format on
17781841

17791842
//===----------------------------------------------------------------------===//

clang/lib/Sema/SemaExpr.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13445,6 +13445,25 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1344513445
return GetSignedVectorType(LHS.get()->getType());
1344613446
}
1344713447

13448+
QualType Sema::CheckMatrixLogicalOperands(ExprResult &LHS, ExprResult &RHS,
13449+
SourceLocation Loc,
13450+
BinaryOperatorKind Opc) {
13451+
13452+
if (!getLangOpts().HLSL) {
13453+
assert(false && "Logical operands are not supported in C\\C++");
13454+
return QualType();
13455+
}
13456+
13457+
if (getLangOpts().getHLSLVersion() >= LangOptionsBase::HLSL_2021) {
13458+
(void)InvalidOperands(Loc, LHS, RHS);
13459+
HLSL().emitLogicalOperatorFixIt(LHS.get(), RHS.get(), Opc);
13460+
return QualType();
13461+
}
13462+
SemaRef.Diag(LHS.get()->getBeginLoc(), diag::err_hlsl_langstd_unimplemented)
13463+
<< getLangOpts().getHLSLVersion();
13464+
return QualType();
13465+
}
13466+
1344813467
QualType Sema::CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS,
1344913468
SourceLocation Loc,
1345013469
bool IsCompAssign) {
@@ -13617,6 +13636,10 @@ inline QualType Sema::CheckLogicalOperands(ExprResult &LHS, ExprResult &RHS,
1361713636
RHS.get()->getType()->isVectorType())
1361813637
return CheckVectorLogicalOperands(LHS, RHS, Loc, Opc);
1361913638

13639+
if (LHS.get()->getType()->isConstantMatrixType() ||
13640+
RHS.get()->getType()->isConstantMatrixType())
13641+
return CheckMatrixLogicalOperands(LHS, RHS, Loc, Opc);
13642+
1362013643
bool EnumConstantInBoolContext = false;
1362113644
for (const ExprResult &HS : {LHS, RHS}) {
1362213645
if (const auto *DREHS = dyn_cast<DeclRefExpr>(HS.get())) {

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2998,6 +2998,36 @@ static bool CheckScalarOrVector(Sema *S, CallExpr *TheCall, QualType Scalar,
29982998
return false;
29992999
}
30003000

3001+
static bool CheckScalarOrVectorOrMatrix(Sema *S, CallExpr *TheCall,
3002+
QualType Scalar, unsigned ArgIndex) {
3003+
assert(TheCall->getNumArgs() > ArgIndex);
3004+
3005+
Expr *Arg = TheCall->getArg(ArgIndex);
3006+
QualType ArgType = Arg->getType();
3007+
3008+
// Scalar: T
3009+
if (S->Context.hasSameUnqualifiedType(ArgType, Scalar))
3010+
return false;
3011+
3012+
// Vector: vector<T>
3013+
if (const auto *VTy = ArgType->getAs<VectorType>()) {
3014+
if (S->Context.hasSameUnqualifiedType(VTy->getElementType(), Scalar))
3015+
return false;
3016+
}
3017+
3018+
// Matrix: ConstantMatrixType with element type T
3019+
if (const auto *MTy = ArgType->getAs<ConstantMatrixType>()) {
3020+
if (S->Context.hasSameUnqualifiedType(MTy->getElementType(), Scalar))
3021+
return false;
3022+
}
3023+
3024+
// Not a scalar/vector/matrix-of-scalar
3025+
S->Diag(Arg->getBeginLoc(),
3026+
diag::err_typecheck_expect_scalar_or_vector_or_matrix)
3027+
<< ArgType << Scalar;
3028+
return true;
3029+
}
3030+
30013031
static bool CheckAnyScalarOrVector(Sema *S, CallExpr *TheCall,
30023032
unsigned ArgIndex) {
30033033
assert(TheCall->getNumArgs() >= ArgIndex);
@@ -3230,7 +3260,8 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
32303260
case Builtin::BI__builtin_hlsl_or: {
32313261
if (SemaRef.checkArgCount(TheCall, 2))
32323262
return true;
3233-
if (CheckScalarOrVector(&SemaRef, TheCall, getASTContext().BoolTy, 0))
3263+
if (CheckScalarOrVectorOrMatrix(&SemaRef, TheCall, getASTContext().BoolTy,
3264+
0))
32343265
return true;
32353266
if (CheckAllArgsHaveSameType(&SemaRef, TheCall))
32363267
return true;
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// RUN: %clang_cc1 -finclude-default-header -triple \
2+
// RUN: dxil-pc-shadermodel6.3-library %s \
3+
// RUN: -emit-llvm -disable-llvm-passes -o - | FileCheck %s
4+
5+
// CHECK-LABEL: define hidden noundef <2 x i1> @_Z16test_and_bool1x2u11matrix_typeILm1ELm2EbES_(
6+
// CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
7+
// CHECK-NEXT: entry:
8+
// CHECK: [[HLSL_AND:%.*]] = and <2 x i32> [[A:%.*]], [[B:%.*]]
9+
// CHECK: ret <2 x i1> [[HLSL_AND_CAST:%.*]]
10+
bool1x2 test_and_bool1x2(bool1x2 x, bool1x2 y)
11+
{
12+
return and(x, y);
13+
}
14+
15+
// CHECK-LABEL: define hidden noundef <3 x i1> @_Z16test_and_bool1x3u11matrix_typeILm1ELm3EbES_(
16+
// CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
17+
// CHECK-NEXT: entry:
18+
// CHECK: [[HLSL_AND:%.*]] = and <3 x i32> [[A:%.*]], [[B:%.*]]
19+
// CHECK: ret <3 x i1> [[HLSL_AND_CAST:%.*]]
20+
bool1x3 test_and_bool1x3(bool1x3 x, bool1x3 y)
21+
{
22+
return and(x, y);
23+
}
24+
25+
// CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool1x4u11matrix_typeILm1ELm4EbES_(
26+
// CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
27+
// CHECK-NEXT: entry:
28+
// CHECK: [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
29+
// CHECK: ret <4 x i1> [[HLSL_AND_CAST:%.*]]
30+
bool1x4 test_and_bool1x4(bool1x4 x, bool1x4 y)
31+
{
32+
return and(x, y);
33+
}
34+
35+
// CHECK-LABEL: define hidden noundef <2 x i1> @_Z16test_and_bool2x1u11matrix_typeILm2ELm1EbES_(
36+
// CHECK-SAME: <2 x i1> noundef [[X:%.*]], <2 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
37+
// CHECK-NEXT: entry:
38+
// CHECK: [[HLSL_AND:%.*]] = and <2 x i32> [[A:%.*]], [[B:%.*]]
39+
// CHECK: ret <2 x i1> [[HLSL_AND_CAST:%.*]]
40+
bool2x1 test_and_bool2x1(bool2x1 x, bool2x1 y)
41+
{
42+
return and(x, y);
43+
}
44+
45+
46+
// CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool2x2u11matrix_typeILm2ELm2EbES_(
47+
// CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
48+
// CHECK-NEXT: entry:
49+
// CHECK: [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
50+
// CHECK: ret <4 x i1> [[HLSL_AND_CAST:%.*]]
51+
bool2x2 test_and_bool2x2(bool2x2 x, bool2x2 y)
52+
{
53+
return and(x, y);
54+
}
55+
56+
// CHECK-LABEL: define hidden noundef <6 x i1> @_Z16test_and_bool2x3u11matrix_typeILm2ELm3EbES_(
57+
// CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
58+
// CHECK-NEXT: entry:
59+
// CHECK: [[HLSL_AND:%.*]] = and <6 x i32> [[A:%.*]], [[B:%.*]]
60+
// CHECK: ret <6 x i1> [[HLSL_AND_CAST:%.*]]
61+
bool2x3 test_and_bool2x3(bool2x3 x, bool2x3 y)
62+
{
63+
return and(x, y);
64+
}
65+
66+
// CHECK-LABEL: define hidden noundef <8 x i1> @_Z16test_and_bool2x4u11matrix_typeILm2ELm4EbES_(
67+
// CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
68+
// CHECK-NEXT: entry:
69+
// CHECK: [[HLSL_AND:%.*]] = and <8 x i32> [[A:%.*]], [[B:%.*]]
70+
// CHECK: ret <8 x i1> [[HLSL_AND_CAST:%.*]]
71+
bool2x4 test_and_bool2x4(bool2x4 x, bool2x4 y)
72+
{
73+
return and(x, y);
74+
}
75+
76+
// CHECK-LABEL: define hidden noundef <3 x i1> @_Z16test_and_bool3x1u11matrix_typeILm3ELm1EbES_(
77+
// CHECK-SAME: <3 x i1> noundef [[X:%.*]], <3 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
78+
// CHECK-NEXT: entry:
79+
// CHECK: [[HLSL_AND:%.*]] = and <3 x i32> [[A:%.*]], [[B:%.*]]
80+
// CHECK: ret <3 x i1> [[HLSL_AND_CAST:%.*]]
81+
bool3x1 test_and_bool3x1(bool3x1 x, bool3x1 y)
82+
{
83+
return and(x, y);
84+
}
85+
86+
// CHECK-LABEL: define hidden noundef <6 x i1> @_Z16test_and_bool3x2u11matrix_typeILm3ELm2EbES_(
87+
// CHECK-SAME: <6 x i1> noundef [[X:%.*]], <6 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
88+
// CHECK-NEXT: entry:
89+
// CHECK: [[HLSL_AND:%.*]] = and <6 x i32> [[A:%.*]], [[B:%.*]]
90+
// CHECK: ret <6 x i1> [[HLSL_AND_CAST:%.*]]
91+
bool3x2 test_and_bool3x2(bool3x2 x, bool3x2 y)
92+
{
93+
return and(x, y);
94+
}
95+
96+
97+
// CHECK-LABEL: define hidden noundef <9 x i1> @_Z16test_and_bool3x3u11matrix_typeILm3ELm3EbES_(
98+
// CHECK-SAME: <9 x i1> noundef [[X:%.*]], <9 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
99+
// CHECK-NEXT: entry:
100+
// CHECK: [[HLSL_AND:%.*]] = and <9 x i32> [[A:%.*]], [[B:%.*]]
101+
// CHECK: ret <9 x i1> [[HLSL_AND_CAST:%.*]]
102+
bool3x3 test_and_bool3x3(bool3x3 x, bool3x3 y)
103+
{
104+
return and(x, y);
105+
}
106+
107+
// CHECK-LABEL: define hidden noundef <12 x i1> @_Z16test_and_bool3x4u11matrix_typeILm3ELm4EbES_(
108+
// CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
109+
// CHECK-NEXT: entry:
110+
// CHECK: [[HLSL_AND:%.*]] = and <12 x i32> [[A:%.*]], [[B:%.*]]
111+
// CHECK: ret <12 x i1> [[HLSL_AND_CAST:%.*]]
112+
bool3x4 test_and_bool3x4(bool3x4 x, bool3x4 y)
113+
{
114+
return and(x, y);
115+
}
116+
117+
// CHECK-LABEL: define hidden noundef <4 x i1> @_Z16test_and_bool4x1u11matrix_typeILm4ELm1EbES_(
118+
// CHECK-SAME: <4 x i1> noundef [[X:%.*]], <4 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
119+
// CHECK-NEXT: entry:
120+
// CHECK: [[HLSL_AND:%.*]] = and <4 x i32> [[A:%.*]], [[B:%.*]]
121+
// CHECK: ret <4 x i1> [[HLSL_AND_CAST:%.*]]
122+
bool4x1 test_and_bool4x1(bool4x1 x, bool4x1 y)
123+
{
124+
return and(x, y);
125+
}
126+
127+
// CHECK-LABEL: define hidden noundef <8 x i1> @_Z16test_and_bool4x2u11matrix_typeILm4ELm2EbES_(
128+
// CHECK-SAME: <8 x i1> noundef [[X:%.*]], <8 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
129+
// CHECK-NEXT: entry:
130+
// CHECK: [[HLSL_AND:%.*]] = and <8 x i32> [[A:%.*]], [[B:%.*]]
131+
// CHECK: ret <8 x i1> [[HLSL_AND_CAST:%.*]]
132+
bool4x2 test_and_bool4x2(bool4x2 x, bool4x2 y)
133+
{
134+
return and(x, y);
135+
}
136+
137+
// CHECK-LABEL: define hidden noundef <12 x i1> @_Z16test_and_bool4x3u11matrix_typeILm4ELm3EbES_(
138+
// CHECK-SAME: <12 x i1> noundef [[X:%.*]], <12 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
139+
// CHECK-NEXT: entry:
140+
// CHECK: [[HLSL_AND:%.*]] = and <12 x i32> [[A:%.*]], [[B:%.*]]
141+
// CHECK: ret <12 x i1> [[HLSL_AND_CAST:%.*]]
142+
bool4x3 test_and_bool4x3(bool4x3 x, bool4x3 y)
143+
{
144+
return and(x, y);
145+
}
146+
147+
// CHECK-LABEL: define hidden noundef <16 x i1> @_Z16test_and_bool4x4u11matrix_typeILm4ELm4EbES_(
148+
// CHECK-SAME: <16 x i1> noundef [[X:%.*]], <16 x i1> noundef [[Y:%.*]]) #[[ATTR0]] {
149+
// CHECK-NEXT: entry:
150+
// CHECK: [[HLSL_AND:%.*]] = and <16 x i32> [[A:%.*]], [[B:%.*]]
151+
// CHECK: ret <16 x i1> [[HLSL_AND_CAST:%.*]]
152+
bool4x4 test_and_bool4x4(bool4x4 x, bool4x4 y)
153+
{
154+
return and(x, y);
155+
}

0 commit comments

Comments
 (0)